클라이언트를 열고 몇 달째 쓰던 프로필을 고르면 "certificate is not yet valid"와 함께 멈춥니다. 로그인 정보는 바뀐 것이 없고 신뢰 저장소도 아마 정상이며, 핸드셰이크에서 제시된 인증서에는 검증기가 사용하는 시각보다 늦게 시작하는 유효 기간이 있습니다. 똑같은 메시지를 만드는 상황은 세 가지이며 각각 다른 조치가 필요합니다. 아래 순서를 따르면 시계나 인증서 파일을 건드리기 전에 어느 상황인지 알 수 있습니다.

세 가지 원인 중 무엇을 보고 있는가

첫 번째 원인은 로컬입니다. 점검을 수행하는 기기의 시계가 인증서 시작일보다 앞서 있습니다. CMOS 배터리가 죽은 하드웨어, 오래된 스냅샷에서 복원한 가상 머신, 시간을 잃을 만큼 오래 꺼져 있던 장비, 그리고 아웃바운드 NTP가 차단된 것을 아무도 몰랐던 네트워크에서 볼 수 있으며, 인증서가 완전히 유효해도 이런 식으로 실패할 수 있습니다.

두 번째 원인은 발급자 쪽으로, 인증서가 정말 미래에 시작하기 때문입니다. 일찍 발급되었거나 명시적 시작 시각으로 생성되었거나 아직 실행되지 않은 활성화 단계의 일부로 서명되었으며, 세 번째 원인은 리프는 유효한데 제시된 체인의 다른 인증서가 유효하지 않아 오류가 한 번도 설치한 적 없는 자료를 지목하기 때문에 시간을 가장 많이 낭비합니다.

한 가지 질문이 이들을 갈라놓습니다. 실패가 기기를 따라가는가, 서비스를 따라가는가? 같은 네트워크의 두 머신이 다르게 동작하면 시계 문제입니다. 모든 클라이언트가 같은 방식으로 실패하면 인증서의 유효 기간과 그 뒤의 체인 문제입니다.

실제로 제시된 인증서에서 유효 기간을 읽는다

이전 배포에서 남은 PEM 파일을 검사하지 말고, 지금 서비스가 보내는 체인을 요청하세요. openssl s_client -connect vpn.example.com:443 -servername vpn.example.com -showcerts 는 체인의 모든 인증서를 출력합니다. 필요한 블록을 저장하고 openssl x509 -noout -subject -issuer -dates 를 실행하면 마지막 것이 notBefore와 notAfter를 출력하며, 이 두 값이 판단을 좌우합니다. Windows에서는 연결의 인증서 대화 상자와 내보낸 파일에 대한 certutil -dump 가 같은 필드를 보여 줍니다.

유효 기간의 양 끝을 읽으세요. 두 시간 뒤에 열리는 인증서와 두 시간 뒤에 닫히는 인증서는 다른 메시지로 실패하고 다른 팀을 부릅니다. 오류가 어느 인증서를 지목하는지(리프, 중간, 루트)를 기록해야 클라이언트 쪽에서 고칠 수 있는지가 결정됩니다.

유효 기간을 기다리지 않고 시험할 수도 있으며 검증은 명시적 시각을 받습니다. openssl verify -attime 1793600000 -CAfile ca.pem -untrusted intermediate.pem leaf.pem 는 그 타임스탬프 시점에서 체인을 평가합니다. 현재 시각으로 실행해 실패를 재현하고, 다음으로 인증서 시작 시각으로 실행해 기간이 열리면 같은 체인이 통과하는지 확인하세요. RFC 5280 은 유효성 필드와 그 밖에서 인증서를 사용해서는 안 된다는 규칙을 정의하며, 클라이언트가 방금 적용한 규칙이 바로 그것입니다.

내 시계인가, 상대 시계인가

기기 시계를 신뢰하는 출처에서 얻은 인증서의 UTC 시작 시각과 비교하세요. date -u 는 그 순간을 알려 주고, systemd 호스트에서는 timedatectl status 가 시계 동기화 여부도 보고합니다. Windows에서는 w32tm /query /status 가 현재 출처와 마지막 성공 동기화를 보여 줍니다. 트레이에 표시되는 시간대는 표시 선택일 뿐 잘못된 시계가 아니며 검증기는 UTC 순간을 비교합니다.

What you seeMost likely readingNext step
Clock behind, one device affectedLocal time faultResync time, keep validation on, retest
Clock correct, window opens soonCertificate staged earlyWait for the window or follow the cutover plan
Clock correct, intermediate not yet validChain material mismatchOperator replaces the intermediate
Some peers pass, others do notInconsistent nodesRecord each peer's chain before changing anything

시계가 뒤처져 있으면 인증서 자료를 바꾸기 전에 다시 동기화하고 다시 시험하세요. 몇 분이나 몇 시간 어긋난 기기는 만나는 최근 발급 인증서를 모두 거부하며 한 서비스만이 아니므로 단일 서비스 설명은 대개 틀립니다. 시계가 정확하고 동기화되어 있으면 기기를 보지 말고, 유효 기간은 발급자의 것이므로 통과시키기 위해 로컬 설정을 조정해서는 안 됩니다.

그 표가 결정의 전부입니다. 시계를 인증서가 기대하는 값으로 옮기는 것도 시간 점검을 끄는 것도 수리가 아니며, 둘 다 오류를 만든 상태를 숨길 뿐입니다.

리프가 멀쩡해 보이는데 체인이 실패하는 이유

갱신된 리프와 교체용 중간 인증서는 보통 함께 배포되지만 항상 같은 순간에 도착하지는 않습니다. 서비스가 자체 유효 기간이 더 늦게 시작하는 중간 인증서로 서명한 새 리프를 보낼 수도 있고, 새 리프 아래에서 더 오래된 중간 인증서를 계속 제공할 수도 있습니다. 어느 쪽이든 리프 자체의 날짜가 합리적으로 보이는 동안 체인이 실패합니다.

부하 분산 엔드포인트는 이것을 고장에서 불일치로 바꿉니다. 재시도가 성공하거나 한 네트워크만 동작한다면, 설정을 바꾸기 전에 어느 피어가 응답했고 어느 체인을 보냈는지 기록하세요. openssl s_client 는 연결된 주소를 출력하므로 몇 번 시도하면 각 노드가 같은 체인을 제공하는지 드러납니다.

검증을 그대로 유지하는 수리 경로

시계 문제는 검증을 켜 둔 채 기기에서 고칩니다. 인증서 문제는 운영자가 지금을 이미 포함하는 유효 기간으로 발급된 자료로 고칩니다. 어떤 클라이언트 설정도 아직 유효하지 않은 인증서를 유효하게 만들지 않으며, 시간 점검을 건너뛰는 플래그는 진단을 확인하기 위한 것이지 운영에 배포하기 위한 것이 아닙니다.

인증서가 계획된 활성화를 위해 준비된 경우 전환 계획을 따르세요. 유효 기간이 열릴 때 설치하거나 공급자가 문서화한 중첩 절차를 사용하고, 미리 설치해서 사용자가 경고를 클릭해 넘기도록 가르치는 것은 피하세요. 사람들이 무시하는 법을 배우는 경고는 짧은 지연보다 비쌉니다.

마지막으로 실패가 일어난 방식 그대로 다시 시험하세요. 새 세션, 같은 클라이언트, 실제로 필요한 리소스입니다. TLS 라이브러리는 연결 수명 동안 검증된 체인을 캐시할 수 있고 재개된 세션이 반드시 다시 검사하지는 않으므로 오래된 세션은 수리 후에도 계속 실패하거나 회귀 후에도 계속 동작할 수 있으며, 뷰어에서 열리는 파일은 읽을 수 있다는 것만, 완료된 핸드셰이크는 체인의 검증을 증명합니다.

티켓을 닫기 전에 네 가지를 확인하세요. 실패한 기기의 UTC 시각과 동기화 상태, 제시된 체인의 각 인증서 notBefore와 notAfter, 두 번째 클라이언트에서 같은 체인, 그리고 오류가 인증서에 붙이는 이름이며, 시계가 정확하고 유효 기간이 아직 열리지 않았다면 나머지는 운영자의 일이고 우리 쪽의 올바른 행동은 점검을 약화하는 것이 아니라 기간을 기다리는 것입니다.

관련 글