curl -k로 우회하지 않고 UTC 시각, SAN·만료일, 검증 체인, SNI별 leaf 인증서와 TLS 1.2·1.3 협상 결과를 분리해 확인한 뒤 NGINX 설정과 인증서 갱신을 안전하게 적용합니다.
certificate expiredunable to get local issuer certificateTLS SNI wrong certificatehostname mismatch SANTLS protocol version alertopenssl s_client verify_hostnameNGINX fullchain.pemCertbot renew failure
환경OpenSSL 3.x · curl · NGINX systemd · 선택적으로 Certbot · 공개 인증서와 제한된 private-key 경로 권한
분류웹·보안
검토일2026-09-04
진행5단계 · 조회 우선
SAFE OPERATING BOUNDARY
중단·복구 기준부터 확인하세요
STOP CONDITIONS
여기서는 멈추세요
DNS_NAME·실제 LB/backend·certificate 소유 팀과 UTC 시각을 확정하지 못했다면 갱신·config·reload를 실행하지 않습니다.
curl -k·--insecure 또는 verify error 무시로만 성공하는 경우 정상화로 간주하지 않고 trust chain 담당자에게 이관합니다.
private key·ACME token·client certificate secret의 출력·복사·외부 전달이 요구되면 작업을 중단하고 HSM·secret manager·승인된 배포 절차를 사용합니다.
TLS 1.0·1.1 활성화나 cipher 보안 수준 하향이 필요해 보이면 즉시 적용하지 말고 client 교체·위험 수용 승인을 포함한 보안 검토로 이관합니다.
ROLLBACK
복구 기준
NGINX server block·full-chain 경로·protocol 변경은 0600으로 보관한 정확한 이전 config를 nginx -t로 검증한 뒤 reload해 되돌립니다. 인증서 갱신은 임의 삭제하지 않고 CA·Certbot lineage에 보관된 검증된 이전 공개 certificate와 기존 private key를 표준 배포 절차로 다시 참조합니다. private key와 ACME credential은 rollback 증거에 포함하거나 출력하지 않습니다.
ESCALATION PACK
담당자에게 전달할 자료
UTC 시각·DNS 응답·관찰 지점, endpoint leaf subject/SAN/issuer/serial/notBefore/notAfter/SHA-256 fingerprint
verify return·chain build 결과와 backend IP별 SNI fingerprint, TLS 1.2·1.3·ALPN 협상 결과
민감값을 제거한 NGINX server_name·certificate path·protocol diff와 nginx -t·reload 시각
Certbot dry-run/live renewal 결과 요약과 변경 전후 외부 health·client matrix 검증
2026년 9월 4일 기준 PostgreSQL·Kubernetes·OpenSSL·NGINX·Certbot 공식 문서를 대조했습니다. 진단은 읽기 전용 명령과 최소 권한 계정으로 시작하고, 취소·세션 종료·설정 적용·reload는 대상·영향·복구 경로를 기록해 담당자가 승인한 경우에만 실행합니다. <...> 자리표시자는 검토된 리터럴 값으로 직접 치환하며 외부 입력으로 shell 명령을 조립하지 않습니다.
BEFORE YOU START
이런 증상에서 시작합니다
certificate has expired 또는 certificate is not yet valid 오류가 발생함
unable to get local issuer certificate·unknown CA가 특정 client에서만 발생함
같은 IP의 다른 도메인 인증서가 반환되거나 hostname mismatch가 발생함
protocol version·handshake failure가 특정 TLS client 또는 backend에서 발생함
CHECK THE BRANCH
놓치기 쉬운 원인 분기
01
만료·not yet valid인 경우
endpoint가 실제로 제공하는 leaf 인증서의 notBefore·notAfter와 UTC 시각을 비교합니다. 파일만 갱신되고 proxy가 이전 인증서를 계속 제공하는 상황을 구분합니다.
02
체인 검증 실패인 경우
leaf 다음 intermediate가 서버에서 제공되는지와 client trust store를 분리합니다. NGINX ssl_certificate에는 leaf가 먼저 오고 intermediate가 뒤따르는 full chain을 사용합니다.
03
SNI·hostname mismatch인 경우
DNS 이름을 -servername과 -verify_hostname에 모두 넣고 각 LB/backend IP에 연결해 비교합니다. IP로만 접속한 결과의 default certificate를 정상 인증서로 오판하지 않습니다.
04
프로토콜 협상 실패인 경우
TLS 1.2와 TLS 1.3을 각각 검증해 client/server 공통 범위를 확인합니다. 문제 해결을 위해 TLS 1.0·1.1이나 인증서 검증 우회를 켜지 않습니다.
FOLLOW THE FLOW
순서대로 확인하기
1
조회시스템을 변경하지 않는 확인 단계
UTC 시각·DNS·검증된 handshake 관찰
인증 정보나 client certificate를 넣지 않은 공개 health endpoint에서 시작합니다. curl --insecure 또는 -k를 사용하지 않으며 OpenSSL에는 검증 실패 시 중단 옵션을 넣습니다.
curl과 s_client가 모두 실패하면 인증서·chain·protocol 분기를, 특정 IP/backend에서만 실패하면 SNI routing 또는 배포 불일치를 우선 확인합니다.
다음 판단
endpoint가 제공하는 leaf 공개정보와 30일 만료 임계, 별도 chain 검증을 확인합니다.
2
조회시스템을 변경하지 않는 확인 단계
SAN·만료·issuer와 chain 판별
인증서는 공개 정보지만 내부 SAN과 topology가 포함될 수 있어 외부 공유 전 마스킹합니다. 이 단계의 s_client pipeline은 불신·만료 인증서에서도 공개 leaf 메타데이터를 수집하기 위해 verify_return_error를 사용하지 않는 진단 전용입니다. 비검증 수집 결과는 절대 정상 판정에 쓰지 않고 1단계의 별도 검증 handshake 결과와 함께 봅니다. private key 파일 내용은 어떤 명령에서도 출력하지 않습니다.
private key의 경로·권한만 확인하고 cat·head·checksum으로 내용을 출력하지 않습니다.
결과 읽기
SAN에 DNS 이름이 없으면 hostname 문제, notAfter 임박·경과면 갱신 문제, endpoint chain은 실패하지만 leaf 자체 날짜가 정상이라면 intermediate 제공 순서나 client CA bundle 문제입니다.
다음 판단
SNI별 backend와 TLS 1.2·1.3을 동일한 검증 조건으로 비교합니다.
3
주의서버 부하나 권한을 고려할 단계
SNI routing·backend 배포·프로토콜 범위 비교
LB 뒤 여러 IP를 하나씩 확인합니다. 신뢰 판정 명령은 -servername과 -verify_hostname을 실제 서비스 DNS 이름으로 유지합니다. 그 다음 별도 비검증 명령으로 공개 leaf fingerprint만 수집할 수 있지만 그 결과를 정상 판정에 사용하지 않습니다.
install -d -m 0700 <APPROVED_EVIDENCE_DIR>
umask 077
if sudo test -f <NGINX_TLS_CONFIG>; then sudo cp --archive --no-clobber <NGINX_TLS_CONFIG> <APPROVED_EVIDENCE_DIR>/nginx-tls.before.conf; fi
if sudo test -f <APPROVED_EVIDENCE_DIR>/nginx-tls.before.conf; then sudo chmod 0600 <APPROVED_EVIDENCE_DIR>/nginx-tls.before.conf; fi
private key와 ACME account credential은 복사하지 않습니다. 백업 파일이 실제로 생성된 경우에만 chmod가 적용됩니다.
결과 읽기
backend별 fingerprint가 다르면 배포 불일치, DNS name handshake와 고정 IP+SNI 결과가 다르면 LB routing, 특정 protocol만 실패하면 승인된 client compatibility와 server policy 교집합 문제입니다.
다음 판단
인증서 갱신 또는 NGINX full-chain·protocol 설정 중 확인된 원인 하나만 변경합니다.
4
변경데이터·서비스 상태가 달라질 수 있는 단계
승인된 인증서 갱신 또는 NGINX TLS 설정 적용
CA rate limit·domain validation·LB 전체 배포 범위와 rollback certificate를 확인합니다. dry-run 성공 없이 live renewal하지 않고, nginx -t 성공 없이 reload하지 않습니다.
변경 단계입니다. 실행 전 대상 이름과 경로, 서비스 중단 영향, 복구 방법을 다시 확인하세요.