Tomcat & nginx 운영 · SSL 종료와 인증서 · 실습
사설 CA 로 인증서 발급하고 nginx 에 적용하기
목표
사설 CA 를 만들어 SAN 이 포함된 서버 인증서를 발급하고, 체인 파일을 구성해
nginx 에 HTTPS 를 적용하고, 만료 감시 스크립트까지 만들 수 있게 됩니다.
왜 중요한가
인증서 장애의 대부분은 암호학이 아니라 체인 누락과 만료 두 가지입니다.
중간 인증서를 빼먹으면 브라우저에서는 잘 되는데 연동 상대 시스템에서만 실패합니다.
브라우저는 중간 인증서를 캐시하거나 알아서 받아 오지만, 서버 간 HTTP 클라이언트는
그러지 않기 때문입니다. "개발자 PC 에서는 되는데요"는 이 증상의 전형입니다.
그리고 만료는 예고 없이 오지 않는데도 담당자 교체와 알림 누락으로 매년 사고가 납니다.
사설 CA 로 한 번 직접 만들어 보면 이 구조가 손에 남습니다.
단계
1. /root/ng/tls 디렉터리를 만들고 RSA 2048비트 개인키를/root/ng/tls/server.key 로 생성합니다.
2. 그 키로 CSR 을 만들어 /root/ng/tls/server.csr 로 저장합니다.
주체는 CN=labhub.local, O=LabHub, C=KR 을 포함해야 합니다.
3. 사설 CA 를 만듭니다. /root/ng/tls/ca.key 와 /root/ng/tls/ca.crt.
CA 인증서의 주체는 CN=LabHub Root CA 이고 유효기간은 3650일 이상,basicConstraints 에 CA:TRUE 가 있어야 합니다.
4. CA 로 CSR 에 서명해 /root/ng/tls/server.crt 를 만듭니다.
SAN 에 DNS:labhub.local 과 IP:127.0.0.1 이 모두 들어가야 하고,
발급자(issuer)가 CA 의 주체와 같아야 합니다.
5. /root/ng/tls/fullchain.pem 을 만듭니다.
서버 인증서 → CA 인증서 순서로 이어 붙이며, 파일 안에 인증서가 정확히 2개여야 합니다.openssl verify -CAfile ca.crt server.crt 가 성공해야 합니다.
6. nginx 에 8443 포트 HTTPS 서버 블록을 추가합니다.ssl_certificate 는 fullchain, ssl_certificate_key 는 server.key,ssl_protocols 는 TLSv1.2 TLSv1.3 만 허용합니다.openssl s_client -connect 127.0.0.1:8443 -CAfile /root/ng/tls/ca.crt 의 결과에Verify return code: 0 이 나와야 합니다.
7. 8088 포트의 모든 요청이 https:// 로 301 리다이렉트되게 합니다.curl -s -o /dev/null -w '%{http_code} %{redirect_url}' http://127.0.0.1:8088/x
결과가 301 이고 리다이렉트 URL 이 https:// 로 시작하며 8443 을 포함해야 합니다.
8. /root/ng/certcheck.sh 를 만듭니다. 인자 두 개(인증서파일 임계일수)를 받아
남은 유효기간이 임계일수보다 많으면 종료코드 0,
임계일수 이내로 임박했으면 0 이 아닌 종료코드로 끝냅니다.
인증서 파일이 없으면 역시 0 이 아닌 종료코드로 끝나야 합니다.
참고
- 키 생성:
openssl genrsa -out server.key 2048 - CSR:
openssl req -new -key server.key -out server.csr -subj "/C=KR/O=LabHub/CN=labhub.local" - 자체 서명 CA:
openssl req -x509 -new -key ca.key -days 3650 -out ca.crt -subj "..." - 서명 시 SAN 주입: 확장 파일을 만들어
openssl x509 -req ... -extfile <파일> - 만료 확인:
openssl x509 -in <파일> -noout -checkend <초> - 흔한 실수 1: SAN 없이 CN 만 넣고 "왜 브라우저가 거부하지"를 반복하는 것.
- 흔한 실수 2: fullchain 의 순서를 CA 먼저로 만드는 것. 서버 인증서가 먼저입니다.
- 흔한 실수 3:
-checkend의 인자를 '일'로 주는 것. 초 단위입니다.
(CA 확장은 -addext "basicConstraints=critical,CA:TRUE" 로 줄 수 있습니다)
단계 8개
- 서버 개인키 생성
- CSR 생성
- 사설 CA 만들기
- CA 로 서버 인증서 서명
- 체인 파일 구성
- nginx HTTPS 적용
- HTTP → HTTPS 리다이렉트
- 만료 감시 스크립트