사무실 LAN에서는 내부 이름이 즉시 응답합니다. VPN이 연결되는 순간 작동이 멈추고, 애플리케이션은 타임아웃을 보고하며, 터널 자체는 불평 없이 트래픽을 전달하고 있습니다. 달라진 것은 리졸버이며, 그 리졸버는 사설 주소에 대해 나름의 견해를 가지고 있습니다.

리바인딩 보호는 특정한 수법 하나를 막기 위해 존재합니다. 일부러 게시된 사설 이름은 방어가 작동할 만큼 비슷하게 보입니다.

정책보다 응답을 먼저 읽으세요

VPN이 실제로 배포하는 리졸버에 이름을 질의하세요. 집에서 노트북이 쓰는 리졸버가 아니라, 응답을 기대하는 레코드와 비교하고, 응답이 비어 있는지, 거부되었는지, 아니면 아무도 계획하지 않은 공인 주소로 가득한지 기록하세요.

증상은 서로 겹치므로 응답의 모양이 진단을 결정합니다. NXDOMAIN은 레코드 누락, REFUSED는 접근 규칙, 내부 이름에 대한 공인 주소는 정책 또는 split DNS 오류, 그리고 클라이언트가 쓸 수 없는 올바른 사설 주소는 전혀 다른 문제입니다. 거부된 연결이나 멈춘 요청은 그 자체로 아무것도 증명하지 못하므로, 이런 티켓의 첫 명령은 재시작이 아니라 조회여야 합니다. 무엇이든 바꾸기 전에 응답을 적어 두세요.

방어가 실제로 막는 것

DNS 리바인딩은 클라이언트가 이미 이름을 신뢰한 뒤에 그 이름이 어디로 해석되는지를 바꾸는 방식으로 작동합니다. 공격자가 제어하는 이름에서 페이지가 로드되고, 응답이 사설 주소로 뒤집히며, 브라우저는 직접 연결은 결코 받아들이지 않았을 로컬 네트워크의 무언가와 대화하도록 속습니다. 방어는 리졸버가 사설 이름 공간을 서비스하도록 요청받은 적이 없을 때 사설 공간을 가리키는 응답을 거부하는 것입니다. 그 비대칭이 공격의 전부입니다.

dnsmasq는 도메인별 예외와 함께 바로 그 동작을 문서화합니다. 자사의 매뉴얼에서 rebind-domain-ok 를 그러한 주소를 정당하게 반환할 수 있는 도메인을 지정하는 방법으로 설명합니다. 의도된 수정은 범위가 한정된 허용이지 전역 스위치가 아니라는 신호로 읽으세요.

예외를 이름 공간으로 한정하세요

먼저 이름 공간을 고치고, 그다음 예외를 고칩니다. 실패하는 이름이 조직이 관리하는 도메인에 속하고 레코드가 의도적으로 유지되는지 확인하세요. 익숙한 LAN 범위와 비슷하기만 한 예상치 못한 주소는 예외가 아니라 의심을 받을 만하므로, 어떤 허용도 쓰기 전에 영역 소유자를 확인하세요.

# ask the resolver the VPN pushed, and show the full answer
dig +noall +answer db.corp.example @10.40.0.1
dig +short db.corp.example @10.40.0.1

# dnsmasq: what does the running configuration already allow?
grep -R 'rebind' /etc/dnsmasq.d /etc/dnsmasq.conf

그다음 VPN 클라이언트가 질의하는 리졸버 구성에서, 도메인 하나 또는 위임된 하위 도메인 하나로 의도한 이름을 포괄하는 가장 좁은 허용을 추가하세요. 그 리졸버의 모든 이름에 대해 보호를 끄면 필요 없었던 이름까지 포함해 전부의 방어가 한 번에 사라집니다.

Split DNS도 같은 결정에 속하며, 사설 이름 공간이 내부 리졸버에서만 응답되어야 한다면 거기에 게시하고 공인 리졸버로 새는 것을 멈추세요. 그러면 예외가 모든 경로가 아니라 한 경로를 덮습니다.

리소스와 방어를 다시 테스트하세요

다시 질의한 뒤 서비스에 접속해 클라이언트가 보는 것을 확인하세요. 올바른 사설 응답과 정상 세션이면 예외가 적용된 것입니다. 올바른 응답인데 세션이 멈춘다면 다음 용의자는 경로나 서비스 ID입니다.

# the internal name and the public control should behave differently
dig +short db.corp.example @10.40.0.1
dig +short www.example.com @10.40.0.1

# and the service itself, with the certificate it presents
curl -sS -o /dev/null -w '%{http_code}\n' https://db.corp.example/health

같은 리졸버로 공인 이름도 테스트하세요. 예외 밖의 이름에서는 보호가 계속 올바르게 작동해야 하며, 그 확인이 실패하면 변경이 의도보다 넓었던 것입니다. 인증서 검증은 내내 그대로 두세요, 올바르게 해석되는 이름도 서비스가 제시하는 인증서와 일치해야 하기 때문입니다.

거부된 응답, 도메인, 리졸버, 정책 소유자를 티켓에 기록하세요. 그 기록이 수수께끼 같은 내부 장애를 누군가 검토할 수 있는 구성 변경으로 바꿉니다.

관련 글