Batasi koneksi maks per alamat IP dan koneksi baru per detik dengan iptables

37

Kami memiliki server Ubuntu 12.04 dengan httpd di port 80 dan kami ingin membatasi:

  • koneksi maksimum per alamat IP ke httpd hingga 10
  • koneksi baru maksimum per detik ke httpd hingga 150

Bagaimana kita bisa melakukan ini dengan iptables?

evachristine
sumber

Jawaban:

48
iptables -A INPUT -p tcp --syn --dport 80 -m connlimit --connlimit-above 15 --connlimit-mask 32 -j REJECT --reject-with tcp-reset  

Ini akan menolak koneksi di atas 15 dari satu IP sumber.

iptables -A INPUT -m state --state RELATED,ESTABLISHED -m limit --limit 150/second --limit-burst 160 -j ACCEPT  

Dalam hal ini 160 koneksi baru (benar-benar paket) diizinkan sebelum batas 150 koneksi BARU (paket) per detik diterapkan.

totti
sumber
1
Bisakah pengaturan di atas berfungsi pada semua port, bukan hanya port 80?
EminezArtus
1
Apakah Anda yakin ini sesuai IP?
LatinSuD
2
Untuk mengatur aturan ini untuk semua port, cukup hapus --dport 80.
Dan Pritts
5
Aturan kedua TIDAK berfungsi pada "koneksi baru". Ini secara eksplisit mempengaruhi koneksi yang ada ("ESTABLISHED"). Untuk melakukan koneksi baru, Anda ingin --state NEW. Anda mungkin juga mempertimbangkan menggunakan -m conntrack --ctstatedi tempat -m state --state. conntrack adalah baru dan ditingkatkan vs negara.
Dan Pritts
2
komentar di atas untuk menambahkan aturan ke-2 pada NEWkoneksi - jangan lakukan itu - secara efektif mengubah INPUTrantai Anda menjadi default accept!!!
Stuart Cardall
8

Anda ingin aturan berikut di iptables Anda untuk menjawab kedua persyaratan dalam pertanyaan Anda:

iptables -t filter -I INPUT -p tcp --dport 80 -j ACCEPT

iptables -t filter -I INPUT -p tcp --dport 80 -m state \
  --state RELATED,ESTABLISHED -j ACCEPT

# Adjust "--connlimit-above NN" to limit the maximum connections per IP
#   that you need.
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 10 --connlimit-mask 32 -j DROP

# Adjust "--connlimit-above NNN" to the maximum total connections you
#   want your web server to support
iptables -t filter -I INPUT -p tcp --syn --dport 80 -m connlimit \
  --connlimit-above 150 -j DROP

Karena kita menggunakan -I (sesuai permintaan OP) kita harus melakukannya dalam urutan terbalik jadi 'baca' dari bawah ke atas.

Saya juga menyarankan untuk mempertimbangkan perubahan --connlimit-mask NN dari 32 menjadi 24. Ini akan membatasi jaringan Kelas-C penuh (maks 256 alamat IP dalam kisaran yang sama) hingga 10 koneksi. Anda juga bisa menggunakan nomor tanpa kelas lain seperti 22 atau 30 tergantung pada bagaimana Anda berpikir layanan Anda mungkin digunakan.

Juga tergantung pada bagaimana Anda ingin klien berperilaku, Anda mungkin ingin menggunakan "-j TOLAK - menolak-tcp-reset" bukan "-j DROP" dalam dua aturan di atas, atau bahkan hanya dalam 150 koneksi maks aturan.

Jika Anda MENOLAK koneksi, peramban atau perangkat lunak yang menggunakan port 80 akan segera menunjukkan status "tidak tersedia", tetapi opsi DROP akan menyebabkan klien menunggu dan mencoba lagi beberapa kali sebelum melaporkan situs yang tidak tersedia. Saya cenderung cenderung ke DROP sendiri karena berperilaku lebih seperti koneksi yang buruk daripada server offline.

Juga, jika batas koneksi turun kembali di bawah 150 (atau 10) ketika masih mencoba lagi, maka akhirnya akan sampai ke server Anda.

Namun, opsi REJECT akan menyebabkan sedikit lebih sedikit lalu lintas ke situs Anda, karena DROP akan menyebabkannya mengirim paket tambahan saat ia mencoba lagi. Mungkin tidak semua itu relevan.

Jika di sisi lain lalu lintas port 80 Anda adalah bagian dari sebuah cluster maka REJECT akan memberi tahu pengontrol cluster bahwa ia turun dan berhenti mengirimkan lalu lintas ke sana selama durasi coba lagi.

Aturan TERKAIT, DIDIRIKAN ada dengan asumsi aturan default Anda adalah untuk memblokir semua lalu lintas (iptables -t filter -P INPUT DROP). Ini hanya menerima paket lebih lanjut milik koneksi yang diterima.

Juga --syn memberitahukannya untuk memperhatikan (atau menghitung) paket-paket yang mengatur koneksi TCP.

Ian Macintosh
sumber
Terima kasih telah berjalan melewati detail perintah ini.
txyoji
Bisakah saya mendapatkan --connlimit-mask untuk hanya memblokir alamat IP tertentu dan bukan seluruh rentang?
Analog
--Connlimit-mask 32 adalah batas alamat tunggal. Yaitu, itu seperti netmask / 32. Kurang dari itu, seperti 24 seperti netmask / 24, mengabaikan 8 bit yang lebih rendah.
Ian Macintosh
5

Anda perlu menggunakan connlimitmodul yang memungkinkan Anda untuk membatasi jumlah koneksi TCP paralel ke server per alamat IP klien (atau blok alamat).

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP
Raman_Singh
sumber
Saya memperbarui jawaban Anda, saya harap ini masih OK (mengapa "--syn" diperlukan?). + Dan bagaimana dengan "Koneksi maksimum per detik (port 80, tcp) ke 150"? Terima kasih!
evachristine
--syn berarti aturan hanya melihat paket TCP dengan flag syn - yang berarti koneksi baru. Anda dapat melakukan kira-kira sama dengan -m state --state NEW, tetapi ini mungkin lebih cepat.
Dan Pritts