AAAA 조회를 비활성화하는 방법은 무엇입니까?


35

우리가 통제 할 수없는 깨진 DNS 서버를 보완하기 위해.

우리의 문제 : 우리는 다양한 IPv4 전용 사이트에서 센서 데이터를 수집하는 내장 장치를 배포합니다. 일부 사이트는 잘못 구성되었거나 파손 된 DNS 캐시 및 / 또는 AAAA 쿼리를 모두 무시하거나 응답이 깨진 (예 : 잘못된 소스 IP!) 응답하는 방화벽과 같이 네트워크가 제대로 유지되지 않았습니다. 시설 부서의 외부 공급 업체 인 우리는 (때로는 꺼리는) IT 부서에 영향을 미치지 않습니다. 조만간 DNS 서버 / 방화벽을 고칠 가능성은 미미합니다.

장치에 미치는 영향은 각 gethostbyname ()마다 프로세스가 AAAA 쿼리가 시간 초과 될 때까지 기다려야하며,이 시점에서 일부 프로세스는 이미 연결 시도 시간을 모두 초과 한 것입니다.

나는 해결책을 찾고 있습니다 ...

  • 시스템 전체. 수십 개의 응용 프로그램을 개별적으로 재구성 할 수 없습니다
  • 비 영구적이고 구성 가능합니다. IPv6을 고정 / 롤아웃 할 때 / 재설정해야합니다. 재부팅은 정상입니다.
  • 솔루션에 glibc와 같은 핵심 라이브러리를 교체해야하는 경우 교체 라이브러리 패키지는 잘 관리 될 것으로 알려진 리포지토리 (예 : 데비안 테스팅, 우분투 유니버스, EPEL)에서 제공해야합니다. 셀프 빌딩은 여러 가지 이유로 옵션이 아니므로 어디서부터 시작 해야할지조차 모르므로 전혀 나열하지 않습니다 ...

가장 확실한 해결책은 AAAA 레코드를 쿼리하지 않도록 / etc / { resolv , nsswitch , gai } .conf를 통해 확인자 라이브러리를 구성하는 것 입니다. 경우 resolv.conf 옵션 no-inet6제안으로 여기는 것입니다 정확히 내가 무엇을 찾고. 불행히도 적어도 우리 시스템에는 구현되지 않았습니다 (Debian 7의 libc6-2.13-38 + deb7u4; Ubuntu 14.04의 libc6-2.19-0ubuntu6.3)

그럼 어떻게? SF와 다른 곳에서 제안 된 다음과 같은 방법을 찾았지만 작동하지 않습니다.

  • 예를 들어 /etc/modprobe.d/에서 ipv6 LKM을 블랙리스트에 추가하여 IPv6을 모두 비활성화합니다 sysctl -w net.ipv6.conf.all.disable_ipv6=1. ( 호기심에서 : 리졸버가 IPv6이 비활성화 된 곳에서 AAAA를 요구하는 이유는 무엇입니까? )
  • options inet6/etc/resolv.conf에서 제거 처음 inet6에는 없었지만 요즘 기본적으로 단순히 활성화되어 있습니다.
  • options single-request/etc/resolv.conf에서 설정 이렇게하면 A 및 AAAA 쿼리가 병렬이 아닌 순차적으로 수행됩니다.
  • precedence/etc/gai.conf에서 변경 DNS 쿼리에는 영향을 미치지 않으며 여러 회신이 처리되는 방식에만 영향을줍니다.
  • 외부 확인자 (또는 손상된 DNS 서버를 우회하는 로컬 확인자 데몬을 실행)를 사용하면 도움이되지만 일반적으로 회사의 방화벽 정책에서는 허용되지 않습니다. 또한 내부 리소스에 액세스 할 수 없게 만들 수 있습니다.

다른 추악한 아이디어 :

  • localhost에서 DNS 캐시를 실행하십시오. AAAA가 아닌 모든 쿼리를 전달하지만 NOERROR 또는 NXDOMAIN (해당 A 쿼리의 결과에 따라)으로 AAAA 쿼리에 응답하도록 구성하십시오. 그래도이 작업을 수행 할 수있는 DNS 캐시를 알지 못합니다.
  • 영리한 iptables u32 일치 또는 Ondrej Caletka의 iptables DNS 모듈 을 사용하여 AAAA 쿼리를 일치 시키십시오. 빈 NOERROR를 가진 모든 것.

SE에는 비슷한 관련 질문이 있습니다. 내 질문은 자주 제기되는 비 작동 솔루션을 블랙리스트에 표시하고 단일 응용 프로그램에만 국한되지 않으므로 명시 적 요구 사항을 나열하므로 해결하려는 실제 문제를 구체화하는 한 다릅니다. 이 토론에 이어 질문을 게시했습니다.


13
PS : SF에 대한 대중의 믿음과는 달리, DNS가 작동하는 경우에도 IPv4 전용 네트워크의 컴퓨터에서 IPv6 / AAAA를 비활성화해야하는 몇 가지 이유가 있습니다. 브로드 캐스트로드를 줄입니다. DNS 확인자에 대한 부하를 거의 50 % 줄입니다. 연결 시작 시간을 줄입니다 (대개 DNS 캐시가 지연되는 경우). 모범 사례에 따라 비 기능적 기능을 비활성화하여 보안 및 안정성을 향상시킵니다. 물론 IPv6을 사용할 수있게되면 다시 활성화하는 것을 잊어 버린 경우 시스템은 IPv6 롤아웃을 방해하는 IPv4 레거시 밸러스트가됩니다. 이 단점에 대해 나열된 전문가를 평가할 수 있어야합니다.
Nils Toedtmann

localhost에서 전체 리졸버를 실행하지 않는 이유는 무엇입니까? 이렇게하면 다른 사람의 신뢰할 수없는 DNS 확인자에 대한 종속성을 제거 할 수 있습니다.
샌더 스테판

@SanderSteffann 회사 방화벽 정책은 일반적으로 허용하지 않습니다. 그러나 다른 곳에서는 이것이 옵션입니다. 나중에 질문에 추가하겠습니다.
Nils Toedtmann

3
@joeqwerty 당사는 사이트에서 IPv6가 지원되는지 여부에 대한 어떠한 가정도하지 않습니다. DNS 서버는 표준을 준수한다고 가정합니다. 또한 일부 IT 부서는 불행히도 인프라를 올바르게 구성하는 기술 부족합니다. 그것에 대해 무딘 죄송합니다.
Nils Toedtmann

4
당신이 무슨 말을하는지 이해합니다. 상자가 다른 방식으로 네트워크에서 작동하도록해야합니다. 이것이 바로 여러분이 요구하는 것입니다. 우리가 IT 분야에서 고객을 비난하고 존중하지 않을 때 조금 화가납니다. 그들은 우리의 빵과 버터입니다. 좋든 나쁘 든 우리는 그것을 존중하고 존중해야합니다. 고객은 비즈니스에 방해가되지 않으며 비즈니스의 이유입니다.
joeqwerty

답변:


9

사용을 중지하십시오 gethostbyname(). getaddrinfo()대신에 사용하고 수년 동안 사용 했어야합니다 . 맨 페이지는 심지어 이것을 경고합니다.

gethostbyname * (), gethostbyaddr * (), herror () 및 hstrerror () 함수는 더 이상 사용되지 않습니다. 애플리케이션은 대신 getaddrinfo (3), getnameinfo (3) 및 gai_strerror (3)를 사용해야합니다.

다음은 이름에 대한 A 레코드 찾는 방법을 보여주는 C의 빠른 샘플 프로그램 과 A 레코드 조회 네트워크를 통과 했음을 보여주는 Wireshark 캡처 입니다.

특히, 세트에 필요 ai_familyAF_INET만 수행 레코드 조회를 원하는 경우. 이 샘플 프로그램은 리턴 된 IP 주소 만 인쇄합니다. getaddrinfo()나가는 연결 방법에 대한 자세한 예 는 맨 페이지를 참조하십시오 .

에서 Wireshark를 캡처 , 172.25.50.3 로컬 DNS 리졸버이다; 캡처가 이루어 졌으므로 발신 쿼리 및 응답도 볼 수 있습니다. 참고 A 레코드를 요청했다. AAAA 조회는 수행되지 않았습니다.

#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <stdio.h>

int main(void) {
    struct addrinfo hints;
    struct addrinfo *result, *rp;
    int s;
    char host[256];

    memset(&hints, 0, sizeof(struct addrinfo));
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;

    s = getaddrinfo("www.facebook.com", NULL, &hints, &result);
    if (s != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
        exit(EXIT_FAILURE);
    }

    for (rp = result; rp != NULL; rp = rp->ai_next) {
        getnameinfo(rp->ai_addr, rp->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
        printf("%s\n", host);
    }
    freeaddrinfo(result);
}

흥미 롭습니다! AAAA 요청을 트리거하는 응용 프로그램을 조사하겠습니다. 그것이 우리의 것이라면, 나는 당신의 제안을 우리의 개발자에게 전달할 것입니다. 그러나 데비안 / 우분투 패키지 소프트웨어가 많이 어려움을 겪고 있다는 사실을 강력히 알고 있습니다.
Nils Toedtmann

응용 프로그램이 아마도 가장 중요한 응용 프로그램 일 것입니다. 다른 모든 것을 고칠 수는 없더라도 상황을 개선 할 수 있습니다.
마이클 햄튼

4

확실치 않은 경우 소스 코드로 이동하십시오! 이제 보자 ... gethostbyname () 이 흥미로워 보인다. 그것은 우리 가보고있는 것을 정확하게 설명합니다 : IPv6을 먼저 시도한 다음 원하는 대답을 얻지 못하면 IPv4로 넘어갑니다. 이 RES_USE_INET6깃발이 뭐야? 다시 추적하면 res_setoptions () 에서 나옵니다 . 여기 resolv.conf가 읽힌 곳 입니다.

그리고 ..... 그것은 아이디어가 아닙니다. RES_USE_INET6에 설정되어 있지 않은 경우 어떻게 설정되어 있는지 완전히 확실하지 않습니다 resolv.conf.


RES_USE_INET6 options inet6 에서 를 통해 설정할 있습니다 resolv.conf. 내 문제는 컴파일 타임에 일단 설정 되면 설정을 해제 할 수 없다는 것 입니다. 모든 주요 배포판은 오늘날 (올바른?) 따라서 options no_inet6위에서 언급 한 기능 요청 .
Nils Toedtmann

1
불행히도 코드에서 볼 수 있듯이에 no_inet6옵션 이없는 것 같습니다 res_setoptions(). 그러나 (no-)에서 볼 수 있듯이 ip6-dotint쉽게 추가 할 수 있습니다. 그것은 당신의 배포판에서 기본적으로 설정되는 것 그 이론을 테스트하기 위해, 나는 패키지 원본 파일을 잡아 줄을 추가 한 후 (패키지가 동작을 복제되었는지 확인하려면) "처녀"한 번 컴파일 : { STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },받는 options[]배열하고 있는지 에서 해당 옵션을 설정하면 문제가 해결됩니다 resolv.conf.
BMDan

1
마지막으로, 가치가있는 것을 위해 로컬 호스트에서 DNS 캐시를 실행 하여이 문제를 해결합니다 (위의 참조). 핵심 시스템 라이브러리의 해킹 된 버전을 유지하는 것보다 자신의 해킹 된 DNS 프록시 / 캐시를 유지 관리하는 것이 훨씬 쉬울 것입니다.
BMDan

3

BIND를 로컬 리졸버로 사용할 수 있으며 AAAA를 필터링하는 옵션이 있습니다.

https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html


2
임베디드 장치의 경우 꽤 무겁습니다.
마이클 햄튼

감사합니다. 바인드의 AAAA 필터에 대해 몰랐습니다. 마이클이 언급했듯이, 바인드의 큰 공간으로 인해 우리에게는 해결책이 아닐 것입니다. 그러나 다른 시나리오에서 AAAA 응답을 걸러 내려는 사람들에게는 실용적인 방법 일 수 있습니다. 우분투는 실제로 최소한 14.04에서 "--enable-filter-aaaa"로 바인드를 빌드합니다. 데비안에 대해서는 확실하지 않습니다. - 참조 ipamworldwide.blogspot.co.uk/2011/09/...
닐스 Toedtmann

1
14.04에 있는데이 필터링 옵션을 사용할 수없는 것 같습니다.
Zitrax

0

PDNS-recursor를 설정하고 /etc/resolv.conf에 설정하고 "AAAA"조회를 거부 했습니까? 같은 것을 사용하여query-local-address6=


1
query-local-address6=다른 작업을 수행합니다 (쿼리를 보낼 IPv6 주소-IPv6가 비활성화되어 있어도 AAAA 요청은 여전히 ​​IPv4를 통해 해결됨). 또한 AAAA 쿼리를 필터링하는 다른 설정 ( doc.powerdns.com/html/built-in-recursor.html )을 식별 할 수 없습니다 . 그 정보가 없으면, 당신의 대답은 그다지 도움이되지 않습니다 :(
Nils Toedtmann
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.