我面临一些主机向我的网络服务器 ( NGINX ) 发送大量请求的情况。我试图通过 iptables、ipset和一个很好的旧DROP
规则来阻止它们。
该规则对连接有效NEW
,但是只要孩子们可以进来并建立ESTABLISHED
连接RELATED
,我的 DROP 规则就会失败,因为我的防火墙也有一个iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
规则。
我的防火墙配置的相关部分是:
# iptables -nL
Chain INPUT (policy ACCEPT)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
DROP all -- 0.0.0.0/0 0.0.0.0/0 match-set Blacklist src
ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 multiport dports 80,443
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
ipsetBlacklist
包括有问题的 IP:
# ipset list Blacklist | grep <attacking-server-ip>
<attacking-server-ip>
问题是:我怎样才能杀死所有的 TCP 连接,甚至是 ESTABLISHED 或 RELATED 连接?
我尝试过的事情:
Stop-wait-30-secs-start the webserver ( service nginx stop && sleep 30 && service nginx start
) - 值得一试,但由于连接已经建立,它会持续存在。
conntrack --flush
和conntrack -F
。没有效果
tcpkill
:只要我保持进程运行,它就可以工作。但是一旦我关闭进程,连接就会恢复。我真的无法解释
conntrack -D --orig-src <attacking-server-ip>
: 连接被删除,但随后又立即出现。
要检查我使用的连接:
netstat -putan | grep '<attacking-server-ip>'
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60763 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60807 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60545 ESTABLISHED 2372190/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59785 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59730 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59841 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60578 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60941 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59390 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59849 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60744 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59766 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59819 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60679 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59603 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60134 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60907 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59732 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60128 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60437 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59623 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59356 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60502 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59414 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60592 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59370 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60861 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59783 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59858 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59769 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60817 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59393 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60479 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60450 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59401 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60838 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60123 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60854 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59445 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59419 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60111 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60934 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60510 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60832 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60922 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60447 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60171 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60536 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59344 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59394 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59369 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60601 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59754 TIME_WAIT -
tcp 0 5534 <my-server-ip>:443 <attacking-server-ip>:60954 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60895 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60236 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60099 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:59460 TIME_WAIT -
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60570 ESTABLISHED 2372191/nginx: work
tcp 0 0 <my-server-ip>:443 <attacking-server-ip>:60555 ESTABLISHED 2372191/nginx: work
还:
# conntrack -L --orig-src <attacking-server-ip>
tcp 6 431977 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=62907 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=62907 [ASSURED] mark=0 use=1
tcp 6 431989 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63062 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63062 [ASSURED] mark=0 use=1
tcp 6 431976 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=62882 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=62882 [ASSURED] mark=0 use=1
tcp 6 299 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63215 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63215 [ASSURED] mark=0 use=1
tcp 6 431975 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=62869 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=62869 [ASSURED] mark=0 use=1
tcp 6 271 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=62800 dport=443 [UNREPLIED] src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=62800 mark=0 use=1
tcp 6 299 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63211 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63211 [ASSURED] mark=0 use=1
tcp 6 431977 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=62902 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=62902 [ASSURED] mark=0 use=1
tcp 6 431987 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63038 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63038 [ASSURED] mark=0 use=1
tcp 6 431999 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63195 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63195 [ASSURED] mark=0 use=1
tcp 6 431976 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=62887 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=62887 [ASSURED] mark=0 use=1
tcp 6 431988 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63050 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63050 [ASSURED] mark=0 use=1
tcp 6 431999 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63201 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63201 [ASSURED] mark=0 use=1
tcp 6 431998 ESTABLISHED src=<attacking-server-ip> dst=<my-server-ip> sport=63181 dport=443 src=<my-server-ip> dst=<attacking-server-ip> sport=443 dport=63181 [ASSURED] mark=0 use=1
conntrack v1.4.5 (conntrack-tools): 14 flow entries have been shown
您必须在有状态的接受规则之前测试黑名单,否则您的测试永远不会达到,因为它短路了。
代替:
颠倒他们的顺序:
您现在可以通过在第一个位置插入规则来执行此操作:
你也可以这样做而不是上面的:
conntrack
使用命令及其-D
/--delete
命令删除 conntrack 条目一旦条目被删除,连接将通过 NEW 状态恢复(因为 Netfilter 默认将 TCP 设置为恢复模式)并且应该被仍在第二位置的黑名单阻止,除非服务器首先回复将重新建立连接。因此,必须完成以下其中一项:
终止套接字(不终止进程,但显然让进程在此套接字上出错
ECONNABORTED
)最近的 Linux 内核接受
ss --kill
使用其内置的过滤逻辑强制终止套接字。示例(源和目标总是从本地系统看到的,所以倒置了。还要注意括号之间的空格):(或者只是目的地,无论如何都是关于攻击者的)。
与此不同的是
tcpkill
,它不涉及在任何地方发送自定义数据包,它是使用内核 API 直接对套接字完成的。然后,例如,如果黑名单是单个 IP 地址的列表,则可以这样做以从 conntrack 状态和套接字状态中删除所有攻击者 IP 地址。
如果将添加条目到黑名单的脚本(通常类似于fail2ban和
actionban = ipset ...
in/etc/fail2ban/action.d/iptables-ipset-proto4.conf
)更改为在每次执行conntrack
和ss
命令时也运行,那么您不必反转 INPUT 规则并将节省一些 CPU 和内存(有点在防火墙中,更多在nginx中)。在不终止套接字的情况下,服务器迟早会发出一个处于 conntrack 状态 NEW 的数据包(尽管没有 TCP SYN 标志) ,一旦攻击者回复(仍在已建立的 TCP 连接中),它将在 ESTABLISHED 状态下重新建立conntrack条目). 这是由默认情况下松散的此切换条件决定的:
这就是为什么在 OP 的案例中“恢复”了连接。为避免这种情况发生(并改为获取 INVALID 状态):
这将阻止连接在 a 之后恢复
conntrack -F
(包括远程 SSH!,所以最好像-D
上面那样使用)。启用此功能可能仅对重新启动的防火墙路由器最有用。