... untuk mengkompensasi server DNS yang rusak yang berada di luar kendali kami.
Masalah kami: Kami menggunakan perangkat tertanam yang mengumpulkan data sensor di berbagai, sebagian besar situs IPv4 saja. Beberapa situs memiliki jaringan yang tidak dikelola dengan baik, mis. Konfigurasi yang salah atau cache DNS yang rusak dan / atau firewall yang mengabaikan kueri AAAA sama sekali, atau meresponsnya dengan balasan yang rusak (mis. IP sumber salah!). Sebagai pemasok eksternal ke departemen fasilitas, kami hampir tidak memiliki pengaruh pada departemen TI (terkadang enggan). Kemungkinan mereka memperbaiki server DNS / firewall mereka dalam waktu dekat sangat kecil.
Efeknya pada perangkat kami adalah bahwa dengan setiap gethostbyname (), proses harus menunggu sampai AAAA meminta waktu habis, pada saat mana beberapa proses telah habis waktu upaya koneksi mereka sama sekali.
Saya mencari solusi yang ...
- seluruh sistem. Saya tidak dapat mengkonfigurasi ulang lusinan aplikasi secara individual
- tidak permanen dan dapat dikonfigurasi. Kita perlu (kembali) mengaktifkan IPv6 di mana / ketika itu diperbaiki / diluncurkan. Reboot tidak apa-apa.
- Jika suatu solusi memerlukan pustaka inti seperti glibc untuk diganti, paket pustaka pengganti harus tersedia dari repositori yang dikenal dengan baik (misalnya Pengujian Debian, Ubuntu universe, EPEL). Membangun sendiri bukanlah suatu pilihan karena begitu banyak alasan sehingga saya bahkan tidak tahu harus mulai dari mana, jadi saya tidak menuliskannya sama sekali ...
Solusi yang paling jelas adalah mengkonfigurasi perpustakaan resolver mis. Via / etc / { resolv , nsswitch , gai } .conf untuk tidak meminta catatan AAAA. Sebuah pilihan resolv.conf no-inet6
seperti yang disarankan di sini akan menjadi persis apa yang saya cari. Sayangnya itu tidak diterapkan, setidaknya tidak pada sistem kami (libc6-2.13-38 + deb7u4 pada Debian 7; libc6-2.19-0ubuntu6.3 di Ubuntu 14.04)
Jadi bagaimana? Satu menemukan metode berikut disarankan pada SF dan di tempat lain, tetapi tidak ada yang bekerja:
- Menonaktifkan IPv6 secara bersamaan, misalnya dengan memasukkan daftar hitam IPM6 LKM di /etc/modprobe.d/, atau
sysctl -w net.ipv6.conf.all.disable_ipv6=1
. ( Karena penasaran: Mengapa resolver meminta AAAA di mana IPv6 dinonaktifkan? ) - Menghapus
options inet6
dari /etc/resolv.conf. Itu tidak ada di tempat pertama,inet6
hanya diaktifkan secara default hari ini. - Pengaturan
options single-request
di /etc/resolv.conf. Ini hanya memastikan bahwa kueri A dan AAAA dilakukan secara berurutan daripada secara paralel - Mengubah
precedence
/etc/gai.conf. Itu tidak memengaruhi kueri DNS, hanya bagaimana beberapa balasan diproses. - Menggunakan resolvers eksternal (atau menjalankan daemon resolver lokal yang menghindari server DNS yang rusak) akan membantu, tetapi biasanya tidak diizinkan oleh kebijakan firewall perusahaan. Dan itu dapat membuat sumber daya internal tidak dapat diakses.
Gagasan jelek alternatif:
- Jalankan cache DNS di localhost. Konfigurasikan untuk meneruskan semua pertanyaan non-AAAA, tetapi untuk menanggapi pertanyaan AAAA dengan NOERROR atau NXDOMAIN (tergantung pada hasil dari kueri-A yang sesuai). Saya tidak mengetahui adanya cache DNS yang dapat melakukan ini.
- Gunakan beberapa kecocokan iptables pintar u32, atau modul DNS iptables Ondrej Caletka untuk mencocokkan permintaan AAAA, untuk menolak icmp-mereka (bagaimana lver resolver bereaksi terhadap hal itu?), Atau untuk mengarahkan mereka ke server DNS lokal yang merespons semuanya dengan NOERROR kosong.
Perhatikan bahwa ada pertanyaan serupa yang terkait pada SE. Pertanyaan saya berbeda sejauh menguraikan masalah aktual yang saya coba pecahkan, karena daftar persyaratan eksplisit, karena daftar hitam beberapa solusi yang tidak bekerja sering disarankan, dan karena tidak spesifik untuk satu aplikasi. Setelah diskusi ini , saya memposting pertanyaan saya.
sumber
Jawaban:
Berhenti menggunakan
gethostbyname()
. Anda seharusnya menggunakangetaddrinfo()
, dan seharusnya sudah bertahun-tahun sekarang. Halaman manual bahkan memperingatkan Anda tentang ini.Berikut ini adalah contoh program cepat di C yang menunjukkan hanya mencari catatan A untuk nama, dan penangkapan Wireshark menunjukkan bahwa hanya pencarian catatan A pergi melalui jaringan.
Secara khusus, Anda perlu set
ai_family
untukAF_INET
jika Anda hanya ingin Sebuah catatan pencarian dilakukan. Program sampel ini hanya mencetak alamat IP yang dikembalikan. Lihatgetaddrinfo()
halaman manual untuk contoh yang lebih lengkap tentang cara membuat koneksi keluar.Dalam penangkapan Wireshark , 172.25.50.3 adalah resolver DNS lokal; tangkapan diambil di sana, jadi Anda juga melihat pertanyaan dan respons keluarnya. Perhatikan bahwa hanya catatan A yang diminta. Tidak ada pencarian AAAA yang pernah dilakukan.
sumber
Jika ragu, buka kode sumber! Jadi, mari kita lihat ... gethostbyname () terlihat menarik; yang menggambarkan dengan tepat apa yang kita lihat: coba IPv6 terlebih dahulu, lalu kembali ke IPv4 jika Anda tidak mendapatkan jawaban yang Anda suka.
RES_USE_INET6
Bendera apa ini ? Menelusuri kembali, itu berasal dari res_setoptions () . Di sinilahresolv.conf
dibaca.Dan .... itu saya kehabisan ide. Saya benar-benar tidak jelas bagaimana
RES_USE_INET6
pengaturannya jika tidakresolv.conf
.sumber
options inet6
inresolv.conf
. Saya kira masalah saya adalah bahwa hal itu tidak dapat diset setelah itu ditetapkan pada waktu kompilasi, yang semua distro utama tampaknya lakukan hari ini (benar?). Oleh karena itu permintaan fitur untukoptions no_inet6
yang saya sebutkan di atas.no_inet6
opsi dires_setoptions()
. Namun, seperti yang Anda lihat dari (tidak-)ip6-dotint
, ini merupakan perubahan yang mudah untuk ditambahkan. Untuk menguji teori bahwa ia diset secara default oleh distro Anda, saya akan mengambil file source paket dan mengkompilasinya sekali "virgin" (untuk mengonfirmasi bahwa paket mereplikasi perilaku) dan kemudian menambahkan:{ STRnLEN ("no-inet6"), 1, ~RES_USE_INET6 },
keoptions[]
array dan melihat apakah masalah hilang saat Anda mengatur opsi itu diresolv.conf
.Anda dapat menggunakan BIND sebagai resolver lokal, ia memiliki opsi untuk memfilter AAAA:
https://kb.isc.org/article/AA-00576/0/Filter-AAAA-option-in-BIND-9-.html
sumber
Apakah Anda mencoba men-setup PDNS-recursor, meletakkannya di /etc/resolv.conf Anda dan menolak pencarian "AAAA" di dalamnya? Menggunakan sesuatu seperti
query-local-address6=
sumber
query-local-address6=
melakukan sesuatu yang berbeda (dari mana alamat IPv6 mengirim pertanyaan - perhatikan bahwa meskipun IPv6 dinonaktifkan, permintaan AAAA masih akan diselesaikan melalui IPv4). Juga saya tidak dapat mengidentifikasi pengaturan lain yang akan memfilter kueri AAAA ( doc.powerdns.com/html/built-in-recursor.html ). Tanpa informasi itu, jawaban Anda tidak terlalu membantu :(