Gunakan tabel IP atau rute nol untuk daftar hitam sekitar 1 juta alamat IP?

22

Saya telah menemukan sebuah situasi di mana seorang klien perlu memasukkan satu set daftar kurang dari 1 juta alamat IP individual (tidak ada subnet), dan kinerja jaringan menjadi perhatian. Sementara saya akan menduga bahwa aturan IPTables akan memiliki lebih sedikit dampak kinerja daripada rute, itu hanya dugaan.

Apakah ada yang punya bukti kuat atau pembenaran lain untuk memilih IPTable atau null routing sebagai solusi untuk daftar hitam daftar panjang alamat IP? Dalam hal ini semuanya otomatis, jadi kemudahan penggunaan tidak terlalu menjadi perhatian.

EDIT 26-Nov-11

Setelah beberapa pengujian dan pengembangan, tampaknya tidak satu pun dari opsi ini bisa dikerjakan. Tampaknya kedua pencarian rute dan iptables melakukan pencarian linear melalui ruleet, dan terlalu lama untuk memproses banyak aturan ini. Pada perangkat keras modern, menempatkan item 1M dalam daftar hitam iptables memperlambat server menjadi sekitar 2 lusin paket per detik. Jadi IPTable dan null rute keluar.

ipset, seperti yang direkomendasikan oleh Jimmy Hedman, akan sangat bagus, kecuali bahwa itu tidak memungkinkan Anda untuk melacak lebih dari 65536 alamat dalam satu set, jadi saya bahkan tidak dapat mencoba menggunakannya kecuali seseorang memiliki ide.

Tampaknya satu-satunya solusi untuk memblokir banyak IP ini adalah melakukan pencarian indeks di lapisan aplikasi. Bukan begitu?


Informasi Lebih Lanjut:

Kasus penggunaan dalam kasus ini memblokir daftar "alamat yang diketahui melanggar" dari alamat IP dari mengakses konten statis di server web. FWIW, melakukan pemblokiran melalui Apache Deny fromsama lambatnya (jika tidak lebih) karena ia juga melakukan pemindaian linier.


FYI: Solusi kerja terakhir adalah menggunakan mod_rewrite apache bersama dengan peta DB berkeley untuk melakukan pencarian terhadap daftar hitam. Sifat terindeks DB berkeley memungkinkan daftar untuk skala dengan kinerja O (log N).

tylerl
sumber
5
Bukankah ipset ( ipset.netfilter.org ) lebih dirancang untuk menangani masalah seperti ini?
Jimmy Hedman
@ JimmyHedman: Anda harus menjawabnya. Dan kemudian tambahkan saran untuk benchmark melakukan semuanya dengan 3 cara :)
MikeyB
Saya ingin tahu apakah Anda dapat memberikan sedikit informasi tentang masalah apa yang Anda coba selesaikan? Mungkin memblokir alamat IP 1M bukan cara untuk memperbaiki masalah?
SpacemanSpiff
Akan sangat membantu untuk mengetahui mengapa Anda ingin memblokir banyak alamat ini, dan apakah Anda ingin memfilter lalu lintas INPUT atau FORWARD.
Juliano
Di sini Anda dapat melihat bagaimana ipset membuat aturan iptables sekitar 11x lebih cepat dari aturan iptables biasa. daemonkeeper.net/781/mass-blocking-ip-addresses-with-ipset Semoga bantuan ini.
Alien Torres

Jawaban:

15

coba gunakan iptables dan bangun pohon multi-level untuk mengurangi jumlah pencarian.

iptables -N rules_0_0_0_0_2
iptables -N rules_64_0_0_0_2
iptables -N rules_128_0_0_0_2
iptables -N rules_192_0_0_0_2
iptables -N rules_0_0_0_0_4
iptables -N rules_16_0_0_0_4

iptables -A INPUT -p tcp --dport 80 -s 0.0.0.0/2 -j rules_0_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 64.0.0.0/2 -j rules_64_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 128.0.0.0/4 -j rules_128_0_0_0_2
iptables -A INPUT -p tcp --dport 80 -s 192.0.0.0/4 -j rules_192_0_0_0_2

iptables -A rules_0_0_0_0_2 -s 0.0.0.0/4 -j rules_0_0_0_0_4
iptables -A rules_0_0_0_0_2 -s 16.0.0.0/4 -j rules_16_0_0_0_4

dan seterusnya - menambahkan tingkat bersarang; jelas Anda akan memerlukan cara otomatis untuk membangun aturan dan Anda harus memiliki rantai hanya untuk jaringan di mana Anda memiliki satu atau lebih pelanggar - dengan cara ini Anda dapat mengurangi jumlah pencarian yang harus dilakukan cukup signifikan dan saya pikir itu mungkin sebenarnya bekerja.

pQd
sumber
Ini terdengar seolah-olah itu bisa bekerja, secara efektif mengurangi kompleksitas waktu dari pencarian aturan firewall dari O (n) ke O (log n), secara efektif membangun pohon pencarian di iptables.
Per von Zweigbergk
Jika Anda memutuskan untuk pergi dengan rute ini, mungkin akan berguna untuk menggunakan beberapa algoritma untuk membangun pohon pencarian biner seimbang dari daftar alamat IP, dan kemudian hanya membuang struktur pohon pencarian itu sebagai seperangkat aturan IPtables.
Per von Zweigbergk
@Per von Zweigbergk - memang ... atau hanya memangkas pohon lebih awal di mana tidak perlu membuat pencarian lebih dalam. meskipun memuat jumlah aturan yang tidak saleh itu akan membutuhkan banyak waktu.
pQd
Ini adalah pendekatan yang sangat bagus. Jelas itu membutuhkan sedikit proses untuk mempertahankan, tapi itu ide yang tepat, saya pikir.
tylerl
3
@ pQd setelah kegagalan sebelumnya dengan iptables et al., Saya menerapkan solusi di apache menggunakan RewriteMap dengan database Berkeley. Tapi mekanisme saya tercepat saya menggunakan iptables dalam satu loop memuat sekitar 100 aturan per detik, sementara iptables-restore melakukan seluruh set dalam waktu sekitar 4 detik. Ini adalah komputer desktop terbaik. Mekanisme RewriteMap memiliki dampak rendah yang tidak dapat terdeteksi pada kinerja.
tylerl
11

Ini tepat untuk apa ipset.

Dari situs webnya http://ipset.netfilter.org/ :

Jika Anda menghendaki

  • menyimpan beberapa alamat IP atau nomor port dan cocok dengan koleksi dengan iptables sekaligus;
  • memperbarui aturan iptables secara dinamis terhadap alamat atau port IP tanpa penalti kinerja;
  • mengekspresikan alamat IP kompleks dan aturan berbasis port dengan satu aturan iptables tunggal dan manfaatkan kecepatan set IP

maka ipset mungkin menjadi alat yang tepat untuk Anda.

Ini ditulis oleh anggota tim inti netfilter Jozsef Kadlecsik (yang juga menulis target TOLAK) jadi ini adalah pilihan terbaik yang bisa saya pikirkan.

Bahkan termasuk dalam kernel baru-baru ini.

cstamas
sumber
Sejauh yang saya lihat, ipset menempati urutan teratas di 65k alamat IP. Apakah ada tipe set yang dapat menangani entri 1M?
tylerl
7
Jika Anda menggunakan tipe hash: ip set Anda dapat memiliki jumlah alamat yang sangat besar. Saya mencoba 1000000 dan kinerjanya cukup baik. Jika Anda mengatur -m state --state ESTABLISHED aturan sebelum memeriksa set Anda, Anda dapat memastikan Anda hanya memeriksa set pada koneksi baru yang akan meningkatkan kinerja ketika berhadapan dengan sejumlah besar paket.
Matthew Ife
Perlu disebutkan bahwa penggunaan memori ipset dengan alamat 1M mulai menjadi besar. Menurut posting ini di milis netfilter formula 2015 saat ini untuk ukuran hash ipset adalah H * 40byte + (N/4 + N%4) * 4 * element sizeyang mencapai sekitar 64MB untuk alamat 1M dalam hash slot 1,5m. Menggunakan solusi apache / berkdb menyimpan data pada disk dan hanya memuat halaman alamat aktif.
M Conrad
5

Saya belum mengujinya sendiri, tetapi ketika saya mendengar deskripsi masalah Anda, saya langsung berpikir " pf" (seperti dari OpenBSD).

pfmemiliki konsep tabel alamat yang mungkin hanya apa yang Anda cari.

Menurut beberapa penelitian yang sangat sepintas yang saya lakukan, tampaknya ini memiliki potensi untuk skala yang lebih baik daripada ipset. Menurut bab FAQ PF tentang Opsi Runtime , di luar kotak tanpa tuning, pf mendukung total 1.000 tabel, dengan total 200.000 entri di semua tabel secara default. (100.000 jika sistem memiliki <100MB memori fisik). Ini membuat saya percaya bahwa paling tidak pantas mempertimbangkan mencoba untuk menguji ini untuk melihat apakah itu bekerja pada tingkat berguna apa pun.

Tentu saja, saya berasumsi Anda menjalankan server Anda di Linux, jadi Anda harus memiliki kotak firewall terpisah yang menjalankan beberapa OS dengan pf (seperti OpenBSD atau FreeBSD). Anda mungkin juga dapat meningkatkan throughput dengan menghilangkan semua jenis penyaringan paket stateful sama sekali.

Per von Zweigbergk
sumber
Mengubah arsitektur server klien ke BSD bukanlah pilihan. Setidaknya berpikir di luar kotak.
tylerl
2
Anda tidak perlu mengubah seluruh arsitektur server menjadi BSD, itu akan cukup untuk membangun firewall untuk diletakkan di depan server yang sebenarnya. (Cukup mudah dilakukan dalam VM.)
Per von Zweigbergk
2

Sudahkah Anda menyelidiki menggunakan FIB_TRIE alih-alih FIB_HASH.

FIB_TRIE seharusnya skala jauh lebih baik untuk jumlah awalan Anda. (/ 32-an null rute masih awalan, hanya sangat spesifik)

Anda mungkin perlu mengkompilasi kernel Anda sendiri untuk menggunakannya, tetapi itu membantu.

FIB_TRIE Catatan

Joel K
sumber
2

Untuk keturunan: menurut ipsetdokumen ukuran default dari set adalah 65536, ini dapat diubah dengan opsi.

maxelem Parameter ini valid untuk perintah create dari semua set tipe hash. Itu menentukan jumlah elemen maksimal yang dapat disimpan dalam set, default 65536. Contoh:ipset create test hash:ip maxelem 2048.

Saya meletakkan ini di sini karena saya belum bisa berkomentar.

tukang potong
sumber
1

Beberapa catatan bermanfaat bagi siapa saja yang menemukan masalah ini di masa mendatang:

Pertama-tama, jangan menganalisis lalu lintas apa pun yang tidak perlu Anda lakukan. Jika Anda memblokir lalu lintas TCP, misalnya, hanya filter paket SYN, dengan cara itu Anda hanya menekan filter sekali per koneksi. Anda dapat menggunakan -m statejika Anda mau, tetapi pelacakan koneksi memiliki overhead sendiri yang mungkin ingin Anda hindari jika kinerja merupakan masalah.

Kedua, memasukkan sejuta aturan ke iptables membutuhkan waktu yang lama: beberapa menit. Jika Anda perlu melacak banyak entitas itu, sebaiknya Anda tetap keluar dari netfliter. Ukuran tipis dari peraturan memang membuat perbedaan.

Ketiga, tujuannya adalah untuk menghindari pemindaian linear; tapi sayangnya, kedua iptables dan iproute2 secara inheren linier. Anda dapat membagi aturan menjadi gaya pohon biner menjadi sejumlah besar rantai yang membatasi jumlah aturan yang harus Anda baca, tetapi meskipun demikian, iptables tidak cocok untuk ukuran masalah ini. Ini akan berhasil , tetapi itu adalah pemborosan sumber daya yang berharga.

Keempat, dan yang paling penting, mendorong beban kerja Anda ke userspace bukanlah ide yang buruk. Ini memungkinkan Anda untuk menulis kode ketat Anda sendiri atau menggunakan solusi off-the-shelf yang disetel ke set masalah Anda. Solusi saya sendiri untuk masalah ini, seperti yang disebutkan, adalah menggunakan pencarian BDB yang dipicu melalui sistem mod_rewrite apache. Ini memiliki manfaat tambahan dengan memicu hanya satu pencarian per sesi, dan hanya setelah permintaan yang valid diajukan. Dalam hal ini, kinerjanya sangat cepat dan biaya pemblokiran hampir dapat diabaikan.

Anda dapat melakukan manipulasi userspace serupa dengan iptables dengan menggunakan -j QUEUEtarget bersamaan libnetfilter_queue. Alat ini sangat kuat, sederhana, dan tidak terdokumentasi dengan baik. Saya akan merekomendasikan membaca sebanyak mungkin dari banyak sumber yang dapat Anda temukan, karena ada banyak bahan menarik yang tersebar di web yang bukan merupakan bagian dari dokumentasi resmi apa pun.

tylerl
sumber