เชลล์สคริปต์เพื่อแบน IP


8

IP บางรายการกำลังเปิดการเชื่อมต่อหลายพันครั้งในเซิร์ฟเวอร์ของฉัน ฉันมีเซิร์ฟเวอร์ Ubuntu 14 ฉันตรวจสอบการเชื่อมต่อทั้งหมดโดยใช้คำสั่งต่อไปนี้:

netstat -an | grep tcp | awk '{พิมพ์ $ 5}' | ตัด -f 1 -d: | จัดเรียง | uniq -c | เรียงลำดับ -n

จากนั้นฉันใช้กฎ iptables ต่อไปนี้เพื่อบล็อก IP ผู้ร้าย

iptables -I INPUT 1 -s xxxx -j DROP

มันทำงานได้ดีและปิดกั้นที่อยู่ IP อย่างไรก็ตามฉันไม่สามารถออนไลน์ตลอด 24/7 เพื่อตรวจสอบเซิร์ฟเวอร์ ฉันสงสัยว่ามีสคริปต์เชลล์ที่ฉันสามารถใช้ทำมันโดยอัตโนมัติหรือไม่? ตัวอย่างเช่นหาก IP เปิดการเชื่อมต่อมากกว่า X จำนวนเมื่อใดก็ควรถูกแบนโดยอัตโนมัติตามกฎ iptables ข้างต้น


6
คุณดูเพื่อดูว่าfail2banตรงกับความต้องการของคุณหรือไม่?
John1024

ขอโทษความรู้ที่ จำกัด ของฉัน ไม่ใช่ fail2ban สำหรับการรับรองความถูกต้อง ssh หรือไม่ ฉันไม่แน่ใจว่าจะใช้กับพอร์ต 80 นอกจากนี้เซิร์ฟเวอร์ของฉันเป็นเซิร์ฟเวอร์แชทดังนั้นผู้ใช้สามารถลองเชื่อมต่อ / ping ได้หลายครั้ง ในกรณีนี้ fail2ban จะสร้างสัญญาณเตือนที่ผิดพลาดจำนวนมากและห้ามการรับส่งข้อมูลที่ถูกกฎหมาย ความคิดใด ๆ
user3404047

คำตอบ:


10

อย่างแรกเลยอย่าคิดค้นล้อใหม่ นั่นคือสิ่งที่denyhostsถูกต้องสำหรับ:

   DenyHosts  is a python program that automatically blocks ssh attacks by
   adding entries to /etc/hosts.deny.  DenyHosts will  also  inform  Linux
   administrators  about  offending  hosts,  attacked users and suspicious
   logins.

เท่าที่ฉันรู้denyhostsมีไว้สำหรับsshการเชื่อมต่อเท่านั้น แต่ยัง fail2banมีข้อตกลงที่เกี่ยวข้องกับสิ่งที่สวยมาก:

   Fail2Ban consists of a client, server and configuration files to  limit
   brute force authentication attempts.

   The  server  program  fail2ban-server is responsible for monitoring log
   files and issuing ban/unban commands.  It  gets  configured  through  a
   simple  protocol  by fail2ban-client, which can also read configuration
   files and issue corresponding configuration commands to the server.

ทั้งสองมีอยู่ในที่เก็บ:

sudo apt-get install denyhosts fail2ban

คุณสามารถใช้สคริปต์นี้หากคุณต้องการ สิ่งที่ต้องการ:

#!/usr/bin/env sh
netstat -an | 
    awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="0.0.0.0"){c[a[1]]++}}
    END{for(ip in c){if(c[ip]>max){print ip}}}' |
        while read ip; do iptables -I INPUT 1 -s "$ip" -j DROP; done

awkจะดึง IPs และนับพวกเขาและพิมพ์เฉพาะที่ปรากฏมากขึ้นกว่าmaxครั้ง (ที่นี่-vmax=100เปลี่ยนได้ตาม) จากนั้น IP จะถูกป้อนไปยังลูป while ที่เรียกใช้iptablesกฎที่เกี่ยวข้อง

ในการเรียกใช้ 24/7 นี้ฉันจะสร้าง cronjob ที่รันคำสั่งด้านบนทุก ๆ นาที เพิ่มบรรทัดนี้ไปที่/etc/crontab

* * * * * root /path/to/script.sh

ขอบคุณ terdon สำหรับคำตอบที่ชัดเจน AFAIK, fail2ban สำหรับการรับรองความถูกต้อง ssh การเชื่อมต่อทั้งหมดเปิดอยู่ที่พอร์ต 80 ฉันจะสำรวจว่าฉันสามารถใช้ fail2ban บนพอร์ต 80 ได้หรือไม่สำหรับสคริปต์ที่กำหนดเองฉันจะรัน 24/7 ในพื้นหลังได้อย่างไร คำสั่งหน้าจอ? หรือติดตั้ง cron? BTW ฉันใช้เซิร์ฟเวอร์เป็นเซิร์ฟเวอร์แชทเพื่อให้บุคคลสามารถ ping ได้หลายครั้ง (หรือเปิดการเชื่อมต่อหลายรายการ) ดังนั้นฉันอาจไปหาสคริปต์ที่กำหนดเองที่คุณให้ไว้
user3404047

2
@ user3404047 คุณสามารถเรียกใช้เป็น cronjob ใช่ ดูคำตอบที่อัปเดต อย่างไรก็ตามfail2banไม่ได้มีไว้สำหรับ ssh เท่านั้น นอกจากนี้ยังทำงานได้ดีสำหรับพอร์ต 80 ดูตัวอย่างเช่นที่นี่ , ที่นี่และที่นี่
terdon

1

ตัวเลือกทางเลือกที่เป็นไปได้คือการระบุและจัดการกับปัญหาที่อยู่ IP ทั้งหมดภายในชุดกฎ iptables โดยใช้recentโมดูล ความท้าทายด้วยวิธีนี้คือขีด จำกัด Hitcount เริ่มต้นที่ 20 ดังนั้นจึงจำเป็นต้องเบี่ยงเบนจากค่าเริ่มต้นหรือสร้างตัวนับระดับพกพาที่สูงขึ้นเพื่อให้ได้จุดทริกเกอร์ Hitcount ที่สูงขึ้น

ตัวอย่างด้านล่างมาจากชุดกฎ iptables ของฉันและจะห้ามที่อยู่ IP นานกว่า 1 วันหากทำการเชื่อมต่อ TCP ใหม่ 80 พอร์ตที่พอร์ต 80 ในเวลาน้อยกว่า 12 นาที เมื่ออยู่ในรายชื่อคนเลวความพยายามในการเชื่อมต่อใด ๆ จะรีเซ็ตตัวนับ 1 วันเป็น 0 วิธีนี้สามารถไปได้สูงสุด 400 ครั้งก่อนที่จะขยายไปยังการพกพาอื่นจะต้องใช้ โปรดทราบว่ารหัสตามที่โพสต์มีโครงสร้างพื้นฐานที่จะใช้ในการแบนเป็นเวลานานเมื่อทริกเกอร์ที่สั้นกว่าหลายครั้ง ขณะนี้ฉันได้ตั้งค่าที่จะห้ามเป็นเวลานานในการเรียกครั้งแรก

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in4
#
# A NEW Connection on port 80 part 4.
#
# multiple hits on the banned list means you get a one day ban.
# (I re-load the firewall rule set often, so going longer makes
# little sense.)
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
# Place holder routine, but tested. Logs if a day ban would have
# been activated.
#
$IPTABLES -N http-new-in4
#$IPTABLES -A http-new-in4 -m recent --set --name HTTP_BAN_DAY

$IPTABLES -A http-new-in4 -j LOG --log-prefix "DAY80:" --log-level info
$IPTABLES -A http-new-in4 -j DROP

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in3
#
# A NEW Connection on port 80 part 3.
#
# carry forward to the actual banned list:
# Increment this count. Leave the previous count.
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
$IPTABLES -N http-new-in3
$IPTABLES -A http-new-in3 -m recent --remove --name HTTP_02
$IPTABLES -A http-new-in3 -m recent --update --hitcount 1 --seconds 86400 --name HTTP_BAN -j http-new-in4
$IPTABLES -A http-new-in3 -m recent --set --name HTTP_BAN

$IPTABLES -A http-new-in3 -j LOG --log-prefix "BAN80:" --log-level info
$IPTABLES -A http-new-in3 -j DROP

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in2
#
# A NEW Connection on port 80 part 2.
#
# carry forward from previous max new connections per unit time:
# Increment this count and clear the lesser significant count.
#
$IPTABLES -N http-new-in2
$IPTABLES -A http-new-in2 -m recent --remove --name HTTP_01
$IPTABLES -A http-new-in2 -m recent --update --hitcount 3 --seconds 720 --name HTTP_02 -j http-new-in3
$IPTABLES -A http-new-in2 -m recent --set --name HTTP_02

$IPTABLES -A http-new-in2 -j LOG --log-prefix "CARRY80:" --log-level info
$IPTABLES -A http-new-in2 -j ACCEPT

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in
#
# A NEW Connection on port 80:
#
$IPTABLES -N http-new-in

echo Allowing EXTERNAL access to the WWW server

# . check the static blacklist.
#
# http related
$IPTABLES -A http-new-in -i $EXTIF -s 5.248.83.0/24 -j DROP
... delete a bunch on entries ...
$IPTABLES -A http-new-in -i $EXTIF -s 195.211.152.0/22 -j DROP
$IPTABLES -A http-new-in -i $EXTIF -s 198.27.126.38 -j DROP

# . check the dynamic banned list
#
# The 1 Hour banned list (bumped to more than a day):
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j LOG --log-prefix "LIM80:" --log-level info
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j DROP

# A generic log entry. Usually only during degugging
#
#$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80ALL:" --log-level info

# Dynamic Badguy List. Least significant hit counter.  Detect and DROP Bad IPs that do excessive connections to port 80.
#
$IPTABLES -A http-new-in -m recent --update --hitcount 20 --seconds 240 --name HTTP_01 -j http-new-in2
$IPTABLES -A http-new-in -m recent --set --name HTTP_01

$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80:" --log-level info
$IPTABLES -A http-new-in -j ACCEPT

... a bunch of stuff not included here

# Allow any related traffic coming back to the server in.
#
#
$IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT

... the above is needed before the below ...

# If required, go to NEW HTTP connection sub-routine
#
$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 80 -j http-new-in
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.