iptables-restore 有时会在重启时失败

Sam*_*ull 6 linux iptables systemd

今天和昨天,我的服务器自动重启,在启动过程中无法启动网络设备。如果我再次重新启动机器,它就会正常启动,在过去的 2 个月里我也没有遇到任何问题。

我能找到的与此相关的唯一错误日志是:

Aug 23 06:37:14 server systemd[1]: Started ifup for ens16.
Aug 23 06:37:14 server systemd[1]: ifup@ens16.service: Main process exited, code=exited, status=1/FAILURE
Run Code Online (Sandbox Code Playgroud)

Aug 23 06:37:14 server sh[281]: iptables-restore: line 10 failed
Aug 23 06:37:14 server systemd[1]: ifup@ens16.service: Main process exited, code=exited, status=1/FAILURE
Aug 23 06:37:14 server sh[281]: run-parts: /etc/network/if-pre-up.d/iptables exited with return code 1
Aug 23 06:37:14 server sh[281]: ifup: failed to bring up ens16
Run Code Online (Sandbox Code Playgroud)

/etc/network/if-pre-up.d/iptables 包含:

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.up.rules
Run Code Online (Sandbox Code Playgroud)

/etc/iptables.up.rules 包含:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [896:90530]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp --dport 80 -j ACCEPT
-A INPUT -p tcp --dport 443 -j ACCEPT
-A INPUT -j REJECT --reject-with icmp-port-unreachable
COMMIT
Run Code Online (Sandbox Code Playgroud)

这种间歇性的方式可能会出现什么问题,我如何确保它不会再次发生?

And*_*mes 4

/etc/network/if-pre-up.d/iptables我仍然怀疑在整个启动过程中同时运行了两个执行。由于systemd同时启动事物的正常行为,除非建议不要这样做,我相信启动过程会触发lo接口的一个脚本进程和接口的另一个ens16脚本进程。这将导致 的并发执行iptables-restore,这可能会导致诸如 之类的错误iptables-restore: line 10 failed。但我无法提供证据。

我习惯管理CentOS和Red Hat系统。曾几何时,其中一台服务器无法iptables在启动时初始化服务,因为systemd它是ip6tables同时启动的。该特定错误记录在此处:https ://bugzilla.redhat.com/show_bug.cgi?id=1477413

我建议您在脚本中处理并发性,例如使用flock

#!/bin/sh
/usr/bin/flock /run/.iptables-restore /sbin/iptables-restore < /etc/iptables.up.rules
Run Code Online (Sandbox Code Playgroud)

${IFACE}或者,您可以在恢复规则之前检查变量的实际值iptables(参考:man 5interfaces):

#!/bin/sh
if [ "${IFACE}" == ens16 ]; then
    /sbin/iptables-restore < /etc/iptables.up.rules
fi
Run Code Online (Sandbox Code Playgroud)

此外,如果您只想iptables在启动时加载规则,我建议您改用iptables-persistent

# apt-get install iptables-persistent netfilter-persistent
# mv -v /etc/iptables.up.rules /etc/iptables/rules.v4
# systemctl enable netfilter-persistent.service
# rm -v /etc/network/if-pre-up.d/iptables
Run Code Online (Sandbox Code Playgroud)