Làm cách nào để vô hiệu hóa tra cứu AAAA?


35

... Để bù đắp cho các máy chủ DNS bị hỏng nằm ngoài tầm kiểm soát của chúng tôi.

Vấn đề của chúng tôi: Chúng tôi triển khai các thiết bị nhúng thu thập dữ liệu cảm biến tại các trang web khác nhau, chủ yếu là IPv4. Một số trang web có mạng được bảo trì kém, ví dụ như bộ nhớ cache DNS bị hỏng hoặc / hoặc tường lửa bị hỏng hoàn toàn bỏ qua các truy vấn AAAA hoặc trả lời chúng với các phản hồi bị hỏng (ví dụ IP sai nguồn!). Là một nhà cung cấp bên ngoài cho bộ phận cơ sở, chúng tôi không có ảnh hưởng gì đến các bộ phận CNTT (đôi khi miễn cưỡng). Cơ hội để họ sửa chữa máy chủ / tường lửa DNS của họ bất cứ lúc nào sớm là rất nhỏ.

Ảnh hưởng trên thiết bị của chúng tôi là với mỗi gethostbyname (), các quy trình phải đợi cho đến khi hết thời gian truy vấn AAAA, tại thời điểm đó, một số quy trình đã hết thời gian thử kết nối của chúng.

Tôi đang tìm giải pháp ...

  • toàn hệ thống. Tôi không thể cấu hình lại hàng tá ứng dụng riêng lẻ
  • không cố định và cấu hình. Chúng tôi cần (bật lại) bật IPv6 trong đó / khi nó được sửa / triển khai. Khởi động lại là OK.
  • Nếu một giải pháp yêu cầu một thư viện lõi như glibc phải được thay thế, gói thư viện thay thế sẽ có sẵn từ một kho lưu trữ được bảo trì tốt (ví dụ: Thử nghiệm Debian, vũ trụ Ubuntu, EPEL). Tự xây dựng không phải là một lựa chọn vì rất nhiều lý do mà tôi thậm chí không biết bắt đầu từ đâu, vì vậy tôi hoàn toàn không liệt kê chúng ...

Giải pháp rõ ràng nhất sẽ là cấu hình thư viện trình phân giải, ví dụ: via / etc / { decv , nsswitch , gai } .conf để không truy vấn các bản ghi AAAA. Một tùy chọn độ phân giải no-inet6như được đề xuất ở đây sẽ chính xác là những gì tôi đang tìm kiếm. Thật không may, nó không được triển khai, ít nhất là không phải trên các hệ thống của chúng tôi (libc6-2.13-38 + deb7u4 trên Debian 7; libc6-2.19-0ubfox6.3 trên Ubuntu 14.04)

Vậy thì thế nào? Người ta tìm thấy các phương pháp sau được đề xuất trên SF và các nơi khác, nhưng không phải phương pháp nào cũng hoạt động:

  • Vô hiệu hóa IPv6 hoàn toàn, ví dụ: bằng cách liệt kê danh sách đen ipv6 LKM trong /etc/modprobe.d/ hoặc sysctl -w net.ipv6.conf.all.disable_ipv6=1. ( Vì tò mò: Tại sao trình giải quyết yêu cầu AAAA nơi IPv6 bị vô hiệu hóa? )
  • Xóa options inet6khỏi /etc/resolv.conf. Nó không ở đó ngay từ đầu, inet6chỉ đơn giản là được bật theo mặc định những ngày này.
  • Đặt options single-requesttrong /etc/resolv.conf. Điều này chỉ đảm bảo rằng các truy vấn A và AAAA được thực hiện tuần tự chứ không phải song song
  • Thay đổi precedencetrong /etc/gai.conf. Điều đó không ảnh hưởng đến các truy vấn DNS, chỉ cách xử lý nhiều câu trả lời.
  • Sử dụng các trình phân giải bên ngoài (hoặc chạy trình nền trình phân giải cục bộ phá vỡ các máy chủ DNS bị hỏng) sẽ giúp ích, nhưng thường không được phép bởi các chính sách tường lửa của công ty. Và nó có thể làm cho tài nguyên nội bộ không thể truy cập.

Ý tưởng xấu xí khác:

  • Chạy bộ đệm DNS trên localhost. Định cấu hình nó để chuyển tiếp tất cả các truy vấn không phải AAAA, nhưng để trả lời các truy vấn AAAA bằng NOERROR hoặc NXDOMAIN (tùy thuộc vào kết quả của truy vấn A tương ứng). Tôi không biết bộ đệm DNS có thể làm điều này mặc dù.
  • Sử dụng một số kết hợp iptables u32 thông minh hoặc mô-đun DNS iptables của Ondrej Caletka để khớp với các truy vấn AAAA, để từ chối icmp (cách trình phân giải lib phản ứng với điều đó?) Hoặc chuyển hướng chúng đến máy chủ DNS cục bộ phản hồi tất cả mọi thứ với một NOERROR trống.

Lưu ý rằng có những câu hỏi tương tự, liên quan đến SE. Câu hỏi của tôi khác nhau khi nó giải quyết vấn đề thực tế mà tôi đang cố gắng giải quyết, vì nó liệt kê các yêu cầu rõ ràng, vì nó liệt kê một số giải pháp không hoạt động thường được đề xuất và vì nó không dành riêng cho một ứng dụng. Sau cuộc thảo luận này , tôi đã đăng câu hỏi của mình.


13
PS: Trái với niềm tin phổ biến ở đây về SF, có một số lý do chính đáng để vô hiệu hóa IPv6 / AAAA trên máy trong mạng chỉ có IPv4, ngay cả khi DNS hoạt động: Giảm tải phát sóng; Giảm tải cho bộ phân giải DNS gần 50%; Giảm thời gian khởi động kết nối (đáng kể khi bộ đệm DNS bị lag); Thực hiện theo các thực tiễn tốt nhất để vô hiệu hóa các tính năng phi chức năng để tăng cường bảo mật và ổn định. Phải thừa nhận rằng, nếu tôi quên kích hoạt lại IPv6 một khi nó trở nên khả dụng, thì hệ thống của tôi sẽ trở thành chấn lưu kế thừa của IPv4 cản trở việc triển khai IPv6. Một người nên được phép cân nhắc những ưu điểm được liệt kê chống lại con lừa này.
Nils Toedtmann

Bất kỳ lý do nào khiến bạn không chạy trình phân giải đầy đủ trên localhost? Bằng cách đó, bạn loại bỏ sự phụ thuộc vào người giải quyết DNS (dường như) không đáng tin cậy hoàn toàn.
Sander Steffann

@SanderSteffann Chính sách tường lửa của công ty thường không cho phép điều đó. Nhưng nơi khác đó là một lựa chọn. Tôi sẽ thêm nó vào câu hỏi của tôi sau.
Nils Toedtmann

3
@joeqwerty Chúng tôi không đưa ra bất kỳ giả định nào về việc IPv6 có được hỗ trợ trên trang web hay không. Chúng tôi đưa ra giả định mặc dù các máy chủ DNS tuân thủ tiêu chuẩn. Ngoài ra, một số bộ phận IT không may làm thiếu các kỹ năng để cấu hình cơ sở hạ tầng của họ đúng cách. Xin lỗi vì đã thẳng thừng về điều đó.
Nils Toedtmann

4
Tôi hiểu bạn đang nói gì. Bạn cần làm cho hộp của bạn hoạt động trên mạng của họ chứ không phải theo cách khác, và đó là những gì bạn đang ở đây hỏi về. Tôi chỉ hơi lầm bầm khi chúng tôi trong lĩnh vực CNTT đổ lỗi cho khách hàng và không tôn trọng họ. Họ là bánh mì và bơ của chúng tôi. Dù tốt hay xấu chúng ta cần tôn trọng điều đó và tôn trọng họ. Khách hàng của chúng tôi không phải là một trở ngại cho doanh nghiệp của chúng tôi, họ là lý do cho việc kinh doanh của chúng tôi.
joeqwerty

Câu trả lời:


9

Ngừng sử dụng gethostbyname(). Bạn nên sử dụng getaddrinfo()thay thế, và nên có được trong nhiều năm nay. Trang người đàn ông thậm chí cảnh báo bạn về điều này.

Các hàm gethostbyname * (), gethostbyaddr * (), herror () và hstrerror () đã lỗi thời. Các ứng dụng nên sử dụng getaddrinfo (3), getnameinfo (3) và gai_strerror (3) để thay thế.

Dưới đây là một chương trình mẫu nhanh chóng trong C mà chứng tỏ nhìn lên chỉ bản ghi A cho một cái tên, và chụp Wireshark cho thấy rằng chỉ một tra cứu kỷ lục đi qua mạng.

Cụ thể, bạn cần phải đặt ai_familythành AF_INETnếu bạn chỉ muốn thực hiện tra cứu bản ghi. Chương trình mẫu này chỉ in các địa chỉ IP được trả về. Xem getaddrinfo()trang hướng dẫn để biết ví dụ đầy đủ hơn về cách tạo kết nối đi.

Trong bản chụp Wireshark , 172.25.50.3 là trình phân giải DNS cục bộ; việc chụp được thực hiện ở đó, vì vậy bạn cũng thấy các truy vấn và phản hồi gửi đi của nó. Lưu ý rằng chỉ có một bản ghi A được yêu cầu. Không có tra cứu AAAA đã từng được thực hiện.

#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);
}

Hấp dẫn! Tôi sẽ điều tra những ứng dụng kích hoạt yêu cầu AAAA. Nếu nó chỉ là của chúng tôi, thì tôi sẽ chuyển lời đề nghị của bạn đến các nhà phát triển của chúng tôi. Nhưng tôi có một linh cảm mạnh mẽ rằng rất nhiều phần mềm đóng gói Debian / Ubuntu đang gặp phải vấn đề này và chúng tôi sẽ không vá chúng.
Nils Toedtmann

Ứng dụng của bạn có lẽ là quan trọng nhất. Ngay cả khi bạn không thể sửa chữa mọi thứ khác, nó có thể cải thiện tình hình.
Michael Hampton

4

Khi nghi ngờ, hãy đến mã nguồn! Vì vậy, hãy xem ... gethostbyname () trông thú vị; mô tả chính xác những gì chúng ta đang thấy: trước tiên hãy thử IPv6, sau đó quay lại IPv4 nếu bạn không nhận được câu trả lời mình thích. RES_USE_INET6Lá cờ này là gì? Truy tìm lại, nó đến từ res_setoptions () . Đây là nơi resolv.confđược đọc trong.

Và .... đó là ý tưởng của tôi. Tôi hoàn toàn không rõ làm thế nào mà nó RES_USE_INET6được thiết lập nếu không resolv.conf.


RES_USE_INET6 có thể được thiết lập thông qua options inet6trong resolv.conf. Tôi đoán vấn đề của tôi là nó không thể được đặt khi nó được đặt ở thời gian biên dịch, điều mà tất cả các phân phối chính dường như làm trong những ngày này (đúng không?). Do đó, yêu cầu tính năng cho options no_inet6điều đó tôi đã đề cập ở trên.
Nils Toedtmann

1
Thật không may, như bạn có thể thấy từ mã, dường như không có no_inet6tùy chọn nào trong đó res_setoptions(). Tuy nhiên, như bạn có thể thấy từ (không-) ip6-dotint, đây là một thay đổi dễ dàng để thêm. Để kiểm tra lý thuyết rằng nó được đặt theo mặc định bởi distro của bạn, tôi lấy các tệp nguồn gói và biên dịch nó một lần "virgin" (để xác nhận rằng gói sao chép hành vi) và sau đó thêm: { STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },vào options[]mảng và xem nếu vấn đề biến mất khi bạn đặt tùy chọn đó trong resolv.conf.
BMDan

1
Cuối cùng: với giá trị của nó, tôi sẽ giải quyết vấn đề này bằng cách chạy bộ đệm DNS trên localhost (như bạn đã tham khảo ở trên). Sẽ dễ dàng hơn nhiều để duy trì proxy / bộ đệm DNS bị hack của riêng bạn so với việc duy trì phiên bản hack của thư viện hệ thống lõi.
BMDan

3

Bạn có thể sử dụng BIND làm trình phân giải cục bộ, nó có tùy chọn để lọc AAAA:

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


2
Đó là khá nặng cho một thiết bị nhúng.
Michael Hampton

Cảm ơn bạn, tôi đã không biết về bộ lọc AAAA của Bind. Như Michael đề cập, nó có lẽ không phải là một giải pháp cho chúng tôi do dấu chân lớn của Bind. Nhưng đối với những người muốn lọc ra phản hồi AAAA trong các tình huống khác thì đó có thể là một cách khả thi. Ubuntu thực sự xây dựng liên kết với "--enable-filter-aaaa", ít nhất là vào ngày 14.04. Không chắc chắn về Debian. - Xem thêm ipamworld Worldwide.blogspot.co.uk/2011/09/ Cách
Nils Toedtmann

1
Tôi đang ở ngày 14.04 và dường như tùy chọn lọc này không khả dụng.
Zitrax

0

Bạn đã thử thiết lập PDNS-recoder, đặt nó trong /etc/resolv.conf và từ chối tra cứu "AAAA" trong đó chưa? Sử dụng một cái gì đó nhưquery-local-address6=


1
query-local-address6=thực hiện một cái gì đó khác nhau (địa chỉ IPv6 để gửi truy vấn từ - lưu ý rằng ngay cả khi IPv6 bị tắt, các yêu cầu AAAA vẫn sẽ được giải quyết thông qua IPv4). Ngoài ra, tôi không thể xác định bất kỳ cài đặt nào khác sẽ lọc các truy vấn AAAA ( doc.powerdns.com/html/built-in-recthon.html ). Không có thông tin đó, câu trả lời của bạn không hữu ích lắm :(
Nils Toedtmann
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.