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

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

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

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

Aug 23 06:37:14 server systemd[1]: Started ifup for ens16.
Aug 23 06:37:14 server systemd[1]: [email protected]: Main process exited, code=exited, status=1/FAILURE

Aug 23 06:37:14 server sh[281]: iptables-restore: line 10 failed
Aug 23 06:37:14 server systemd[1]: [email protected]: 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

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

#!/bin/sh
/sbin/iptables-restore < /etc/iptables.up.rules

/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

这种间歇性的情况可能出了什么问题?我该如何确保它不再发生?

答案1

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

我习惯于管理 CentOS 和 Red Hat 系统。曾经有一次,其中一台服务器由于同时启动而无法iptables在启动时初始化服务。该特定错误记录在此处:systemdip6tableshttps://bugzilla.redhat.com/show_bug.cgi?id=1477413

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

#!/bin/sh
/usr/bin/flock /run/.iptables-restore /sbin/iptables-restore < /etc/iptables.up.rules

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

#!/bin/sh
if [ "${IFACE}" == ens16 ]; then
    /sbin/iptables-restore < /etc/iptables.up.rules
fi

此外,如果您只想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

相关内容