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_family에 AF_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.