Shell脚本禁止IP

一些IP正在打开我服务器的数千个连接。 我有一个Ubuntu 14服务器。 我使用以下命令检查总连接:

netstat -an | grep tcp | awk'{print $ 5}’| cut -f 1 -d:| 排序| uniq -c | 排序-n

然后我使用以下iptables规则来阻止罪魁祸首IP。

iptables -I INPUT 1 -s xxxx -j DROP

它工作正常并阻止IP地址。 但是,我不能24/7全天候在线监控服务器。 我想知道是否有任何我可以用来自动执行的Shell脚本? 例如,如果IP在任何时候打开超过X个连接数,它应该被上面的iptables规则自动禁止。

首先,不要重新发明轮子。 这正是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将提取IP并对其进行计数,并仅打印出现次数超过max的IP(此处, -vmax=100 ,相应地更改)。 然后将IP提供给运行相关iptables规则的while循环。

为了全天候运行,我会制作一个每分钟左右运行命令的cronjob。 将此行添加到/etc/crontab

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

一种可能的替代选择是使用recent模块识别和处理iptables规则集内的所有问题IP地址。 使用此方法的挑战是默认的hitcount限制为20,因此需要偏离默认值或创建更高级别的进位计数器以实现更高的hitcount触发点。

以下示例来自我的iptables规则集,并且如果在不到12分钟内在端口80上建立80个新的TCP连接,则将禁止IP地址超过1天。 一旦进入坏人列表,任何连接尝试都会将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