AdGuard Home이 LAN 주소에서 WireGuard 클라이언트에 응답합니다
0.0.0.0 바인드는 커널이 응답 소스를 선택하게 합니다. 다중 네트워크 인터페이스를 가진 호스트에서는 그 응답이 터널이 도달할 수 없는 주소에서 올 수 있습니다.
터널은 열려 있고, 방화벽은 포트 53을 허용하며, AdGuard Home은 실행 중이지만 WireGuard 클라이언트에서는 여전히 이름이 해결되지 않습니다. 쿼리는 정상적으로 도착하고 응답도 정상적으로 나가므로, 리졸버의 패킷 카운터는 건강해 보이며 서비스도 문제 없어 보입니다. 잘못되는 것은 그 응답의 출발지 주소입니다: 클라이언트가 요청하지 않은 로컬 주소에서 나가고, 클라이언트의 스텁 리졸버는 이를 버립니다. AdGuard Home 설정의 한 목록이 이를 결정하며, 일반적인 기본값은 결정을 커널에 맡깁니다.
쿼리가 도착하고, 응답은 다른 곳에서 나갑니다
10.6.0.1을 해석기로 구성한 클라이언트가 10.6.0.1 포트 53으로 UDP 쿼리를 보낸다. 그 패킷은 터널을 통과해 호스트에 도착하며, AdGuard Home이 이에 응답한다. 그러나 실제 전송되는 패킷은 호스트의 스택에서 선택한 출발지 주소를 가지는 새로운 패킷이다, 클라이언트의 예상과는 다르게.
클라이언트의 해석기가 연결된 소켓일 경우, 이는 systemd-resolved, dnsmasq 및 대부분의 스텁 해석기가 사용하는 방식과 같으며, 클라이언트는 자신이 보낸 정확한 주소로부터 온 응답만 허용한다. 192.168.1.10에서 온 응답이 10.6.0.1로 보낸 쿼리에 대해서는 어떤 파싱도 이루어지기 전에 버려진다. 해석기는 성공적인 응답을 기록하고, 클라이언트는 타임아웃을 기록하며, 두 경우 모두 사실을 말하고 있는 것이다.
그래서 카운터는 거짓말을 하지 않고, 클라이언트도 거짓말을 하지 않습니다. 필요한 증거는 세 군데에 있으며, 순서는 다음과 같습니다: 리스너가 바인딩된 주소, 커널이 클라이언트로 돌아가는 데 사용할 경로, 실제 응답 패킷의 소스 주소.
커널이 응답 소스를 선택하는 방법
UDP 소켓이0.0.0.0에 바인딩되어 있을 때 자체 소스 주소가 없으므로, 각 발신 응답마다 목적지에 대한 경로 조회가 트리거됩니다. 그런 다음 커널은 해당 경로에서 소스를 가져옵니다: 경로에서 고정된 주소나 발신 인터페이스의 기본 주소. 쿼리의 목적지 주소에 대한 정보는 기억되지 않습니다.
단일 홈을 가진 호스트에서는 답이 하나뿐이므로 보이지 않습니다. LAN 주소, WireGuard 주소 및 관리 주소를 가진 기계에서는 여러 답이 가능하며, 승자는 그 순간의 라우팅 테이블에 따라 달라집니다. 추가 경로를 추가하거나, 동일한 인터페이스에 두 번째 주소를 추가하거나, 리졸버 앞에 NAT 리다이렉트를 설정하거나, 자체 네임스페이스를 가진 컨테이너에서 AdGuard를 실행하면 선택된 소스가 클라이언트가 질의한 것과 다를 수 있습니다.
ss -lunp | grep :53는 어떤 게임에 있는지 보여줍니다.0.0.0.0:53에서 리스너는 와일드카드 경우입니다;10.6.0.1:53에서 리스너는 이미 답을 고정했습니다. 소켓을 읽는 것이 YAML을 읽는 것보다 빠르며, 마지막으로 저장된 것이 아니라 실제 실행 중인 것을 반영합니다.
bind_hosts가 실제로 제어하는 것
AdGuard Home의dns.bind_hosts는 DNS 리스너가 사용하는 로컬 주소 목록입니다. 기본 제공값은 와일드카드로, 이는 모든 로컬 주소에서 수락하고 커널이 응답마다 소스 주소를 선택하도록 합니다. 와일드카드를 클라이언트가 질의하는 주소로 바꾸면 소켓이 변경되며, 그에 따라 모든 응답의 소스 주소도 변경됩니다.
목록에는 여러 항목을 넣을 수 있으며, 이는 두 개의 네트워크를 서비스하는 리졸버에 중요합니다.10.6.0.1와192.168.1.10를 나열하면 두 개의 바인딩된 소켓이 생성되며, 그 중 하나로 도착한 질의는 도착한 주소에서 응답됩니다. 대부분의 사람들이 와일드카드가 이미 제공한다고 생각하는 동작입니다.
YAML은 일반 텍스트이며, 그 안의 주소는 호스트의 기본 주소가 아니라 터널 클라이언트가 사용하라고 전달받은 주소입니다:
dns:
bind_hosts:
- 10.6.0.1
port: 53하나의 리졸버를 두 번 설치하면 왜 의견이 다른가
플러그인 관리(plugin-managed)라는 것은, 이 문맥에서, 리졸버(resolver)가 다른 패키지에 의해 설치되고 관리된다는 것을 의미합니다: 라우터 펌웨어 패키지, NAS 패키지, 또는 홈 오토메이션(add-on) 부가 기능이 될 수 있습니다. 해당 패키지는 대개 AdGuard Home의 YAML 파일 사본을 자체적으로 제공하며, 자체 일정에 맞춰 프로세스를 재시작합니다. 반면 독립 실행형 인스턴스는 사용자가 직접 구성하는 벤더 바이너리나 컨테이너입니다. 어느 쪽이든, 동일한 업스트림 리스트와 필터 리스트를 읽는다 해도, 두 개의 독립적인 프로세스가 각각 다른 구성 파일과 바인딩 선택을 가지고 있는 것입니다. 하나는 특정 터널 주소를 바인딩할 수 있고, 다른 하나는 와일드카드를 상속하며, 웹 인터페이스는 양쪽 모두 동일하게 보입니다.
그렇기 때문에 "마이그레이션 이전에 같은 리졸버가 작동했다"는 현재 바인딩에 대해 아무것도 증명하지 못합니다. 소켓을 확인한 후, 실제로 실행 중인 프로세스가 로드한 구성 파일을 확인하세요. 다른 디렉터리에 있는 오래된 사본이 편집이 효과가 없는 것처럼 보이는 흔한 이유입니다.
핀으로 고정한 다음 터널 쪽에서 테스트하세요
변경bind_hosts터널 주소로, 서비스를 재시작하고, 소켓이 이동했는지 확인합니다:ss -lunp | grep :53이제 보여야 합니다10.6.0.1:53그리고 와일드카드 항목이 없습니다. 여전히 표시되면0.0.0.0,실행 중인 프로세스가 당신이 편집한 파일을 읽고 있지 않습니다.
그런 다음 클라이언트에서 테스트하세요. 그것이 유일하게 중요한 쪽이기 때문입니다. 쿼리와 함께dig @10.6.0.1 example.com사용자가 연습하는 경로를 연습하고, 호스트에서 캡처합니다.tcpdump -ni wg0 udp port 53응답의 출처 주소를 네트워크 상에서 보여줍니다. 이를 클라이언트의 해결기 설정에 있는 주소와 비교하세요. 두 주소가 같으면 타임아웃의 원인이 더 이상 미스터리가 아닙니다.
ip route get 10.6.0.2남은 이상 현상을 설명하는데, 이는 인터페이스와 호스트가 클라이언트로 다시 사용할 소스를 출력하기 때문입니다. 그 출력에 LAN 인터페이스 이름이 표시되면, 바인드 변경만으로는 완전한 해결이 아니며 다음에 확인할 것은 라우팅 테이블입니다.
바인드 설정으로 고칠 수 없는 것
리스너를 고정해도 터널 서브넷을 생략한 액세스 리스트, 쿼리는 허용하지만 응답은 허용하지 않는 방화벽 규칙, 또는 WireGuard 풀로 돌아가는 경로 누락을 수정하지는 못합니다. 이러한 문제들은 소스 주소보다 먼저 또는 나중에 실패하며, 각각 다른 소유자가 있습니다.
그것도 변하지 않습니다리졸버가 전달하는 상류, 바인딩 보호가 개인 이름에 대한 개인 응답을 거부하는지 여부, 또는 클라이언트가 자체 검색 도메인을 어떻게 적용하는지 여부. 그것들은 별개의 제어입니다. 응답 소스가 잘못되었을 때 바인드 주소를 변경하고, 그렇지 않을 때는 다른 것을 변경하십시오.