我开始在我的 Debian Jessie 服务器上添加一些基本的 iptables 规则。我的目标是过滤和记录网络流量(出于安全和学习目的)。忽略 ICMP 数据包,这些是我正在使用的规则:
# INPUT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
# OUTPUT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A OUTPUT -m limit -j LOG --log-prefix "UNKNOWN_OUTGOING: " --log-level 5
对于 INPUT 和 OUTPUT,该策略均设置为 ACCEPT。
现在日志经常列出传出快速恢复时间数据包,通常发送到端口 80。这里的 SRC IP 属于我的服务器,目标 IP 被部分编辑,以免泄露其他人的活动。
Aug 14 11:48:37 reynholm kernel: [81795.100496] UNKNOWN_OUTGOING: IN= OUT=ifext SRC=89.238.65.123 DST=108.162.[edited] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=3594 DPT=80 WINDOW=0 RES=0x00 RST URGP=0
我不明白是什么原因造成的,除了 SSH 和 MTA 之外没有任何应用程序在运行。是不是因为我的输入拒绝规则?但这些数据包不应该由输出处理吗状态规则?
下面是对其中一个数据包的捕获以及显然触发它的连接尝试。108.162.[edited]
在此之前我的服务器之间没有发送任何数据包。
11:48:37.860337 IP (tos 0x0, ttl 60, id 0, offset 0, flags [DF], proto TCP (6), length 44)
108.162.[edited].80 > 89.238.65.123.3594: Flags [S.], cksum 0x79bb (correct), seq 79911989, ack 235561828, win 29200, options [mss 1460], length 0
0x0000: 4500 002c 0000 4000 3c06 7342 6ca2 0000 E..,..@.<.sBl...
0x0010: 59ee 417b 0050 0e0a 04c3 5c35 0e0a 6364 Y.A{.P....\5..cd
0x0020: 6012 7210 79bb 0000 0204 05b4 0000 `.r.y.........
11:48:37.860408 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 40)
89.238.65.123.3594 > 108.162.[edited].80: Flags [R], cksum 0x648e (correct), seq 235561828, win 0, length 0
0x0000: 4500 0028 0000 4000 4006 6f46 59ee 417b E..(..@[email protected]{
0x0010: 6ca2 0000 0e0a 0050 0e0a 6364 0000 0000 l......P..cd....
0x0020: 5004 0000 648e 0000 P...d...
答案1
TCP RST 数据包的创建来自您的规则
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
默认策略(在您的情况下为 ACCEPT)仅适用于与链中任何规则都不匹配的数据包。如果数据包与上述规则与 REJECT 目标匹配,则它将不受默认策略的约束,并且将被 REJECT(并生成 TCP RST)而不是 ACCEPT。
此 TCP RST 与您的规则不匹配:
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
因为它与另一个已建立的连接无关,并且它不是 ESTABLISHED 连接的一部分。它将继续执行您的规则和比赛
-A OUTPUT -m limit -j LOG --log-prefix "UNKNOWN_OUTGOING: " --log-level 5
并最终出现在您的日志中。如果您不想记录这些 RST 数据包,请调整此规则以不匹配它们,或者插入较早的规则以匹配 RST 数据包,并在它们到达此处之前对它们进行一些处理。
我注意到的其他事情是,您记录的第一个数据包是来自远程网络服务器的 SYN/ACK 数据包,它看起来像是远程网络服务器对您之前发送以开始连接到服务器的 SYN 数据包的响应数据包。端口 80 上的远程主机。如果您没有发送初始 SYN,我认为连接不会匹配“ESTABLISHED”,但如果您确实发送了 SYN,那么我认为连接应该匹配“ESTABLISHED”。这可能会扰乱您的 RST 最终匹配的规则。
答案2
扩展 @casey 的精彩答案:造成这种情况的原因是来自远程的包设置了 SYN 和 ACK 标志。这对于第一个包是无效的。 iptables 不认为重置数据包与初始数据包相关,因为它显然没有意义。
可以使用以下工具重现效果hping3
:使用 发送 SYN/ACK 数据包hping3 -c 1 --syn --ack 89.238.65.123。服务器对此数据包的响应不会设置 ACK 标志,并且不会与状态规则(即与发送 ping 无关)。结果会触发日志条目。
如果在初始请求中未设置 ACK 标志,则不会发生此类影响。
我通过过滤和丢弃传入的无效 tcp 数据包来摆脱日志消息。
-I INPUT 3 -m state --state INVALID -j DROP
答案3
这看起来可能是启动端口扫描的一部分从远程主机上的 tcp/80。远程主机探测您的服务 tcp/3594 并且您的系统正确地说“不。现在离开(RST)”。不幸的是,对于互联网连接系统来说这是相当正常的事情。
您可能想要安装fail2ban
,它可以非常有效地阻止主机尝试以不可接受的方式连接到您的系统。不过,有一个警告:在包含的示例之外对其进行配置并非易事。