Files
kamco-train-api/nginx/SSL_SETUP.md
2026-03-03 08:44:01 +09:00

10 KiB

SSL 사설 인증서 설정 가이드 (RedHat 9.6)

개요

이 문서는 RedHat 9.6 환경에서 https://api.train-kamco.comhttps://train-kamco.com 도메인을 위한 100년 유효한 사설 SSL 인증서 설정 방법을 설명합니다.

디렉토리 구조

nginx/
├── nginx.conf              # Nginx 설정 파일
├── ssl/
│   ├── openssl.cnf         # OpenSSL 설정 파일 (SAN 포함)
│   ├── train-kamco.com.crt # 사설 SSL 인증서 (멀티 도메인)
│   └── train-kamco.com.key # 개인 키 (비공개)
└── SSL_SETUP.md            # 이 문서

인증서 정보

  • 도메인: api.train-kamco.com, train-kamco.com (멀티 도메인)
  • 유효 기간: 100년 (36500일)
  • 알고리즘: RSA 4096-bit
  • CN (Common Name): api.train-kamco.com
  • SAN (Subject Alternative Names): api.train-kamco.com, train-kamco.com

사설 SSL 인증서 생성 (이미 생성됨)

인증서가 이미 생성되어 있습니다. 재생성이 필요한 경우 아래 단계를 따르세요.

1. OpenSSL 설정 파일 생성

cd /path/to/kamco-train-api

cat > nginx/ssl/openssl.cnf << 'EOF'
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn
req_extensions = v3_req

[dn]
C=KR
ST=Seoul
L=Seoul
O=KAMCO
OU=Training
CN=api.train-kamco.com

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = api.train-kamco.com
DNS.2 = train-kamco.com
EOF

2. SSL 인증서 및 개인 키 생성

# nginx/ssl 디렉토리 생성 (없는 경우)
mkdir -p nginx/ssl
chmod 700 nginx/ssl

# 인증서 및 개인 키 생성 (100년 유효)
openssl req -new -x509 -newkey rsa:4096 -sha256 -nodes \
  -keyout nginx/ssl/train-kamco.com.key \
  -out nginx/ssl/train-kamco.com.crt \
  -days 36500 \
  -config nginx/ssl/openssl.cnf \
  -extensions v3_req

# 파일 권한 설정
chmod 600 nginx/ssl/train-kamco.com.key
chmod 644 nginx/ssl/train-kamco.com.crt

3. 인증서 검증

# 인증서 정보 확인
openssl x509 -in nginx/ssl/train-kamco.com.crt -text -noout

# 유효 기간 확인
openssl x509 -in nginx/ssl/train-kamco.com.crt -text -noout | grep -A2 "Validity"

# SAN (멀티 도메인) 확인
openssl x509 -in nginx/ssl/train-kamco.com.crt -text -noout | grep -A1 "Subject Alternative Name"

# CN 확인
openssl x509 -in nginx/ssl/train-kamco.com.crt -noout -subject

# 개인 키 확인
openssl rsa -in nginx/ssl/train-kamco.com.key -check

예상 결과:

X509v3 Subject Alternative Name:
    DNS:api.train-kamco.com, DNS:train-kamco.com

Validity
    Not Before: Mar  2 23:39:XX 2026 GMT
    Not After : Feb  6 23:39:XX 2126 GMT

/etc/hosts 설정 (RedHat 9.6)

1. hosts 파일에 도메인 추가

# root 권한으로 실행
echo "127.0.0.1   api.train-kamco.com train-kamco.com" | sudo tee -a /etc/hosts

# 확인
cat /etc/hosts | grep train-kamco

예상 결과:

127.0.0.1   api.train-kamco.com train-kamco.com

2. 도메인 확인

# ping 테스트
ping -c 2 api.train-kamco.com
ping -c 2 train-kamco.com

Docker Compose 배포

1. 기존 컨테이너 중지 (실행 중인 경우)

cd /path/to/kamco-train-api
docker-compose -f docker-compose-prod.yml down

2. Production 환경 실행

# IMAGE_TAG 환경 변수 설정 (선택사항)
export IMAGE_TAG=latest

# Docker Compose 실행
docker-compose -f docker-compose-prod.yml up -d

# 컨테이너 상태 확인
docker-compose -f docker-compose-prod.yml ps

3. 로그 확인

# Nginx 로그
docker logs kamco-cd-nginx

# API 로그
docker logs kamco-cd-training-api

# 실시간 로그 확인
docker-compose -f docker-compose-prod.yml logs -f

HTTPS 접속 테스트

1. HTTP → HTTPS 리다이렉트 테스트

# api.train-kamco.com
curl -I http://api.train-kamco.com

# train-kamco.com
curl -I http://train-kamco.com

# 예상 결과: 301 Moved Permanently
# Location: https://api.train-kamco.com/ 또는 https://train-kamco.com/

2. HTTPS 헬스체크 (-k: 사설 인증서 경고 무시)

# api.train-kamco.com
curl -k https://api.train-kamco.com/monitor/health

# train-kamco.com
curl -k https://train-kamco.com/monitor/health

# 예상 결과: {"status":"UP","components":{...}}

3. SSL 인증서 확인

# api.train-kamco.com
openssl s_client -connect api.train-kamco.com:443 -showcerts

# train-kamco.com
openssl s_client -connect train-kamco.com:443 -showcerts

# CN 및 SAN 확인

4. 브라우저 테스트

브라우저에서 다음 URL에 접속:

  • https://api.train-kamco.com/monitor/health
  • https://train-kamco.com/monitor/health

주의: 사설 인증서이므로 "안전하지 않음" 경고가 표시됩니다.

  • Chrome/Edge: "고급" → "계속 진행" 클릭
  • Firefox: "위험 감수 및 계속" 클릭

브라우저에서 사설 인증서 신뢰 설정 (선택사항)

사설 인증서를 브라우저에 등록하면 경고 없이 접속 가능합니다.

Chrome/Edge (RedHat Desktop)

  1. chrome://settings/certificates 접속
  2. Authorities 탭 선택
  3. Import 클릭
  4. nginx/ssl/train-kamco.com.crt 선택
  5. Trust this certificate for identifying websites 체크
  6. OK 클릭

Firefox

  1. about:preferences#privacy 접속
  2. CertificatesView Certificates 클릭
  3. Authorities 탭 선택
  4. Import 클릭
  5. nginx/ssl/train-kamco.com.crt 선택
  6. Trust this CA to identify websites 체크
  7. OK 클릭

방화벽 설정 (RedHat 9.6)

1. 방화벽 상태 확인

sudo firewall-cmd --state

2. HTTP (80) 및 HTTPS (443) 포트 개방

# HTTP 포트 개방
sudo firewall-cmd --permanent --add-port=80/tcp

# HTTPS 포트 개방
sudo firewall-cmd --permanent --add-port=443/tcp

# 방화벽 재로드
sudo firewall-cmd --reload

# 확인
sudo firewall-cmd --list-ports

예상 결과:

80/tcp 443/tcp

보안 체크리스트

  • train-kamco.com.key 파일 권한이 600으로 설정됨
  • ssl 디렉토리가 버전 관리에서 제외됨 (.gitignore 확인)
  • 두 도메인(api.train-kamco.com, train-kamco.com) 모두 SAN에 포함됨
  • 방화벽에서 80, 443 포트 개방 확인
  • HSTS 헤더 활성화 확인
  • TLS 1.2 이상만 허용 확인
  • /etc/hosts에 도메인 매핑 확인

트러블슈팅

인증서 관련 오류

"certificate verify failed"

# 해결: -k 플래그 사용 (사설 인증서 경고 무시)
curl -k https://api.train-kamco.com/monitor/health

"NET::ERR_CERT_AUTHORITY_INVALID" (브라우저)

  • 정상 동작: 사설 인증서이므로 브라우저 경고는 예상된 동작입니다
  • 해결: 브라우저에 인증서 등록 (위 "브라우저에서 사설 인증서 신뢰 설정" 참조)

연결 오류

"Connection refused"

# 컨테이너 상태 확인
docker ps | grep kamco-cd

# 포트 바인딩 확인
docker port kamco-cd-nginx

# 예상 결과:
# 80/tcp -> 0.0.0.0:80
# 443/tcp -> 0.0.0.0:443

"502 Bad Gateway"

# API 컨테이너 상태 확인
docker logs kamco-cd-training-api

# nginx → API 연결 확인
docker exec kamco-cd-nginx wget -qO- http://kamco-changedetection-api:8080/monitor/health

"Name or service not known" (도메인 해석 실패)

# /etc/hosts 확인
cat /etc/hosts | grep train-kamco

# 없으면 추가
echo "127.0.0.1   api.train-kamco.com train-kamco.com" | sudo tee -a /etc/hosts

방화벽 관련 오류

외부에서 접속 안 됨

# 방화벽 확인
sudo firewall-cmd --list-ports

# 포트 개방
sudo firewall-cmd --permanent --add-port=80/tcp
sudo firewall-cmd --permanent --add-port=443/tcp
sudo firewall-cmd --reload

인증서 만료 및 갱신

만료 확인

# 인증서 만료일 확인
openssl x509 -in nginx/ssl/train-kamco.com.crt -noout -enddate

# 예상 결과: notAfter=Feb  6 23:39:XX 2126 GMT (100년 후)

갱신 방법 (필요시)

100년 유효한 인증서이므로 갱신이 필요하지 않지만, 재생성이 필요한 경우:

# 기존 인증서 백업
cp nginx/ssl/train-kamco.com.crt nginx/ssl/train-kamco.com.crt.bak
cp nginx/ssl/train-kamco.com.key nginx/ssl/train-kamco.com.key.bak

# 위의 "사설 SSL 인증서 생성" 단계 재실행

# nginx 재시작
docker-compose -f docker-compose-prod.yml restart nginx

주의사항

  1. 사설 인증서 경고: 브라우저에서 "안전하지 않음" 경고가 표시됩니다. 프로덕션 환경에서는 공인 인증서(Let's Encrypt, GlobalSign 등) 사용을 권장합니다.

  2. 포트 80/443: Docker가 자동으로 처리하지만, 이미 사용 중인 프로세스가 있으면 충돌할 수 있습니다.

    # 포트 사용 확인
    sudo lsof -i :80
    sudo lsof -i :443
    
  3. 대용량 파일 업로드: client_max_body_size를 10GB로 설정했으므로, 서버 메모리 및 디스크 용량을 충분히 확보하세요.

  4. 인증서 백업: train-kamco.com.key 파일은 매우 중요합니다. 안전한 곳에 백업하세요.

  5. SELinux: RedHat 9.6에서 SELinux가 활성화된 경우, Docker 볼륨 마운트 권한 문제가 발생할 수 있습니다.

    # SELinux 상태 확인
    getenforce
    
    # 필요시 permissive 모드로 변경
    sudo setenforce 0
    

참고 자료