프로필 두 개, 하나는 연결되고 하나는 안 될 때 이유를 빨리 보는 방법은 diff다. 문제는 같은 diff가 인라인 개인 키, 정적 키, 파일이 담고 있는 자격 증명 블록까지 그대로 출력한다는 점이며, 사람들은 알아차리기 전에 그 출력을 채팅에 붙여 넣는다. 무엇을 비교하는지 정하는 일이 명령을 실행하기 전에 온다. 보호된 사본에서 구조와 역할을 비교하고, 다른 사람이 봐야 할 때는 별도의 마스킹된 파일을 만든다.

.ovpn 파일이 실제로 담는 것

.ovpn 파일은 선택적 인라인 블록을 가진 구성이다. CA 인증서, 클라이언트 인증서, 개인 키, tls-auth 또는 tls-crypt 키, 그리고 외부 파일을 가리키거나 자격 증명을 요구하는 지시문을 담을 수 있다. 두 파일이 거의 같아 보이면서 블록 내부에서만 다를 수도 있고, 전송 방식을 완전히 바꾸는 지시문 하나에서 다를 수도 있다. 줄 수는 그중 무엇이 일어났는지 알려 주지 않는다.

키 블록 내부의 차이는 무엇의 공개적 증거도 아니다. 재발급된 인증서와 새 키로 만든 인증서는 같은 형태의 변화를 만들 수 있으므로, 블록 불일치는 재료가 다르다는 것을 말할 뿐 어떤 결정이 그것을 만들었는지는 말하지 않는다. 필드를 비교하라는 신호로 다루고, 발견으로 다루지 않는다.

줄이 아니라 역할로 비교한다

연결 자체의 순서를 따른다: 먼저 엔드포인트와 전송, 다음으로 신뢰와 예상 신원, 다음으로 사용자 인증, 다음으로 경로, DNS, 스크립트 훅이다. 이 순서는 클라이언트가 하는 일과 맞으므로 만나는 첫 차이가 연결을 끊었을 수 있는 첫 번째 것이 된다. 대신 알파벳순으로 비교하면 관련 설정이 출력 전체에 흩어진다.

필드를 의식한 점검은 이 항목들을 그 순서로 본다. 클라이언트가 대화식으로 묻는 것은 신뢰 행이 아니라 인증 행에 속한다.

  • remote, proto 및 포트, 모든 연결 블록 포함.
  • ca 및 cert: 발급자, 주체, 만료 날짜.
  • 개인 키가 아예 있는지, 절대 무엇이 들어 있는지는 아니다.
  • tls-auth 또는 tls-crypt 존재와 키 방향.
  • 인증 지시문, 자격 증명 파일 참조 포함.
  • 연결 시 실행되는 경로, DNS 옵션, 스크립트 훅.

파일에 연결 블록이 여러 개 있으면 각 옵션을 해당 엔드포인트와 함께 둔다. 첫 remote 줄만 비교하면 클라이언트가 이 네트워크에서 실제로 선택하는 대안을 놓칠 수 있다.

왜 일반 diff가 잘못된 도구인가

일반 diff는 텍스트를 위해 만들어졌지 비밀을 위해 만들어지지 않았다. 개인 키를 기꺼이 스크롤백에 출력하고, 보고 있는 지시문이 장애와 무관하다는 것도 알려 주지 않는다. 필드 추출은 더 안전하면서 더 읽기 쉽다. 인증서 재료를 바이트가 아니라 메타데이터로 비교할 수 있기 때문이다.

openssl x509 -in ca.crt -noout -subject -issuer -enddate
openssl x509 -in client.crt -noout -subject -issuer -enddate
grep -E '^(remote|proto|port|tls-auth|tls-crypt|route|dhcp-option)' profile.ovpn

처음 두 명령은 키를 건드리지 않고 신원과 유효성을 출력하므로 그 출력은 붙여 넣어도 안전하다. grep은 지시문 이름과 값을 출력하지만 블록 본문은 절대 출력하지 않으므로, 전송이나 라우팅 차이를 의심할 때 올바른 첫 점검이 된다. 블록 자체를 비교해야 한다면 내용이 아니라 해시를 비교한다.

티켓을 위한 마스킹 사본 만들기

차이를 설명할 만큼 필드 이름과 구조를 유지하면서 실제 비밀과 불필요한 식별자를 제거한다. 같은 형태의 표식도 재료가 어디에 있고 얼마나 길었는지는 드러내므로, 그것마저 허용되는지 결정한다. 기억하는 명령을 믿는 대신 최종 첨부 파일 자체를 확인한다. 예시를 만들기 위해서만 작업 원본을 편집하지 않는다. 마스킹된 프로필은 반드시 실행 가능한 것이 아니며 다시 가져와서는 안 된다.

원본은 비슷한 이름의 디렉터리 세 개에 복사하는 대신 파일 이름과 해시로 식별 가능하게 유지한다. 해시 문자열은 어느 파일을 검토했는지 증명하기에 충분하고 유출되어도 비용이 없다. 변경이 끝나면 사본을 정리해 다음 사람이 하나의 권위 있는 파일을 물려받게 한다.

비교를 장애에 묶어 두기

비교는 한 번의 가져오기나 한 번의 연결 장애에 대한 질문에 답할 때 값을 한다. 먼저 실패하는 단계를 지목하고, 그 단계가 의존하는 필드만 비교한다. 클라이언트가 가진 모든 자격 증명을 한 디렉터리에 모으면 다음 유출 가능성이 높아지고 다음 진단이 느려진다. 질문이 좁을수록 답할 수 있는 필드 목록은 짧아진다.

새 파일이 운영자로부터 왔다면 신뢰 재료를 교체하기 전에 배포 경로를 확인한다. 변경 후에는 클라이언트가 실제로 선택한 가져온 사본과 협상된 결과를 검사한다. 다른 클라이언트 버전이 지시문을 무시하거나 다르게 읽을 수 있기 때문이다. 디스크의 파일은 실행된 연결의 증거가 아니다. 지시문의 의미는 OpenVPN 2.6 설명서에 있다.

관련 글