我有一台邮件服务器,我想通过仅允许其使用的各个端口上的出站连接来保护它。入站规则运行良好 - 它们由 VM 主机处理。
我还没有找到太多关于此问题的信息,虽然下面的脚本几乎可以工作,但它会丢弃数据包,例如这里的端口 993:
Mar 25 16:08:11 lorina kernel: [200590.714226] IPTables-Dropped: IN= OUT=ens18 SRC=[local IP here] DST=[remote IP here] LEN=148 TOS=0x00 PREC=0x00 TTL=64 ID=37253 DF PROTO=TCP SPT=993 DPT=14826 WINDOW=243 RES=0x00 ACK PSH FIN URGP=0
这是脚本。请注意,ens19 是 LAN 接口(我希望保持打开状态),ens18 是 WAN。
iptables -A OUTPUT -o lo -p all -j ACCEPT
iptables -A OUTPUT -o ens19 -p all -j ACCEPT
iptables -A OUTPUT -p icmp -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -p tcp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp --dport 53 -j ACCEPT
iptables -A OUTPUT -p udp -m owner --uid-owner systemd-timesync -j ACCEPT
ip6tables -A OUTPUT -o lo -p all -j ACCEPT
ip6tables -A OUTPUT -p icmpv6 -j ACCEPT
ip6tables -A OUTPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
ip6tables -A OUTPUT -p tcp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p udp --dport 53 -j ACCEPT
ip6tables -A OUTPUT -p udp -m owner --uid-owner systemd-timesync -j ACCEPT
while read h; do
ip6tables -A OUTPUT -m conntrack --ctstate NEW -d $h -j ACCEPT &> /dev/null
iptables -A OUTPUT -m conntrack --ctstate NEW -d $h -j ACCEPT
done < /usr/local/etc/hosts-to-allow.list
while read p; do
ip6tables -A OUTPUT -m conntrack --ctstate NEW -p tcp --dport $p -j ACCEPT
iptables -A OUTPUT -m conntrack --ctstate NEW -p tcp --dport $p -j ACCEPT
done < /usr/local/etc/ports-to-allow.list
ip6tables -A OUTPUT -o ens18 -j LOGGING
ip6tables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A OUTPUT -o ens18 -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A OUTPUT -o ens18 -j REJECT
ip6tables -A OUTPUT -o ens18 -j REJECT
有趣的脚注
这些规则丢弃的数据包可能是正常的,我偶尔仍会看到它们。Ubuntu 支持论坛上的用户 Doug S 对此提供了解释:
您的日志行示例针对的数据包不是“NEW”。您可以从行末的 TCP 标志看出这一点。
我最好的猜测是,这是一个来自已经关闭和被遗忘的 TCP 会话的延迟数据包,否则它就会遍历 RELATED,ESTABLISHED 路径。
这种情况在 iptables 中经常发生,具体取决于您的路由器和/或数据包传输中的其他内容。为什么?因为对于 TCP 连接,Linux 倾向于使用“半双工”关闭序列,其中会话的任何一方都可以通过单个 2 向 FIN-ACK 握手(将连接置于 CLOSE_WAIT 状态)启动连接终止,而不是完整的 4 向 FIN-ACK 握手。
始终观察旗帜,以确切了解发生了什么。我认为你没事
到目前为止,在今天的 /var/log/syslog 文件中,我有 115 个以“RES=0x00 ACK FIN URGP=0”结尾的条目,其中 93 个来自我的 LAN。
答案1
我猜你的 ports-to-allow.list 包含端口 993,这就是你没有预料到引用的日志条目的原因。但请注意,你似乎正在使用端口列表进行白名单目的地端口,而您的日志显示 993 为来源被阻止数据包的端口。