不久前,我找到了一个防火墙封禁端口的一个项目,其效果是当除指定以外的端口被扫描的时候,会被直接封禁。
比如某个设备企图访问小钢炮的1234端口,iptables发现1234端口并没有设置开启,因此就断定这个设备是不怀好意的设备,并封禁其ip。还是挺有意思的,具体详细可访问源项目查看。
同样的,建议在开始操作之前,用crontab定时脚本,定时恢复防火墙,为自己留后门,以免误操作被ban(本人惨痛经历建议)。不过,小钢炮系统的iptable规则有点不同,是默认开机重置的,因此如果出错我们也可以直接拔掉电源重启,而其他linux系统的话,建议百度,旨在安全修改和测试,该留后门留后门。
下面以小钢炮系统为例,我们要把自定义的防火墙规则写成脚本
touch /etc/init.d/iptable_rule
把下面的内容复制到/etc/init.d/iptable_rule里面,此外要改的地方是pub-port-set的那几行,端口根据实际情况进行调整,每行一个。
#!/bin/sh
iptables -F DOCKER-USER #清空DOCKER-USER表,默认是一条没有用的规则,因此我清空了
IP_DENY_SECOND=30 #累计封禁的时间,过期后可继续访问
PORT_SCAN_MAX=3 #访问错误次数,到达3次立即封禁
DEV=eth0 #目标网卡
INPUT="-A INPUT" #在INPUT表插入
FORWARD="-A DOCKER-USER" #在DOCKER-USER表插入
# 新建可访问的端口名单
ipset create pub-port-set bitmap:port range 0-65535
# 设置你平常要用的端口,要按照自己的具体情况进行设置
ipset add pub-port-set 80
ipset add pub-port-set 443
ipset add pub-port-set 22
ipset add pub-port-set 5299
# 名单最大条数
# 例如 100Mbps网络下 IP_DENY_SECOND 秒能收到多少 SYN 包?(SYN 最小 60B)
#如果封禁时间设置了大于30秒,会联动下面这个值,直接爆错,这个时候也可手动把$IP_DENY_SECOND替换成30
#IP_SET_MAX=$((100 * 1024 * 1024 / 8 / 60 * 30))
IP_SET_MAX=$((100 * 1024 * 1024 / 8 / 60 * $IP_DENY_SECOND))
# 新建扫描者名单
ipset create scanner-ip-set hash:ip \
timeout $IP_DENY_SECOND \
maxelem $IP_SET_MAX \
counters
##新建trap-scan规则表 ##
iptables -N trap-scan
iptables -A trap-scan -m set --match-set scanner-ip-set src -j DROP
iptables -A trap-scan -j SET --add-set scanner-ip-set src
iptables -A trap-scan -j DROP
## 引用trap-scan规则表,交给 trap-scan 处理,这里分两个表引用
#一个是INPUT,处理的是与docker无关的端口
iptables -i $DEV $INPUT -p tcp --syn -m set ! --match-set pub-port-set dst -j trap-scan
iptables -i $DEV $INPUT -p tcp --syn -m set ! --update-counters --match-set scanner-ip-set src --packets-gt $PORT_SCAN_MAX -j DROP
iptables -i $DEV $INPUT -p tcp ! --syn -m conntrack ! --ctstate ESTABLISHED,RELATED -j DROP
#另一个是DOCKER-USER,处理的是与docker有关的端口
iptables -i $DEV $FORWARD -p tcp --syn -m set ! --match-set pub-port-set dst -j trap-scan
iptables -i $DEV $FORWARD -p tcp --syn -m set ! --update-counters --match-set scanner-ip-set src --packets-gt $PORT_SCAN_MAX -j DROP
iptables -i $DEV $FORWARD -p tcp ! --syn -m conntrack ! --ctstate ESTABLISHED,RELATED -j DROP
最后建议先直接执行/etc/init.d/iptable_rule进行测试 ,看被封禁ip的命令的命令:
watch -n1 ipset list scanner-ip-set

正常的效果是,当设备访问没有设置过的端口时,会立刻封禁,封禁未过期之前都不能访问小钢炮的任何服务,不过有例外,已经建立连接的服务不会被ban了,比如说你的电脑在被封禁前登录了ssh,封禁之后已经登录了的ssh仍旧可以使用。
测试正常之后就可以把脚本加入开机启动了。
echo "/etc/init.d/iptable_rule" >> /etc/rc.local
手动解除封禁的方法很简单,就是把ip从 scanner-ip-set 移除就好了
ipset del scanner-ip-set $ip
至于设置防火墙的意义,算是聊胜于无把,如果说你n1没啥重要的东西,而且只在本地设置,那也不设置也无妨。
后话:如果你是小钢炮系统,而且还不小心一条命令直接ban掉所有端口,包括ssh,主机管理界面...
恭喜你,走了我的老路(苦笑),不过还好,庆幸你看到了我的帖子吧哈哈哈哈。我已经摸索出免重刷的解决办法了:传送门