클라이언트 로그에는 전달된 DNS 서버가 보이고 터널도 연결되어 있는데 내부 이름은 여전히 아무것도 확인되지 않는다. 전달 자체에는 문제가 없다. 옵션은 도착했지만 운영체제 리졸버는 그것을 쓰지 않았다. 대부분의 Unix 클라이언트에서 OpenVPN은 값을 넘겨주고 적용은 플랫폼에 맡기기 때문이다.

증상: 로그에는 DNS가 보이는데 이름은 여전히 실패한다

OpenVPN dhcp-option은 DNS와 도메인 정보를 나르고, 클라이언트는 받은 내용을 기록한다. 일부 구현에서는 클라이언트가 그 설정을 내부에서 적용하지만, 다른 구현에서는 통합 스크립트나 네트워크 서비스가 쓰도록 내보내기만 한다. 로그 한 줄은 이야기의 전반부만 말해 준다. 후반부는 클라이언트가 통제하지 못하는 곳에서 일어난다. 실패는 대개 그곳에 있다.

그래서 연결된 터널과 실패하는 내부 이름이 자주 함께 나타난다. 값은 있고, 사용하는 쪽이 없거나 설정이 틀렸으며, 리졸버는 연결 전에 쓰던 공용 서버를 조용히 계속 쓴다.

받았다는 것은 적용했다는 뜻이 아니다

시스템 리졸버가 여전히 다른 서비스 소유인데도 클라이언트가 전달된 DNS 값을 기록할 수 있다. 브라우저가 시스템 리졸버를 완전히 우회하는 자체 암호화 DNS 정책을 가질 수도 있으며, 그러면 한 애플리케이션은 내부 이름을 확인하고 다른 하나는 못 하는 인상적인 상황이 만들어진다.

모든 Unix 클라이언트가 같은 파일을 다시 쓴다고 가정하지 말고, 구현이 지원하는 통합 방식을 확인하라. 그 가정이 바로 아무것도 읽지 않는 리졸버 설정을 고치게 만드는 이유다.

플랫폼별로 리졸버 소유자를 찾아라

Windows에서는 이름 확인 정책 표가 특정 접미사를 특정 서버로 보낼 수 있고, VPN 클라이언트가 거기에 규칙을 설치할 수 있다. 어댑터의 DNS 목록만이 아니라 정책을 확인하라. Linux에서는 NetworkManager나 systemd-resolved가 설정을 소유할 수 있고, 둘 중 누가 소유하느냐가 재연결 시 무엇이 보존되는지를 결정한다.

실제로 질의에 응답하는 도구로 유효 상태를 읽어라. systemd-resolved 호스트에서는 resolvectl query internal.example.net, 또는 플랫폼의 동등한 것을 쓴다. 그다음 그 응답을 클라이언트 로그가 보냈다고 주장하는 DNS 서버와 비교하라.

조정 없이 리졸버 설정을 덮어쓰는 여러 서비스를 돌리지 마라. 소유자가 둘이면 결과가 간헐적으로 보이고, 재연결할 때마다 무작위로 고치거나 깨는 것처럼 보인다.

스크립트와 foreign_option

OpenVPN은 전달된 옵션을 foreign_option_N이라는 변수로 스크립트에 내보내고, 스크립트는 그것을 리졸버 명령으로 번역할 수 있다. 이 구조는 지원되는 통합이지 자동 동작이 아니며, 클라이언트에 설치하고 호출해야 한다.

스크립트에 의존한다면 실행과 종료 상태를 기록하라. 실행되지만 조용히 실패하는 스크립트는 스크립트가 없는 것과 같은 증상을 남기고, 설정이 완비되어 보이므로 알아차리기 더 어렵다. 스크립트 파일이 아니라 스크립트의 출력을 확인하라. 파일이 있다는 것은 스크립트가 실행되었다는 뜻이 아니다.

로그가 아니라 이름을 시험하라

연결한 뒤 클라이언트에서 내부 전용 호스트 이름을 질의하고, 다음으로 공개 이름을 질의한 뒤 어느 서버가 응답했는지 확인하라. 제대로 된 구성에서는 두 응답이 서로 다른 곳에서 오고, 둘 다 설계와 맞아야 한다.

이름은 확인되는데 서비스가 실패하면 DNS를 또 바꾸지 말고 라우팅과 애플리케이션 접근으로 넘어가라. OpenVPN 설명서에는 dhcp-option과 스크립트 환경이 문서화되어 있다. 다른 리졸버 파일을 고치기 전에 클라이언트가 무엇을 적용해야 하는지 확인하는 데 쓰라.

관련 글