Memaksa permintaan DNS forwarder ke mode TCP

9

Saya telah menyiapkan server DNS pada SLES10 (saat ini mengikat 9.6) pada server multi-homed. Server ini dapat ditanyakan dari semua jaringan internal dan memberikan jawaban untuk semua jaringan internal. Kami memiliki dua zona "master" DNS terpisah. Masing-masing zona ini dilayani oleh sejumlah server Windows-DNS yang resmi.

Sekarang linux-server saya adalah server DNS sekunder untuk salah satu zona ini (zona internal pribadi) dan bertindak sebagai penerus untuk zona lain (zona internal publik).

Sampai saat ini pengaturan ini bekerja tanpa masalah. Sekarang saya mendapatkan - setelah menanyakan zona internal publik (misalnya dengan hostperintah pada klien linux) pesan kesalahan

;; Terpotong, coba lagi dalam mode TCP

wireshark-dump mengungkap penyebabnya: Query pertama keluar dalam mode UDP, jawabannya tidak sesuai dengan UDP (karena daftar agak panjang NS otoritatif), kemudian coba lagi dalam mode TCP, memberikan jawaban yang benar.

Sekarang pertanyaannya: Dapatkah saya mengonfigurasi bind saya untuk meminta forwarder dalam mode TCP tanpa mencoba UDP terlebih dahulu?

Pembaruan: Mencoba tangan saya pada ASCII-art ...

+--------------+   +--------------+   +-----------------+
| W2K8R2 DNS   |   | SLES 10 DNS  |   | W2K8R2 DNS      |
| Zone private +---+ All internal +---+ Zone public     |
| internal 2x  |   |   Zones      |   | internal 30+ x  |
+--------------+   +-+----------+-+   +-----------------+
                     |          |
                  +--+---+   +--+---+
                  |Client|   |Client|
                  +------+   +------+
Nils
sumber
diagram kecil ini akan berguna - Saya berjuang untuk mencari tahu server mana yang dari deskripsi Anda.
Alnitak
agak lebih baik, meskipun masih belum jelas antara host mana yang Anda jalankan hostperintah ini , dan permintaan apa yang sedang dikirim.
Alnitak
Klien meminta melalui SLES10 entri dari internal publik zona. Internal zona pribadi tidak menderita - karena hanya ada 2 entri NS di sana.
Nils
dan klien hanyalah penyelesai rintisan biasa?
Alnitak
sarankan Anda menambahkan minimal-responses: yeske konfigurasi BIND pada SLES 10 - ini dapat mengurangi ukuran respons. Dalam keadaan apa pun, sebagian besar kueri normal tidak akan melebihi batas 512 byte.
Alnitak

Jawaban:

8

Pertama, saya tidak akan menyebut itu kesalahan, hanya pesan informasi.

Kedua, server DNS akan selalu menjawab pertanyaan UDP (setidaknya BIND, saya tidak dapat menemukan opsi untuk menonaktifkan UDP) dan klien akan selalu (?) Mencoba mengirim kueri UDP terlebih dahulu (misalnya tidak ada opsi dalam resolv.conf untuk mengubah itu atau di JVM) - jika mereka cocok dengan paket UDP (permintaan biasanya dilakukan)

Jika Anda memiliki kasus penggunaan tertentu, Anda dapat menentukan untuk menggunakan TCP, misalnya dalam skrip shell menggunakan 'dig + tcp' atau 'host -T' untuk resolusi, dan Anda dapat menggunakan panggilan sistem 'sethostent / gethostbyname / endhostent' (lihat man halaman) untuk memaksa TCP dalam kasus lain.

Jika Anda benar-benar ingin mencoba dan memblokir UDP, satu-satunya opsi yang dapat saya lihat adalah dengan aturan iptable, tetapi saya tidak yakin bahwa pengaturan itu akan berfungsi. Saya berharap resolusi DNS akan gagal.

Dan Andreatta
sumber
secara nominal ada manfaat kinerja dari mengetahui apriori bahwa kueri UDP akan gagal, dan mencoba melalui TCP terlebih dahulu. Lihat RFC 5966 untuk beberapa diskusi tentang itu.
Alnitak
@Alnitak dan saya ingin mendapatkan manfaat itu.
Nils
1
@Nils jadi kita perlu mencari tahu mengapa EDNS tampaknya tidak berfungsi ...
Alnitak
Saya tidak punya kasus penggunaan khusus - klien akan menggunakan perpustakaan resolver mereka - tetapi setiap permintaan dan setiap jawaban akan melewati jaringan dua kali - saya tidak suka itu.
Nils
@Nils, masalahnya adalah bahwa klien memutuskan UDP / TCP, tetapi server mengetahui ukuran jawabannya.
Dan Andreatta
4

Server BIND Anda harus menggunakan EDNS (lihat RFC 2671) untuk memungkinkan paket UDP lebih dari 512 byte.

options {
    edns-udp-size 4096;
    max-udp-size 4096;
};

Ini akan memungkinkan set NS besar Anda untuk diambil melalui UDP, tanpa memerlukan overhead koneksi TCP untuk permintaan yang lebih kecil lainnya.

Namun perlu dicatat bahwa ini sebenarnya adalah nilai default. Jika EDNS tidak digunakan, entah ada sesuatu yang memblokirnya, atau server yang menerima opsi EDNS tidak mendukungnya.

Juga, perhatikan bahwa hosttidak mendukung EDNS. Sangat mungkin bahwa forwarder Anda -> kueri server sudah menggunakan EDNS, dan Anda tidak bisa melihatnya ketika Anda mencoba dengan klien lokal Anda.

Coba dig +bufsize=4096 @server hostname Aalih-alih menggunakan host.

Alnitak
sumber
Siapa yang seharusnya menggunakan ini? Baik server saya dan forwarder saya dari zona "internal publik"?
Nils
Apa arti mengirim daftar lengkap NS dalam jawabannya?
Nils
@Nils Protokol DNS mensyaratkan bahwa set lengkap entri yang cocok dengan tuple yang sama (QNAME, QTYPE dan QCLASS) tidak dapat dibagi (alias "RRset")
Alnitak
dapatkah Anda mengarahkan saya ke RFC tentang RRset ini?
Nils
1
Tuan rumah Actaully menggunakan pustaka penyelesai standar, dan di workstation saya mendukung EDNS0. Untuk menguji apakah permintaan menentukan EDNS0, jalankan 'tcpdump -x port 53' dan hex dump harus berisi (menjelang akhir, di bagian tambahan) urutan 0029 1000 0000 8000 0000, yang merupakan representasi biner dari OPT RR.
Dan Andreatta