Commit 38d93380 authored by insun park's avatar insun park
Browse files

docs: README 링크 수정 및 SSL 설정 가이드 추가

parent 0764d076
......@@ -14,6 +14,7 @@
- **[Docker 환경 리포트](./docker/geumdo_docker_report_240611.md)**: 서버별 Docker 버전 현황과 주요 Docker Compose 프로젝트 정보를 정리한 문서입니다.
- **[Docker 배포 가이드](./docker/deployment_guide.md)**: Docker를 이용한 서비스 배포 절차를 안내하는 가이드입니다.
- **[Tomcat SSL/TLS 설정 가이드](./docker/docker_ssl_setup_guide.md)**: 리버스 프록시(Nginx/Apache)를 이용해 Tomcat 애플리케이션에 SSL/TLS를 적용하는 방법을 안내합니다.
- **[Docker 예제](./docker/examples/)**: 다양한 Docker 설정 예제 파일들입니다.
#### 🖥️ 고급 가상화: Docker + KVM + Windows VM
......@@ -88,70 +89,70 @@ docker-compose up -d
### 📚 과정 개요
- **[AI 전문가 과정 메인 페이지](./ai%20lecture/README.md)**: 전체 과정 소개 및 기술 스택 정보
- **[강의 계획서](./ai%20lecture/AI_Expert_Course_Schedule.md)**: 16주 과정의 상세한 주차별 학습 목표와 내용
- **[개발 환경 설정 가이드](./ai%20lecture/SETUP.md)**: Poetry를 사용한 현대적인 개발 환경 설정 방법
- **[자주 묻는 질문 (FAQ)](./ai%20lecture/FAQ.md)**: 과정에 대한 주요 질문과 답변
- **[기여 가이드](./ai%20lecture/CONTRIBUTING.md)**: 프로젝트 기여 방법 및 개발 환경 설정
- **[문제 해결 가이드](./ai%20lecture/TROUBLESHOOTING.md)**: 개발 중 발생할 수 있는 문제 해결 방법
- **[AI 전문가 과정 메인 페이지](./ai_lecture/README.md)**: 전체 과정 소개 및 기술 스택 정보
- **[강의 계획서](./ai_lecture/AI_Expert_Course_Schedule.md)**: 16주 과정의 상세한 주차별 학습 목표와 내용
- **[개발 환경 설정 가이드](./ai_lecture/SETUP.md)**: Poetry를 사용한 현대적인 개발 환경 설정 방법
- **[자주 묻는 질문 (FAQ)](./ai_lecture/FAQ.md)**: 과정에 대한 주요 질문과 답변
- **[기여 가이드](./ai_lecture/CONTRIBUTING.md)**: 프로젝트 기여 방법 및 개발 환경 설정
- **[문제 해결 가이드](./ai_lecture/TROUBLESHOOTING.md)**: 개발 중 발생할 수 있는 문제 해결 방법
### 🎯 커리큘럼 구조
#### **Part 1: AI 개발을 위한 파이썬 마스터리 (1-5주차)**
- **[Part 0: 과정 소개](./ai%20lecture/courses/00_introduction/part_0_introduction.md)**
- **[Part 0.1: AI의 역사](./ai%20lecture/courses/00_introduction/part_0.1_history_of_ai.md)**
- **[Part 1: AI 개발 환경 구축](./ai%20lecture/courses/01_ai_development_environment/part_1_ai_development_environment.md)**
- **[Part 2: Python 핵심 문법](./ai%20lecture/courses/02_python_core_syntax/part_2_python_core_syntax.md)**
- **[Part 3: Python 컬렉션](./ai%20lecture/courses/03_python_collections/part_3_python_collections.md)**
- **[Part 4: 객체 지향 프로그래밍](./ai%20lecture/courses/04_object_oriented_programming/part_4_object_oriented_programming.md)**
- **[Part 5: AI 핵심 라이브러리](./ai%20lecture/courses/05_ai_core_libraries/part_5_ai_core_libraries.md)**
- **[Part 0: 과정 소개](./ai_lecture/courses/00_introduction/part_0_introduction.md)**
- **[Part 0.1: AI의 역사](./ai_lecture/courses/00_introduction/part_0.1_history_of_ai.md)**
- **[Part 1: AI 개발 환경 구축](./ai_lecture/courses/01_ai_development_environment/part_1_ai_development_environment.md)**
- **[Part 2: Python 핵심 문법](./ai_lecture/courses/02_python_core_syntax/part_2_python_core_syntax.md)**
- **[Part 3: Python 컬렉션](./ai_lecture/courses/03_python_collections/part_3_python_collections.md)**
- **[Part 4: 객체 지향 프로그래밍](./ai_lecture/courses/04_object_oriented_programming/part_4_object_oriented_programming.md)**
- **[Part 5: AI 핵심 라이브러리](./ai_lecture/courses/05_ai_core_libraries/part_5_ai_core_libraries.md)**
#### **Part 2: 핵심 AI 모델 개발 및 서빙 (6-9주차)**
- **[Part 6: 머신러닝](./ai%20lecture/courses/06_machine_learning/part_6_machine_learning.md)**
- **[Part 7: 딥러닝](./ai%20lecture/courses/07_deep_learning/part_7_deep_learning.md)**
- **[7.1: 순환 신경망 (RNN)](./ai%20lecture/courses/07_deep_learning/part_7.1_recurrent_neural_networks.md)**
- **[7.2: Transformer와 LLM의 원리](./ai%20lecture/courses/07_deep_learning/part_7.2_transformer_and_llm_principles.md)**
- **[7.3: LangChain을 활용한 LLM 애플리케이션 개발](./ai%20lecture/courses/07_deep_learning/part_7.3_llm_application_development_with_langchain.md)**
- **[7.4: 그래프 신경망 (GNN)](./ai%20lecture/courses/07_deep_learning/part_7.4_graph_neural_networks.md)**
- **[7.5: 강화학습 (RL)](./ai%20lecture/courses/07_deep_learning/part_7.5_reinforcement_learning.md)**
- **[Part 8: FastAPI를 이용한 모델 서빙](./ai%20lecture/courses/08_model_serving_with_fastapi/part_8_model_serving_with_fastapi.md)**
- **[Part 9: Production-Ready API](./ai%20lecture/courses/09_production_ready_api/part_9_production_ready_api.md)**
- **[Part 6: 머신러닝](./ai_lecture/courses/06_machine_learning/part_6_machine_learning.md)**
- **[Part 7: 딥러닝](./ai_lecture/courses/07_deep_learning/part_7_deep_learning.md)**
- **[7.1: 순환 신경망 (RNN)](./ai_lecture/courses/07_deep_learning/part_7.1_recurrent_neural_networks.md)**
- **[7.2: Transformer와 LLM의 원리](./ai_lecture/courses/07_deep_learning/part_7.2_transformer_and_llm_principles.md)**
- **[7.3: LangChain을 활용한 LLM 애플리케이션 개발](./ai_lecture/courses/07_deep_learning/part_7.3_llm_application_development_with_langchain.md)**
- **[7.4: 그래프 신경망 (GNN)](./ai_lecture/courses/07_deep_learning/part_7.4_graph_neural_networks.md)**
- **[7.5: 강화학습 (RL)](./ai_lecture/courses/07_deep_learning/part_7.5_reinforcement_learning.md)**
- **[Part 8: FastAPI를 이용한 모델 서빙](./ai_lecture/courses/08_model_serving_with_fastapi/part_8_model_serving_with_fastapi.md)**
- **[Part 9: Production-Ready API](./ai_lecture/courses/09_production_ready_api/part_9_production_ready_api.md)**
#### **Part 3: 프로덕션 MLOps 및 AI 심화 (10-14주차)**
- **[Part 10: AI 전문가 과정 로드맵](./ai%20lecture/courses/10_expert_path/part_10_expert_path.md)**
- **[추천 학습 자료](./ai%20lecture/courses/10_expert_path/recommended_resources.md)**
- **[Part 11: 프로덕션 레벨 MLOps 심화](./ai%20lecture/courses/11_mlops/part_11_mlops.md)**
- **[Part 12: 대규모 AI 모델 최적화 및 서빙](./ai%20lecture/courses/12_model_optimization/part_12_model_optimization.md)**
- **[Part 13: 생성형 AI 및 AI 에이전트 심화](./ai%20lecture/courses/13_generative_ai/part_13_generative_ai.md)**
- **[Part 14: AI 윤리 및 거버넌스 실무](./ai%20lecture/courses/14_ai_ethics/part_14_ai_ethics.md)**
- **[Part 10: AI 전문가 과정 로드맵](./ai_lecture/courses/10_expert_path/part_10_expert_path.md)**
- **[추천 학습 자료](./ai_lecture/courses/10_expert_path/recommended_resources.md)**
- **[Part 11: 프로덕션 레벨 MLOps 심화](./ai_lecture/courses/11_mlops/part_11_mlops.md)**
- **[Part 12: 대규모 AI 모델 최적화 및 서빙](./ai_lecture/courses/12_model_optimization/part_12_model_optimization.md)**
- **[Part 13: 생성형 AI 및 AI 에이전트 심화](./ai_lecture/courses/13_generative_ai/part_13_generative_ai.md)**
- **[Part 14: AI 윤리 및 거버넌스 실무](./ai_lecture/courses/14_ai_ethics/part_14_ai_ethics.md)**
#### **Part 4: 최종 캡스톤 프로젝트 (15-16주차)**
- **[Part 15: 최종 캡스톤 프로젝트 가이드](./ai%20lecture/courses/15_capstone_project/part_15_capstone_project.md)**
- **[캡스톤 프로젝트 템플릿](./ai%20lecture/courses/15_capstone_project/capstone_template.md)**
- **[Part 15: 최종 캡스톤 프로젝트 가이드](./ai_lecture/courses/15_capstone_project/part_15_capstone_project.md)**
- **[캡스톤 프로젝트 템플릿](./ai_lecture/courses/15_capstone_project/capstone_template.md)**
### 💻 실습 코드 및 자료
- **[실습 코드 메인](./ai%20lecture/source_code/README.md)**: 전체 실습 코드 구조 및 사용법
- **[Python 핵심 문법 실습](./ai%20lecture/source_code/02_python_core_syntax/)**
- **[Python 컬렉션 실습](./ai%20lecture/source_code/03_python_collections/)**
- **[객체 지향 프로그래밍 실습](./ai%20lecture/source_code/04_object_oriented_programming/)**
- **[AI 핵심 라이브러리 실습](./ai%20lecture/source_code/05_ai_core_libraries/)**
- **[머신러닝 실습](./ai%20lecture/source_code/06_machine_learning/)**
- **[딥러닝 실습](./ai%20lecture/source_code/07_deep_learning/)**
- **[FastAPI 모델 서빙 실습](./ai%20lecture/source_code/08_model_serving_with_fastapi/)**
- **[Production API 실습](./ai%20lecture/source_code/09_production_ready_api/)**
- **[MLOps 심화 실습](./ai%20lecture/source_code/11_mlops/)**
- **[모델 최적화 실습](./ai%20lecture/source_code/12_model_optimization/)**
- **[생성형 AI 실습](./ai%20lecture/source_code/13_generative_ai/)**
- **[AI 윤리 실습](./ai%20lecture/source_code/14_ai_ethics/)**
- **[실습 코드 메인](./ai_lecture/source_code/README.md)**: 전체 실습 코드 구조 및 사용법
- **[Python 핵심 문법 실습](./ai_lecture/source_code/02_python_core_syntax/)**
- **[Python 컬렉션 실습](./ai_lecture/source_code/03_python_collections/)**
- **[객체 지향 프로그래밍 실습](./ai_lecture/source_code/04_object_oriented_programming/)**
- **[AI 핵심 라이브러리 실습](./ai_lecture/source_code/05_ai_core_libraries/)**
- **[머신러닝 실습](./ai_lecture/source_code/06_machine_learning/)**
- **[딥러닝 실습](./ai_lecture/source_code/07_deep_learning/)**
- **[FastAPI 모델 서빙 실습](./ai_lecture/source_code/08_model_serving_with_fastapi/)**
- **[Production API 실습](./ai_lecture/source_code/09_production_ready_api/)**
- **[MLOps 심화 실습](./ai_lecture/source_code/11_mlops/)**
- **[모델 최적화 실습](./ai_lecture/source_code/12_model_optimization/)**
- **[생성형 AI 실습](./ai_lecture/source_code/13_generative_ai/)**
- **[AI 윤리 실습](./ai_lecture/source_code/14_ai_ethics/)**
### 📚 추가 자료
- **[통합 용어집](./ai%20lecture/glossary.md)**: 전체 과정에서 사용되는 핵심 용어 정리
- **[실습 데이터셋](./ai%20lecture/datasets/)**: 과정에서 사용되는 실습용 데이터
- **[Docker 설정 파일](./ai%20lecture/docker-compose.dev.yml)**: 개발 환경용 Docker 설정
- **[GPU 지원 Docker 설정](./ai%20lecture/docker-compose.gpu.yml)**: GPU 환경용 Docker 설정
- **[프로젝트 TODO](./ai%20lecture/TODO.md)**: 프로젝트 개선 사항 및 향후 계획
- **[통합 용어집](./ai_lecture/glossary.md)**: 전체 과정에서 사용되는 핵심 용어 정리
- **[실습 데이터셋](./ai_lecture/assets/datasets/)**: 과정에서 사용되는 실습용 데이터 (경로 수정 필요 시 확인)
- **[Docker 설정 파일](./ai_lecture/docker-compose.dev.yml)**: 개발 환경용 Docker 설정
- **[GPU 지원 Docker 설정](./ai_lecture/docker-compose.gpu.yml)**: GPU 환경용 Docker 설정
- **[프로젝트 TODO](./ai_lecture/TODO.md)**: 프로젝트 개선 사항 및 향후 계획 (파일 위치 확인 필요)
---
......@@ -182,8 +183,8 @@ docker-compose up -d
## 🚀 시작하기
### AI 강의 과정 시작하기
1. **[개발 환경 설정](./ai%20lecture/SETUP.md)**을 참고하여 환경을 구축합니다.
2. **[Part 0: 과정 소개](./ai%20lecture/courses/00_introduction/part_0_introduction.md)**부터 시작합니다.
1. **[개발 환경 설정](./ai_lecture/SETUP.md)**을 참고하여 환경을 구축합니다.
2. **[Part 0: 과정 소개](./ai_lecture/courses/00_introduction/part_0_introduction.md)**부터 시작합니다.
3. 각 파트별로 이론 학습과 실습을 병행합니다.
### 서버 인프라 설정
......@@ -195,8 +196,8 @@ docker-compose up -d
## 📞 문의 및 지원
- **기술 문의**: 각 파트별 README 파일 및 FAQ 참고
- **개발 환경 문제**: [TROUBLESHOOTING.md](./ai%20lecture/TROUBLESHOOTING.md) 참고
- **프로젝트 기여**: [CONTRIBUTING.md](./ai%20lecture/CONTRIBUTING.md) 참고
- **개발 환경 문제**: [TROUBLESHOOTING.md](./ai_lecture/TROUBLESHOOTING.md) 참고
- **프로젝트 기여**: [CONTRIBUTING.md](./ai_lecture/CONTRIBUTING.md) 참고
---
......
# Tomcat SSL/TLS 설정 가이드 (Apache/Nginx 연동)
## 1. 개요
이 가이드는 **Tomcat**으로 실행되는 웹 애플리케이션에 **SSL/TLS (HTTPS)를 적용**하는 다양한 방법을 설명합니다. 특히, 사내 인프라(`192.168.0.61`과 같은 중앙 프록시)와 유사한 환경 및 클라우드 배포 환경 모두에서 적용할 수 있는 표준적인 방법을 다룹니다.
다양한 조합(Docker/Bare-metal, Apache/Nginx, Let's Encrypt/자체 서명 인증서)에 따른 설정 방법을 체계적으로 안내합니다.
이 가이드의 핵심 전략은 **리버스 프록시(Reverse Proxy)를 이용한 SSL 오프로딩(SSL Offloading)**입니다.
## 2. 핵심 전략: SSL 오프로딩 (TLS Termination)
SSL 오프로딩은 클라이언트와의 암호화된 통신(HTTPS)을 백엔드 애플리케이션(Tomcat) 앞단의 리버스 프록시(Nginx, Apache)가 전담하여 처리하는 구조입니다.
**장점:**
- **중앙 집중식 SSL 관리**: 인증서 관리를 리버스 프록시 한 곳에서 처리하므로 관리가 쉽고, 여러 Tomcat 인스턴스가 있어도 개별적으로 SSL을 설정할 필요가 없습니다.
- **성능 향상**: SSL 암호화/복호화 연산은 CPU를 많이 사용합니다. 웹 서버(Nginx/Apache)가 이를 전담함으로써 Tomcat은 비즈니스 로직 처리에 더 많은 리소스를 사용할 수 있습니다.
- **유연성 및 보안**: 리버스 프록시가 로드 밸런싱, 캐싱, 요청 필터링, 로깅 등 다양한 기능을 수행할 수 있으며, Tomcat 서버가 외부에 직접 노출되지 않아 보안이 강화됩니다.
이 구조에서 Tomcat은 SSL 설정을 할 필요 없이 일반 HTTP 또는 AJP 프로토콜로 실행됩니다.
## 3. 1단계: SSL 인증서 준비
리버스 프록시에 적용할 SSL 인증서를 준비합니다. 환경에 따라 두 가지 방법 중 하나를 선택합니다.
### 3.1. 개발 환경: 자체 서명 인증서 (Self-Signed Certificate)
로컬이나 개발 서버에서 테스트 용도로 사용합니다. `openssl` 명령어로 생성합니다.
```bash
# 인증서를 저장할 디렉토리 생성
mkdir -p certs
# 2048비트 RSA 키와 365일 유효한 자체 서명 인증서 생성
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout certs/self-signed.key \
-out certs/self-signed.crt \
-subj "/C=KR/ST=Seoul/L=Gangnam/O=MyOrg/OU=MyDept/CN=localhost"
```
- `CN` (Common Name)에는 접속할 도메인(예: `dev.mydomain.com` 또는 `localhost`)을 입력합니다.
- 생성된 `self-signed.key`(개인키)와 `self-signed.crt`(인증서) 파일을 리버스 프록시 서버의 특정 경로에 저장합니다.
### 3.2. 운영 환경: Let's Encrypt 인증서 (Certbot 사용)
신뢰할 수 있는 무료 인증 기관인 Let's Encrypt의 인증서를 사용합니다. `certbot` 클라이언트를 통해 발급 및 자동 갱신을 설정하는 것이 일반적입니다.
**사전 준비:**
- 서버를 가리키는 공인 도메인 (예: `www.your-domain.com`)
- 서버의 80번 포트(HTTP)가 외부에 개방되어 있어야 합니다. (Certbot이 도메인 소유권을 확인하기 위해 사용)
**Certbot 설치 (Ubuntu/Debian 기준):**
```bash
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
```
**인증서 발급 (Nginx/Apache 중단 방식):**
리버스 프록시를 잠시 중단하고 독립 실행형(standalone) 모드로 인증서를 발급받는 것이 가장 간단합니다.
```bash
# Nginx 사용 시
sudo systemctl stop nginx
# Apache 사용 시
sudo systemctl stop apache2
# Certbot 실행
sudo certbot certonly --standalone -d your-domain.com --email your-email@example.com --agree-tos
# 프록시 재시작
sudo systemctl start nginx # 또는 apache2
```
- 인증서는 `/etc/letsencrypt/live/your-domain.com/` 디렉토리 내에 `fullchain.pem`(인증서)과 `privkey.pem`(개인키)로 생성됩니다.
- Certbot은 자동으로 갱신을 시도하도록 cron job 또는 systemd timer를 설정합니다. `sudo certbot renew --dry-run`으로 갱신을 테스트할 수 있습니다.
**Docker 환경에서의 Certbot:**
이전 `docker_ssl_setup_guide.md``certbot` 서비스 부분을 참고하여 구성할 수 있습니다. `certbot` 컨테이너가 Nginx와 볼륨을 공유하여 인증서를 발급하고 갱신하도록 설정합니다.
## 4. 2단계: 리버스 프록시 설정 (SSL 적용)
준비된 인증서를 사용하여 Nginx 또는 Apache에 SSL을 설정하고, Tomcat으로 요청을 전달합니다.
### 4.1. Nginx로 설정하기
#### Bare-metal 환경
`/etc/nginx/sites-available/`에 다음과 같은 설정 파일을 작성합니다. (`your-domain.com.conf`)
```nginx
# /etc/nginx/sites-available/your-domain.com.conf
# HTTP (80) -> HTTPS (443) 리디렉션
server {
listen 80;
server_name your-domain.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name your-domain.com;
# 1. SSL 인증서 설정
# Let's Encrypt 사용 시
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# 자체 서명 인증서 사용 시
# ssl_certificate /path/to/certs/self-signed.crt;
# ssl_certificate_key /path/to/certs/self-signed.key;
# SSL 보안 강화 옵션
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
# 2. Tomcat으로 요청 전달 (HTTP)
# Tomcat 서버가 10.0.0.5:8080에서 실행 중이라고 가정
proxy_pass http://10.0.0.5:8080;
# 3. 프록시 관련 헤더 설정 (Tomcat에서 클라이언트 IP 등을 인식하기 위함)
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
```
**설정 적용:**
```bash
# 심볼릭 링크 생성
sudo ln -s /etc/nginx/sites-available/your-domain.com.conf /etc/nginx/sites-enabled/
# 설정 테스트
sudo nginx -t
# Nginx 재시작
sudo systemctl restart nginx
```
#### Docker 환경 (Nginx + Tomcat 연동)
`docker-compose.yml` 파일과 `nginx.conf` 파일을 프로젝트 루트에 구성합니다.
**`docker-compose.yml`**
```yaml
version: '3.8'
services:
tomcat:
image: tomcat:9.0-jdk11-temurin
# server.xml 등을 마운트 할 수 있음
# volumes:
# - ./tomcat/conf/server.xml:/usr/local/tomcat/webapps/conf/server.xml
expose:
- "8080" # 컨테이너 내부 8080 포트
networks:
- my-network
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
# nginx.conf 마운트
- ./nginx.conf:/etc/nginx/conf.d/default.conf
# 인증서 마운트 (letsencrypt 또는 self-signed)
- /etc/letsencrypt:/etc/letsencrypt:ro
# 또는 - ./certs:/etc/nginx/certs:ro
depends_on:
- tomcat
networks:
- my-network
networks:
my-network:
driver: bridge
```
**`nginx.conf`**
- Bare-metal 설정과 거의 동일하지만, `proxy_pass` 부분이 다릅니다.
- Docker의 내부 DNS를 사용하여 서비스 이름(`tomcat`)으로 요청을 전달합니다.
```nginx
# ... (server 블록 및 ssl 설정은 위와 동일) ...
location / {
# 서비스 이름 'tomcat'과 노출된 포트 '8080'으로 전달
proxy_pass http://tomcat:8080;
proxy_set_header Host $host;
# ... (나머지 헤더 설정은 동일) ...
}
# ...
```
### 4.2. Apache로 설정하기
#### Bare-metal 환경
`mod_ssl`, `mod_proxy`, `mod_proxy_http` (또는 `mod_proxy_ajp`) 모듈이 활성화되어 있어야 합니다.
```bash
# 모듈 활성화 (Debian/Ubuntu)
sudo a2enmod ssl proxy proxy_http
# AJP 연동을 원할 경우
# sudo a2enmod proxy_ajp
```
`/etc/apache2/sites-available/`에 다음과 같은 가상 호스트 설정 파일을 작성합니다. (`your-domain-ssl.conf`)
```apache
# /etc/apache2/sites-available/your-domain-ssl.conf
# HTTP -> HTTPS 리디렉션
<VirtualHost *:80>
ServerName your-domain.com
Redirect permanent / https://your-domain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName your-domain.com
# 1. SSL 설정
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/your-domain.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
# 2. Tomcat으로 요청 전달 (선택 1: HTTP 프록시)
ProxyPreserveHost On
ProxyPass / http://10.0.0.5:8080/
ProxyPassReverse / http://10.0.0.5:8080/
# 2. Tomcat으로 요청 전달 (선택 2: AJP 프록시)
# Tomcat의 server.xml에 AJP Connector가 활성화(보통 8009 포트)되어 있어야 함
# ProxyPass / ajp://10.0.0.5:8009/
# ProxyPassReverse / ajp://10.0.0.5:8009/
# 3. 프록시 관련 헤더 설정 (HTTP 프록시 사용 시)
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set X-Forwarded-Port "443"
</VirtualHost>
```
**설정 적용:**
```bash
# 사이트 활성화
sudo a2ensite your-domain-ssl.conf
# 설정 테스트
sudo apache2ctl configtest
# Apache 재시작
sudo systemctl restart apache2
```
#### Docker 환경 (Apache + Tomcat 연동)
공식 `httpd` 이미지를 사용하여 구성할 수 있습니다. `apache.conf``docker-compose.yml`이 필요합니다.
**`docker-compose.yml`**
```yaml
version: '3.8'
services:
tomcat:
# ... (Nginx 예시와 동일) ...
apache:
image: httpd:2.4
ports:
- "80:80"
- "443:443"
volumes:
- ./apache.conf:/usr/local/apache2/conf/extra/httpd-ssl.conf
- /etc/letsencrypt:/etc/letsencrypt:ro
# httpd.conf를 수정하여 ssl.conf를 include 하거나 직접 마운트
# ... 복잡하므로 Bare-metal을 더 권장 ...
depends_on:
- tomcat
# ...
```
*참고: Docker에서 Apache SSL을 설정하는 것은 Nginx보다 다소 복잡합니다. `httpd.conf`를 직접 수정하여 `mod_ssl` 로드, `Listen 443`, `Include conf/extra/httpd-ssl.conf` 등의 지시어를 관리해야 하기 때문입니다.*
## 5. 3단계: Tomcat 설정 (`server.xml`)
리버스 프록시 뒤에서 Tomcat이 올바르게 동작하도록 `server.xml` 파일을 설정합니다. 핵심은 Tomcat이 클라이언트의 원래 요청(HTTPS, 도메인 등)을 인지하도록 만드는 것입니다. **`RemoteIpValve`를 사용하는 것이 가장 표준적이고 권장되는 방법입니다.**
**`conf/server.xml`**
```xml
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<!--
RemoteIpValve:
Nginx/Apache와 같은 프록시 서버로부터 받은 헤더를 기반으로
request.getRemoteAddr(), request.getScheme() 등의 값을 실제 클라이언트 값으로 대체해줍니다.
-->
<Valve className="org.apache.catalina.valves.RemoteIpValve"
internalProxies="192\.168\.0\.61|172\.\d{1,3}\.\d{1,3}\.\d{1,3}|..." <!-- 사내 프록시 IP, Docker 네트워크 대역 프록시 서버 IP 대역을 정규식으로 추가 -->
remoteIpHeader="x-forwarded-for"
protocolHeader="x-forwarded-proto"
/>
</Host>
```
- `internalProxies`: 신뢰할 수 있는 프록시 서버의 IP 주소 목록입니다. 여기에 등록된 IP가 보낸 `x-forwarded-*` 헤더만 신뢰합니다. **중앙 프록시(`192.168.0.61`), Docker의 게이트웨이 IP 등을 등록해야 합니다.**
- `remoteIpHeader`: 클라이언트의 실제 IP가 담긴 헤더 이름입니다. (`X-Real-IP` 또는 `X-Forwarded-For`)
- `protocolHeader`: 원래 프로토콜(http/https)이 담긴 헤더 이름입니다. (`X-Forwarded-Proto`)
`RemoteIpValve`를 사용하면, `ProxyPass` 설정 시 `proxyName`, `proxyPort`, `scheme` 같은 속성을 Connector에 일일이 설정할 필요가 없어 구성이 매우 깔끔해집니다.
Tomcat의 Connector는 SSL 설정 없이 일반 HTTP/AJP로 유지합니다.
**HTTP Connector:**
```xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
```
**AJP Connector (AJP 연동 시):**
```xml
<Connector protocol="AJP/1.3"
address="::1"
port="8009"
redirectPort="8443" />
```
## 6. 결론
Tomca.t 애플리케이션에 SSL을 적용하는 가장 현대적이고 효율적인 방법은 **리버스 프록시를 사용한 SSL 오프로딩**입니다
1. `openssl` 또는 `certbot`으로 **인증서를 준비**합니다.
2. **Nginx/Apache 프록시 서버에 SSL을 설정**하고 Tomcat으로 요청을 전달합니다. (Docker/Bare-metal 환경에 맞게)
3. **Tomcat의 `server.xml`에는 `RemoteIpValve`를 설정**하여 프록시 환경에 대응합니다.
이 구조를 통해 SSL 인증서 관리와 트래픽 제어를 프록시 서버에 위임하고, Tomcat은 비즈니스 로직에 집중하여 안정적이고 확장성 있는 서비스 아키텍처를 구축할 수 있습니다.
## 7. 고급 구성: End-to-End 암호화 (Re-Encryption)
지금까지 설명한 **SSL 오프로딩**이 가장 일반적이고 효율적인 방법이지만, 내부망 보안 규정과 같은 특수한 요구사항으로 인해 리버스 프록시와 Tomcat 서버 간의 통신까지 암호화해야 하는 경우가 있습니다. 이 구성을 "End-to-End 암호화" 또는 "Re-Encryption"이라고 부릅니다.
**구조:** `Client --(HTTPS)--> Nginx/Apache --(HTTPS)--> Tomcat`
이 방식은 보안을 극대화하지만, 다음과 같은 추가 작업이 필요하며 약간의 성능 저하가 발생할 수 있습니다.
1. Tomcat 자체에 SSL/TLS를 설정해야 합니다.
2. 리버스 프록시가 Tomcat의 HTTPS 포트(예: 8443)로 요청을 전달하도록 구성해야 합니다.
### 7.1. 1단계: Tomcat에 SSL 인증서 적용
Tomcat이 HTTPS 요청을 처리할 수 있도록 `conf/server.xml` 파일의 `<Connector>`를 설정합니다. Tomcat 8.5 이상 버전은 Let's Encrypt에서 발급받은 PEM 형식의 인증서를 직접 사용할 수 있어 편리합니다.
**`conf/server.xml` 예시 (PEM 인증서 사용):**
```xml
<!-- HTTP Connector는 비활성화하거나 다른 포트로 유지할 수 있습니다. -->
<!-- HTTPS/TLS Connector 설정 -->
<Connector
protocol="org.apache.coyote.http11.Http11NioProtocol"
port="8443" maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<!--
Let's Encrypt 인증서 경로를 지정합니다.
Docker 환경에서는 이 파일들을 컨테이너 내부로 볼륨 마운트해야 합니다.
-->
<Certificate certificateKeyFile="conf/certs/privkey.pem"
certificateFile="conf/certs/fullchain.pem"
type="RSA" />
</SSLHostConfig>
</Connector>
```
- `certificateKeyFile`: 개인키 파일 (`privkey.pem`)의 경로입니다.
- `certificateFile`: 인증서와 체인 인증서가 포함된 파일 (`fullchain.pem`)의 경로입니다.
- Docker 환경에서는 `docker-compose.yml` 등을 통해 인증서 파일들을 Tomcat 컨테이너의 `conf/certs/`와 같은 경로에 마운트해야 합니다.
### 7.2. 2단계: 리버스 프록시가 Tomcat(HTTPS)으로 요청을 전달하도록 수정
프록시 서버가 Tomcat의 HTTPS 포트(예: 8443)로 요청을 전달하도록 `proxy_pass` (Nginx) 또는 `ProxyPass` (Apache) 설정을 변경합니다.
#### Nginx 설정 변경
`proxy_pass` 지시어의 주소를 `https://...`로 변경합니다.
```nginx
# /etc/nginx/sites-available/your-domain.com.conf
# ... (server 블록 및 ssl 설정은 동일) ...
location / {
# Tomcat HTTPS 백엔드로 프록시
# Docker 환경: proxy_pass https://tomcat:8443;
proxy_pass https://10.0.0.5:8443;
# ... (프록시 헤더 설정은 동일) ...
}
```
- **백엔드 인증서 검증**: Nginx는 기본적으로 백엔드 서버(Tomcat)의 인증서를 검증합니다.
- **공인 인증서**: Tomcat에 Let's Encrypt와 같은 공인 인증서를 사용했다면 추가 설정이 필요 없습니다.
- **자체 서명 인증서**: Tomcat에 자체 서명 인증서를 사용한 경우, Nginx가 해당 인증서를 신뢰하도록 `proxy_ssl_trusted_certificate`를 설정해야 502 오류를 방지할 수 있습니다.
```nginx
# Tomcat의 자체 서명 인증서(또는 CA 인증서)를 Nginx가 신뢰하도록 설정
proxy_ssl_trusted_certificate /etc/nginx/certs/tomcat-self-signed.crt;
# 개발 환경에서만 검증을 끌 수 있습니다 (보안상 비권장).
# proxy_ssl_verify off;
```
#### Apache 설정 변경
`mod_ssl``SSLProxyEngine`을 활성화하고 `ProxyPass` 지시어를 `https://...`로 변경합니다.
```apache
# /etc/apache2/sites-available/your-domain-ssl.conf
<VirtualHost *:443>
ServerName your-domain.com
# ... (SSLEngine on, SSLCertificateFile 등은 동일) ...
# 백엔드 SSL 프록시 기능 활성화
SSLProxyEngine on
# Tomcat HTTPS 백엔드로 요청 전달
ProxyPass / https://10.0.0.5:8443/
ProxyPassReverse / https://10.0.0.5:8443/
# 자체 서명 인증서 사용 시 신뢰 설정
# SSLProxyCACertificateFile /path/to/tomcat-self-signed.crt
# 개발 환경에서만 검증 비활성화
# SSLProxyVerify none
</VirtualHost>
```
이처럼 End-to-End 암호화는 각 컴포넌트(Tomcat, Nginx/Apache)에 모두 SSL 설정을 적용해야 하므로 전체적인 아키텍처 이해가 중요합니다.
- [Configure SSL for Docker (Kendis Help Center)](http://help.kendis.io/en/articles/3382550-configure-ssl-for-docker)
- [SSL for docker apps (Docker Community Forums)](https://forums.docker.com/t/ssl-for-docker-apps/102903)
- [Let's Encrypt](https://letsencrypt.org/)
- [Certbot](https://certbot.eff.org/)
- [Apache Module mod_proxy](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html)
- [Tomcat Remote IP Valve](https://tomcat.apache.org/tomcat-9.0-doc/config/valve.html#Remote_IP_Valve)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment