Shell脚本禁止IP


8

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

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

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

iptables -I输入1 -s xxxx -j DROP

一切正常,并阻止IP地址。但是,我无法24/7全天候在线监视服务器。我想知道是否可以使用任何Shell脚本来自动执行?例如,如果IP随时打开的连接数超过X,则上述iptables规则应自动禁止该IP。


6
您是否查看过fail2ban是否满足您的需求?
John1024

请问我有限的知识。是不是fail2ban用于ssh身份验证?我不确定在端口80上使用它。此外,我的服务器是聊天服务器,因此用户可以尝试多次连接/ ping通。在这种情况下,fail2ban会创建许多误报警报并禁止合法流量。任何想法?
user3404047 2015年

Answers:


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将提取的IP地址,并指望他们和只打印那些出现超过max倍(这里-vmax=100,相应修改)。然后将IP馈送到运行相关iptables规则的while循环。

要运行此24/7,我将创建一个cronjob,每分钟左右运行一次以上命令。将此行添加到/etc/crontab

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

感谢terdon的准确回答。AFAIK,fail2ban用于ssh身份验证。所有连接都在端口80上打开。我将探讨是否可以在端口80上使用fail2ban。对于自定义脚本,我如何在后台24/7运行它?屏幕命令?还是安装cron?顺便说一句。我将服务器用作聊天服务器,因此一个人可以ping通多次(或打开多个连接),因此我可能会使用您提供的自定义脚本。
user3404047 '10 -10-10

2
@ user3404047,您可以将其作为cronjob运行,是的。查看最新答案。但是,fail2ban不仅限于ssh。它对于端口80也可以正常工作。例如,请参见此处此处此处
terdon 2015年

1

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

下面的示例来自我的iptables规则集,如果它在不到12分钟的时间内在端口80上建立了80个新的TCP连接,则将在1天之内禁止ip地址。一旦进入坏人名单,任何尝试连接的尝试都会将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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.