tls-auth 실패는 보통 핸드셰이크 문제로 보고되지만, 실제로는 한 번도 그런 적이 없습니다. HMAC은 어떤 TLS 처리보다도 먼저 제어 패킷에서 검사되므로, 키나 방향이 어긋나면 인증서 문제처럼 보이는 실패가 생기고 두 계층 앞에서 판정됩니다. 봉투를 별개의 객체로 다루면 진단이 짧아집니다. 필드를 읽고, 검사가 일찍 실행되는지 확인한 다음, 양쪽이 합의해야 할 세 가지를 비교하십시오.

봉투는 만들어지는 순서대로 읽으십시오

제어 패킷은 세션 식별자, 선택적인 tls-auth HMAC, 재전송과 확인 정보, 신뢰할 수 있는 메시지 식별자를 담고, 그 뒤에 메시지 유형 페이로드가 옵니다. 메시지가 핸드셰이크 메시지라면 페이로드는 마침 TLS 암호문입니다. 관계는 이것뿐입니다. TLS 자재는 봉투가 이미 보호하는 메시지 안을 지나갑니다. 자세한 내용은 OpenVPN 네트워크 프로토콜 참조 에 제어 채널 필드가 그 순서대로 나열되어 있습니다.

신뢰성 계층을 암호 기술로 착각하기 쉽습니다. 확인, 재전송, 메시지 식별자는 제어 메시지가 신뢰할 수 없는 전송 위에서 한 번씩 순서대로 도착하도록 존재합니다. 그것들은 인증이 아니며, 올바른 메시지 식별자는 패킷을 누가 보냈는지에 대해 아무것도 증명하지 않습니다.

이 묶음은 개념으로 유지하십시오. 바이트 순서 도식이 아니고, HMAC에 들어가는 필드가 구현과 버전과 모드에 따라 달라지므로 태그를 계산하기에 충분하지도 않습니다.

검사가 핸드셰이크보다 먼저 실행됨을 보여 주십시오

공유 키를 가진 수신자는 핸드셰이크 상태를 할당하거나 공개 키 연산을 하지 않고도 HMAC을 검증하고 위조 패킷을 즉시 버릴 수 있습니다. 보호는 초기 핸드셰이크 패킷도 덮으므로, 잘못된 키가 늦은 인증 오류가 아니라 연결 실패로 나타납니다.

데몬의 상세 수준을 높이고 tun 장치가 아니라 제어 채널을 관찰하십시오:

openvpn --config /etc/openvpn/server.conf --verb 6

찾고 있는 것은 어떤 TLS 경고보다도 먼저 패킷 수준에서 보고되는 제어 채널 HMAC 검증 실패입니다. 로그에 TLS 경고가 있다면 봉투가 받아들여졌고 실패가 안쪽으로 옮겨간 것이며, 이는 다른 해결책이 필요한 다른 조사입니다.

방향 처리가 여기에도 있습니다. 정적 키 파일을 tls-auth와 함께 쓰면 두 끝은 반대 방향의 키를 받아들이고, 프로토콜은 그 분할을 이용해 가로챈 패킷이 발신자에게 반사될 수 없게 합니다. 방향을 뒤집으면 키는 그대로인데도 모든 패킷이 실패합니다. 한 번에 한쪽만 바꾸고, 그다음 두 데몬을 모두 재시작해 쌍이 함께 적재되게 하십시오.

양쪽에서 키, 방향, digest를 맞추십시오

세 값이 일치해야 하고 그중 파일은 하나뿐입니다. 정적 키의 내용은 양쪽에서 같아야 하고, 방향은 반대여야 하며, HMAC에 쓰는 digest도 같아야 합니다. 키 자료를 건드리기 전에 구성을 확인하십시오. 방향 하나가 뒤집힌 것만으로도 손상된 파일보다 많은 실패를 설명합니다:

grep -E 'tls-auth|tls-crypt|key-direction|auth ' /etc/openvpn/server.conf

공유 비밀은 편집기가 아니라 도구로 생성하고 권한은 엄격히 유지하십시오:

openvpn --genkey secret /etc/openvpn/ta.key
chmod 600 /etc/openvpn/ta.key

오래된 릴리스는 키 생성용 옵션 순서를 조금 다르게 받아들였고, 그 릴리스용으로 작성된 프로필은 아직 유통됩니다. 생성된 파일은 두 경우 모두 같은 종류의 객체이므로, 확인할 것은 양쪽이 같은 바이트를 보유하는지이지 어떤 표기가 그것을 만들었는지가 아닙니다.

tls-auth를 tls-crypt와 혼동하지 마십시오. 둘 다 제어 채널을 보호하지만, tls-crypt는 그것을 암호화하기도 하고 핸드셰이크를 관측자에게서 숨깁니다. 그리고 방향 분할을 자체 키 처리로 대체합니다. 하나를 쓰는 프로필은 다른 하나에 맞춰진 상대와 상호 운용되지 않으며, 어떤 digest 조정으로도 그 간격은 메워지지 않습니다.

태그는 실제 형식에서만 재현하십시오

바이트 단위 재현은 VPN 운영과 별개의 작업이며, 실제 입력이 있어야만 됩니다. 패킷을 만든 구현과 버전, 선택한 digest, 방향, 그리고 세션 식별자와 확인 배열을 포함한 실제 바이트입니다. 필드 목록의 텍스트 서술은 그 바이트가 아닙니다.

태그 길이는 digest에서 나오므로 고정 길이라는 가정은 누군가 그것을 바꾸는 순간 깨집니다. 블로그 글의 표가 제시하는 방식이 아니라 구현이 하는 방식으로 패킷을 해시하고, 손으로 도출한 기대값이 아니라 같은 상대에게서 얻은 캡처와 비교하십시오.

이 연습은 운영 프로필과 멀리 두십시오. 태그를 재현하는 일은 배포에서 보호를 켜야 하는지에 대해 아무것도 알려 주지 않습니다.

보호를 제거하지 않고 불일치를 되돌리십시오

유혹적인 시험은 tls-auth를 지우고 연결이 성공하는 것을 보고 키가 틀렸다고 결론내리는 것입니다. 그 답은 보호를 잃게 할 뿐 세 값 중 무엇이 어긋났는지 가르쳐 주지 않습니다. 대신 서버 쪽에서 승인된 일치 구성을 받아 그것과 비교하십시오.

변경은 되돌릴 수 있게 준비하십시오. 이전 서버 구성과 키 파일을 보관하고, 수정된 쌍을 적용하고, 클라이언트가 핸드셰이크를 완료하는지 확인한 다음에야 백업을 지우십시오. 변경 후 클라이언트가 실패하면 장애 중에 세 번째 변형을 즉석에서 만들지 말고 이전 파일을 복원하십시오. 복원은 시작하기 전에 이미 알고 있는 명령 하나여야 합니다.

마지막으로 통과한 검사의 의미를 기억하십시오. 상대가 공유 키를 가지고 있음을 증명할 뿐, 그 인증서나 계정이 승인되었음을 증명하지 않으며, 협상된 데이터 채널 암호에 대해서는 아무것도 말하지 않습니다. 권한 부여와 데이터 보호는 나중에 수립되므로, 깨끗한 봉투 검사는 출발점이지 판결이 아닙니다.

관련 글