VPN 인증 기관을 교체하면 무슨 일이 일어나는가
VPN CA 교체는 신뢰와 신원을 각각 바꿉니다. 검증기가 무엇을 확인하는지, 오래된 터널이 왜 살아남는지, 양방향이 동작함을 어떻게 증명하는지 정리합니다.
VPN 인증 기관을 교체하는 것은 파일 교체가 아닙니다. 새 CA가 첫 인증서에 서명하는 순간, 아직 옛 CA만 신뢰하는 모든 검증기는 결정을 내려야 하고, 새 앵커를 받지 못한 호스트는 계속 좋은 피어를 거부합니다. 양방향 모두에서 실패하는 것을 보았습니다. 게이트웨이만 새 CA를 익히고 클라이언트는 익히지 못하면 새 연결은 실패하는데, 이미 올라간 터널은 그대로 남아 장애가 라우팅 문제처럼 보였습니다. 무엇이 바뀌는지, 장애가 나타나는 순서대로 정리합니다.
한 번의 교체, 두 가지 별개의 변화
인증 기관은 이름과 공개 키, 그리고 서명하는 개인 키입니다. 검증기는 ‘CA’라는 추상을 신뢰하지 않습니다. 신뢰 저장소에 이미 있는 특정 인증서를 신뢰하며, 서명 체인이 그 저장된 사본에 닿을 때만 발급자를 받아들입니다. 따라서 CA 교체는 독립적으로 실패하는 두 가지를 바꿉니다. 어떤 앵커가 받아들여지는지, 그리고 그 아래에서 어떤 피어 신원이 발급되었는지입니다.
대부분의 VPN 배포는 양방향으로 검증합니다. 클라이언트가 게이트웨이 인증서를 인증하고, 게이트웨이가 클라이언트 인증서를 인증합니다. 클라이언트 번들만 갱신하는 전환은 옛 CA 신원을 계속 제시하는 모든 클라이언트를 서버가 거부하게 두고, 반대 방향도 마찬가지로 흔합니다. 먼저 적용 지점을 목록화하십시오. 클라이언트 신뢰 저장소, 게이트웨이의 ca 파일, 그 앞에서 TLS를 종료하는 프록시, 외부에서 엔드포인트를 확인하는 프로브입니다.
검증기가 확인하는 것, 순서대로
경로 검증은 피어 인증서에서 중간 인증서를 거쳐 신뢰 앵커에 닿을 때까지 올라갑니다. 각 단계에서 서명을 검증하고, 모든 인증서가 유효 기간 안에 있는지 확인하고, 기본 제약과 키 사용이 발급자의 서명을 허용하는지 확인합니다. 그다음에야 응용 프로그램이 리프 인증서를 봅니다. 주체 대체 이름이 접속한 이름을 덮어야 하고, 확장 키 사용이 서버 또는 클라이언트 인증을 허용해야 합니다.
이 경로를 오프라인에서 재현하려면 -CAfile 을 시스템 저장소가 아니라 배포할 번들 자체로 향하게 하십시오. 그렇지 않으면 변경이 아니라 호스트를 시험하는 셈입니다:
openssl verify -CAfile new-ca.crt gateway.crt
openssl verify -CAfile new-ca.crt -untrusted intermediate.crt client.crt
openssl x509 -in gateway.crt -noout -subject -issuer -dates
openssl s_client -connect gw.example.net:443 -CAfile new-ca.crt
그 명령은 게이트웨이의 HTTPS 관리 페이지 같은 순수 TLS 리스너에만 통합니다. OpenVPN 제어 채널은 TLS보다 앞서므로 s_client로는 터널 핸드셰이크를 들여다볼 수 없습니다.
그 오류 뒤에 있는 경로 구축 규칙은 RFC 5280 6절에 있습니다. 그 규칙은 자칫 임의로 보이는 실패를 설명합니다. 아무도 기억하지 못한 만료된 중간 인증서, 키 사용이 서명을 금지하는 인증서, 시험 대상 호스트를 제외하는 이름 제약입니다.
오래된 터널이 계속 동작하는 이유
TLS와 OpenVPN은 모두 핸드셰이크가 끝난 뒤에도 성립된 세션을 살려 둡니다. 패킷마다 피어 인증서를 다시 검증하지 않으므로, 변경 전에 연결한 클라이언트는 재협상, 재연결 또는 터널 단절이 일어날 때까지 트래픽을 계속 흘려보냅니다. 바로 이 틈 때문에 CA 교체가 한 시간 동안 멀쩡해 보이다가 최악의 순간에 실패합니다. 노트북이 잠에서 깨어나고, NAT 매핑이 만료되고, 게이트웨이가 재시작됩니다.
세션 재개는 이 착각을 더 늘립니다. TLS 세션 티켓이 있으면 클라이언트는 인증서를 다시 보내지 않고 돌아올 수 있고, 재개는 경로 검증을 건너뜁니다. 첫 핸드셰이크가 이미 했기 때문입니다. 그래서 정직한 시험은 새 프로세스에서의 완전한 핸드셰이크입니다. 터널을 다시 연결하지 말고 클라이언트를 재시작하고, 시험 프로필에서는 티켓을 비활성화하는 것을 고려하십시오. 재개 경로가 끊어진 체인을 숨기지 못하게 하기 위해서입니다.
정적 키 계층은 이것과 분리해 두십시오. tls-auth 은 제어 채널에 HMAC을 더하고, tls-crypt 는 그것을 암호화하고 인증합니다. 둘 다 인증서 자료를 나르지 않으므로 어느 쪽을 돌리든 자체 실패 모드를 가진 별개의 변경입니다. 둘을 혼동하는 배포는 정적 키는 정상이고 인증서는 낡았으며 오류 메시지는 둘 다 언급하지 않는 클라이언트로 끝납니다.
주체 이름을 재사용하는 함정
하위 체계가 아무것도 바꾸지 않게 하려고 선임자의 식별 이름을 재사용하고 싶어집니다. 그것은 화면에서 발급자 줄을 안정적으로 유지하고, 필요한 유일한 신호를 파괴합니다. 주체가 같고 키가 다른 두 인증서는 이름으로 구분할 수 없으므로, 두 앵커를 함께 담은 번들은 검증기에게 후보 두 개를 주고 고를 규칙은 주지 않습니다.
그러면 경로 구축이 잘못된 쪽을 고르거나, 올바른 앵커가 있는데도 ‘로컬 발급자 인증서를 가져올 수 없음’을 보고하거나, 후보 순서가 달라 같은 번들을 가진 다른 호스트에서 성공과 실패가 갈릴 수 있습니다. 이름을 재사용해야 한다면 전환 기간에는 두 앵커를 별도 파일에 두고 명시적으로 적재하고, 모든 피어가 새 발급자를 제시한 뒤에만 합치십시오. 그렇지 않다면 대체 CA에 다른 공통 이름을 주십시오. 세대나 날짜 접미사로 충분하며, 로그와 오류 문구가 실패한 피어가 어느 기관 아래에서 발급되었는지 말해 줍니다.
네트워크를 떨어뜨리지 않는 전환
계획된 교체라면 한 번에 바꾸지 말고 제한된 기간 동안 두 앵커를 모두 받아들이십시오. 새 CA와 그 중간 인증서를 발급하고, 새 앵커를 옛 앵커 옆에 각 검증기의 번들에 넣은 다음에야 그것으로 피어 인증서를 발급하기 시작합니다. 옛 신원의 피어는 옛 앵커로 검증되고, 새 피어는 새 앵커로 동작합니다.
그 순서로 하면 각 단계가 되돌릴 수 있습니다. 피하려는 실패는 동시 전환입니다. 번들 갱신을 놓친 클라이언트가 이미 옛 앵커를 은퇴시킨 게이트웨이를 만나고, 핸드셰이크가 죽고, 어느 로그도 어느 쪽이 낡았는지 말하지 않습니다.
반대 방향으로 은퇴시키십시오. 살아남아야 할 모든 신원을 다시 발급하고, 각각이 새 체인을 제시하는지 확인한 뒤 번들에서 옛 앵커를 제거하십시오. 옛 CA의 개인 키는 서비스에서 빼내십시오. 아직 서명할 수 있는 발급자가 남아 있다면 전환이 끝나지 않은 것입니다. 인증서와 발급 기록은 감사를 위해 보관하십시오. 잃어버린 발급자는 같은 신뢰로 복원되지만, 노출된 경우에는 새 신원이 필요하고 옛 앵커로 돌아갈 수 없습니다.
파일 목록이 아니라 결과를 검증하십시오
예상한 디렉터리에 신뢰 파일이 있다는 것은 거의 아무것도 증명하지 않습니다. 응용 프로그램은 다른 경로, 다른 형식, 또는 업그레이드가 교체하는 패키지 안의 사본을 읽을 수 있습니다. 파일의 존재가 아니라 양 끝의 동작을 확인하십시오.
새 신원으로 새 연결이 성공하는지 확인하고, 다음으로 은퇴한 CA가 발급한 신원이 거부되는지 확인하십시오. 사람들이 건너뛰는 것이 바로 두 번째 시험이며, 옛 기관이 더 이상 접근을 허용하지 않음을 보여 주는 유일한 시험입니다. 배포가 CRL이나 OCSP에 의존한다면 새 인증서의 배포 지점이 해석되는지, 질의하는 피어가 응답자에 닿는지 확인하십시오.
한 번도 연결한 적 없는 클라이언트로 마무리하십시오. 프로필 상태를 지우고, 연결하고, 협상된 체인을 읽으십시오. 캐시된 세션을 재개하는 피어는 아무것도 검증하지 않았는데도 이전이 성공했다고 즐겁게 보고합니다.