จำกัด การเชื่อมต่อสูงสุดต่อที่อยู่ IP และการเชื่อมต่อใหม่ต่อวินาทีด้วย iptables


37

เรามีเซิร์ฟเวอร์ Ubuntu 12.04 ที่มี httpd บนพอร์ต 80 และเราต้องการ จำกัด :

  • การเชื่อมต่อสูงสุดต่อที่อยู่ IP ไปยัง httpd ถึง 10
  • การเชื่อมต่อใหม่สูงสุดต่อวินาทีถึง httpd ถึง 150

เราจะทำสิ่งนี้กับ iptables ได้อย่างไร

คำตอบ:


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

สิ่งนี้จะปฏิเสธการเชื่อมต่อที่สูงกว่า 15 จาก IP ต้นทางหนึ่งแหล่ง

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

ใน 160 การเชื่อมต่อใหม่ (แพ็คเก็ตจริง ๆ ) ได้รับอนุญาตก่อนที่จะ จำกัด การเชื่อมต่อ 150 ใหม่ (แพ็คเก็ต) ต่อวินาที


1
สามารถตั้งค่าด้านบนเพื่อทำงานกับพอร์ตทั้งหมดไม่ใช่แค่พอร์ต 80 หรือไม่
EminezArtus

1
คุณแน่ใจหรือไม่ว่านี้เป็นต่อ IP
LatinSuD

2
หากต้องการตั้งกฎนี้สำหรับพอร์ตทั้งหมดเพียงลบ --dport 80
Dan Pritts

5
กฎข้อที่สองไม่ทำงานบน "การเชื่อมต่อใหม่" มันมีผลต่อการเชื่อมต่อ ("ESTABLISHED") ที่มีอยู่อย่างชัดเจน หากต้องการเชื่อมต่อใหม่คุณจะต้อง - ระบุใหม่ นอกจากนี้คุณยังอาจพิจารณาใช้ในสถานที่ของ-m conntrack --ctstate -m state --stateconntrack นั้นใหม่และปรับปรุงขึ้นเมื่อเทียบกับสถานะ
Dan Pritts

2
ความคิดเห็นด้านบนสำหรับการเพิ่มกฎข้อที่ 2 ในNEWการเชื่อมต่อ - อย่าทำอย่างนั้น - มันจะเปลี่ยนINPUTเชนของคุณให้เป็นค่าเริ่มต้นaccept!!!
Stuart Cardall

8

คุณต้องการให้กฎต่อไปนี้ใน iptables ของคุณตอบคำถามทั้งสองข้อในคำถามของคุณ:

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

เนื่องจากเราใช้ -I (ตามคำขอ OP) เราจึงต้องทำในลำดับที่กลับกันดังนั้น 'อ่าน' พวกเขาจากล่างขึ้นบน

ฉันขอแนะนำให้พิจารณา - เปลี่ยนการเปลี่ยนแปลง NN หน้ากากจาก 32 เป็น 24 ซึ่งจะ จำกัด เครือข่าย Class-C เต็ม (สูงสุด 256 ที่อยู่ IP ในช่วงเดียวกัน) ถึง 10 การเชื่อมต่อ คุณสามารถใช้หมายเลขที่ไม่มีคลาสอื่น ๆ เช่น 22 หรือ 30 ขึ้นอยู่กับว่าคุณคิดว่าบริการของคุณอาจถูกนำไปใช้อย่างไร

นอกจากนี้ขึ้นอยู่กับว่าคุณต้องการให้ไคลเอ็นต์ทำงานอย่างไรคุณอาจต้องการใช้ "-j REJECT --reject-with tcp-reset" แทน "-j DROP" ในกฎสองข้อด้านบนหรือแม้กระทั่งใน 150 การเชื่อมต่อสูงสุด กฎ.

หากคุณปฏิเสธการเชื่อมต่อเบราว์เซอร์หรือซอฟต์แวร์ที่ใช้พอร์ต 80 จะแสดงสถานะ "ไม่พร้อมใช้งาน" ทันที แต่ตัวเลือก DROP จะทำให้ไคลเอ็นต์รอและลองอีกสองสามครั้งก่อนที่จะรายงานไซต์ว่าไม่พร้อมใช้งาน ฉันมักจะเอนตัวไปที่ DROP ด้วยตัวเองเพราะมันทำงานเหมือนกับการเชื่อมต่อที่แย่กว่าเซิร์ฟเวอร์ออฟไลน์

นอกจากนี้หากขีด จำกัด การเชื่อมต่อลดลงต่ำกว่า 150 (หรือ 10) ในขณะที่ยังคงลองอีกครั้งในที่สุดก็จะผ่านไปยังเซิร์ฟเวอร์ของคุณ

ตัวเลือกการปฏิเสธจะทำให้การเข้าชมเว็บไซต์ของคุณน้อยลงเนื่องจาก DROP จะทำให้การส่งแพ็กเก็ตเพิ่มเติมในขณะที่ลองใหม่ อาจไม่ใช่ทุกสิ่งที่เกี่ยวข้อง

หากการรับส่งข้อมูลพอร์ต 80 ของคุณเป็นส่วนหนึ่งของคลัสเตอร์ REJECT จะแจ้งให้คอนโทรลเลอร์คลัสเตอร์ทราบว่ามันหยุดทำงานและหยุดส่งทราฟฟิกไปยังพอร์ตนั้นในช่วงระยะเวลาที่ใช้เวลาในการลองใหม่

กฎที่เกี่ยวข้อง ESTABLISHED อยู่ภายใต้สมมติฐานว่ากฎเริ่มต้นของคุณคือบล็อกการรับส่งข้อมูลทั้งหมด (iptables -t filter -P INPUT DROP) เพียงแค่ยอมรับแพ็กเก็ตที่ละเอียดกว่าซึ่งเป็นของการเชื่อมต่อที่ยอมรับ

- ซินบอกให้ใส่ใจ (หรือนับ) แพ็กเก็ตที่ตั้งค่าการเชื่อมต่อ TCP


ขอบคุณสำหรับการเดินผ่านคำสั่งขั้นต่ำเหล่านี้
txyoji

ฉันจะได้รับ - จำกัด จำนวนเพื่อปกปิดเฉพาะที่อยู่ IP นั้นและไม่ใช่ช่วงทั้งหมดหรือไม่
อะนาล็อก

--connlimit-mask 32 เป็นขีด จำกัด ที่อยู่เดียว คือมันเป็นเหมือน / 32 netmask สิ่งที่น้อยกว่าอย่างเช่น 24 คือเหมือน / 24 netmask โดยไม่สนใจ 8 บิตที่ต่ำกว่า
Ian Macintosh

5

คุณต้องใช้connlimitโมดูลที่อนุญาตให้คุณ จำกัด จำนวนการเชื่อมต่อ TCP แบบขนานกับเซิร์ฟเวอร์ต่อที่อยู่ IP ของลูกค้า (หรือบล็อคที่อยู่)

/sbin/iptables -I INPUT -p tcp --syn --dport 80 -m connlimit \
      --connlimit-above 10 -j DROP

ฉันอัปเดตคำตอบของคุณแล้วฉันหวังว่าจะยังคงใช้ได้ (ทำไมต้องใช้ "--syn") + และวิธีการเกี่ยวกับ "การเชื่อมต่อสูงสุดต่อวินาที (พอร์ต 80, tcp) ถึง 150"? ขอขอบคุณ!
evachristine

--syn หมายความว่ากฎจะดูเฉพาะแพ็กเก็ต TCP ที่มีการตั้งค่าสถานะ syn ซึ่งหมายถึงการเชื่อมต่อใหม่ คุณสามารถทำแบบเดียวกันกับ -m state - state new แต่ก็น่าจะเร็วกว่า
Dan Pritts
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.