한 사용자가 VPN을 통해 인트라넷 호스트 이름이 해석되지 않는다고 보고한다. 같은 노트북에서 나온 두 번째 보고는 누출 테스트에서 여전히 로컬 리졸버가 응답한 질의가 보인다고 말한다. 둘은 하나의 문제처럼 들리지만 실제로는 두 개이고 증거도 다르며, 첫 번째에 대한 통상적인 수리가 두 번째를 악화시킨다. 설정을 건드리기 전에 둘을 분리하라.

하나의 장애가 아닌 두 가지 증상

내부 이름 해석에 실패한다는 것은 질문이 그에 대한 답이 없는 곳으로 갔다는 뜻이다. 질의가 터널을 떠난다는 것은 답을 얻을 수 있는 상황에서도 질문이 잘못된 곳으로 갔다는 뜻이다. 이 둘은 반대되는 장애로, 하나는 답이 없는 것이고 다른 하나는 목적지가 하나 더 있는 것이다.

함정은 사무실 리졸버를 모든 곳에 추가하면 첫 번째는 고쳐지고 두 번째는 확실히 생긴다는 점이다. 공개 리졸버를 모든 곳에 추가하면 반대가 된다.

두 관찰을 모두 시각과 함께 기록한 다음 아래 네 가지 점검을 순서대로 진행하라.

어떤 어댑터의 리졸버가 질의를 받는가

Windows에서는 DNS 클라이언트가 어댑터 바인딩 순서에 따라 서버를 고르며, 터널 어댑터가 자동으로 첫 번째가 되지는 않는다. 어댑터의 고급 설정을 열어 원격 액세스 연결을 물리 어댑터 위로 옮긴 다음, 변경이 새 세션에 적용되도록 다시 연결하라.

바인딩 순서는 절반에 불과하다. 클라이언트는 어떤 이름이 그 어댑터에 속하는지도 알아야 하며, 그것은 순서가 아니라 접미사의 문제다.

작동하는 컴퓨터의 ipconfig /all 를 터널이 올라간 상태에서 찍은 노트북의 것과 나란히 두어라. 작동하는 컴퓨터는 사무실 어댑터에 연결별 DNS 접미사를 보여 줄 것이고, 노트북은 터널에서 아무것도 보여 주지 않을 수 있다. 이 차이는 «서버는 바로 거기에 있는데 이름은 여전히 해석되지 않는다»는 보고의 한 부류 전체를 설명하는데, 접미사가 없으면 짧은 이름이 사무실 리졸버가 담당하는 영역으로 완성되지 않기 때문이다.

짧은 이름은 경로보다 접미사가 먼저 필요하다

자격 없는 호스트 이름을 입력하면 리졸버에게 도메인을 추측하라고 요청하는 셈이다. 그 추측은 연결에 붙은 접미사 목록에서 나오며, 그 목록이 비어 있으면 질의는 단일 레이블로 나가 어떤 사설 영역과도 일치하지 않는다.

작동하는 컴퓨터의 접미사를 DNS 탭의 VPN 어댑터 IPv4 속성에 복사한 다음 다시 연결하라. Linux에서 이에 해당하는 것은 터널 링크의 검색 도메인이며, systemd-resolved는 이를 전역이 아니라 링크별로 노출한다.

두 설정은 메모에서 따로 유지하라. 접미사는 무엇을 묻는지를 바꾸고, 리졸버 주소는 누구에게 묻는지를 바꾼다. 하나를 고치는 동안 다른 하나가 틀리면 결과가 무작위처럼 보인다.

리졸버에게 직접 묻고, 그다음 이름을 물어라

사무실 리졸버에 직접 질의하기 는 클라이언트의 리졸버 선택을 완전히 우회하므로 이름 문제와 경로 문제를 분리한다.

nslookup intranet.corp.example 10.20.0.53
nslookup intranet
resolvectl status

첫 번째 명령은 특정 서버에 정규화된 이름을 묻는다. 응답이 오면 리졸버와 그곳으로 가는 경로는 정상이고 장애는 선택이나 접미사에 있다. 시간이 초과되면 주소가 틀렸거나 도달할 수 없으며 문제는 DNS가 아니라 라우팅이다. 두 번째 명령은 짧은 이름으로 무슨 일이 일어나는지 보여 주고, 세 번째는 systemd 호스트에서 링크별 리졸버 구성을 출력한다.

일부 네트워크가 알 수 없는 이름에 대해 돌려주는 와일드카드 응답을 주의하라. 그럴듯해 보이는 응답이 의도한 서버가 답했다는 증거는 아니므로, 반환된 주소를 내부 서비스가 실제로 쓰는 주소와 비교하라. 그 주소가 파킹 페이지나 프록시의 것이라면 리졸버는 답했지만 그 답은 결코 당신의 것이 아니었다. 이 구분은 내내 정상이던 터널을 쫓느라 쓰는 한 시간을 아껴 준다.

Linux에서 /etc/resolv.conf 를 다시 쓰는 VPN 클라이언트는 로컬 리졸버를 완전히 대체한다. vpnc는 이를 막기 위해 DNSUpdate no 를 노출하고, systemd-resolved는 나열된 도메인만 터널 링크로 라우팅할 수 있다. 두 방법 모두 공개 이름은 로컬 리졸버에 남기고 내부 이름은 사무실로 보낸다.

누출은 체크박스가 아니라 규칙이다

이름 해석은 포트 53으로 가는 UDP 교환이므로, 웹 트래픽은 나르지만 UDP는 나르지 않는 터널은 질의를 물리 경로에 남긴다. 공개 이름을 해석하는 동안 물리 NIC에서 캡처해 증명하라. 그 인터페이스에서 읽을 수 있는 형태로 질의가 보이면 터널이 그것을 나르지 않는 것이다.

sudo tcpdump -ni eth0 -c 20 'udp port 53'
resolvectl query example.com

그 인터페이스에서 질의가 읽을 수 있는 형태로 나타나면 터널은 그것을 나르지 않는다. 수리는 VPN이 배포한 리졸버로만 포트 53을 허용하고 다른 목적지는 버리는 규칙, 그리고 배포된 옵션을 조용히 버리지 않는 클라이언트 구성이다.

그 마지막 부분은 보이는 것보다 중요하다. OpenVPN을 route-nopull 로 시작하면 풀 필터를 넓혀 그것을 유지하지 않는 한 배포된 DNS 옵션이 경로와 함께 사라진다. 그리고 dhcp-option DNS 를 무시하는 클라이언트는 이전에 쓰던 것을 계속 쓴다. 서버 쪽의 어떤 변경이든 리졸버 목록이 터널이 올라올 때 전달되고 오래된 세션이 이전 상태를 계속 보여 주기 때문에 새 세션이 필요하다.

티켓을 닫기 전에 실제로 관찰한 장애가 무엇인지 기록하라. 내부 응답이 없는 것과 질의가 터널을 빠져나가는 것은 서로 다른 수리를 요구하며, 첫 번째를 고치는 접미사 변경이 두 번째를 조용히 악화시킬 수 있다. 다음에 티켓을 받는 사람은 라벨을 믿을 것이므로 라벨을 정확하게 만들어라.

관련 글