检查iptables用户链是否存在的最佳方法



我正在尝试以编程方式创建用户链并在iptables中删除它们。我想知道检查用户链是否存在以及它是否没有创建它的最佳方法是什么。

使用 iptables(8) 列出链,将 stdout/stderr 重定向到 /dev/null ,并检查退出代码。如果链存在,iptables将退出 true。

这个 shell 函数来自我的 iptables 前端脚本:

chain_exists()
{
    [ $# -lt 1 -o $# -gt 2 ] && { 
        echo "Usage: chain_exists <chain_name> [table]" >&2
        return 1
    }
    local chain_name="$1" ; shift
    [ $# -eq 1 ] && local table="--table $1"
    iptables $table -n --list "$chain_name" >/dev/null 2>&1
}

请注意,我使用 -n 选项,以便 iptables 不会尝试将 IP 地址解析为主机名。没有这个,你会发现这个功能会很慢。

然后,您可以使用此函数有条件地创建链:

chain_exists foo || create_chain foo ...

其中create_chain是创建链的另一个函数。你可以直接打电话给iptables,但上面的命名使发生的事情变得非常明显。

对于默认表filterIPv4

溶液:

user_chain='MY_CHAIN'
sudo iptables-save -t filter | awk -F ":| " "/^:${user_chain:?} /"' {rc = 1;}; END { exit !rc }' && printf "Skip create: ${user_chain:?}n" || 
{ sudo iptables -t filter -N "${user_chain:?}" && printf "Created: ${user_chain:?}n" ;}

首次运行时的输出:

Created: MY_CHAIN

对于后续运行:

Skip create: MY_CHAIN

或者,如果您不关心打印,那么解决方案是:

user_chain='MY_CHAIN'
sudo iptables-save -t filter | awk -F ":| " "/^:${user_chain:?} /"' {rc = 1;}; END { exit !rc }' || 
sudo iptables -t filter -N "${user_chain:?}"

请记住,上面的例子只解决了IPv4,如果你想解决IPv6,那就改变

  • iptablesip6tables
  • iptables-saveip6tables-save

在提供的解决方案中。

解释:

  • iptables-save -t filter输出IPv4 filter表的所有规则,包括链名(它们以:为前缀) - 删除用于输出规则的-t filter和所有表的链名称
  • 如果找到user_chain则退出代码0 awk -F ":| " "/^:${user_chain:?} /"' {rc = 1;}; END { exit !rc }'如果未找到,则退出 ec = 1
  • || sudo iptables -t filter -N "${user_chain:?}" 如果使用1代码退出awk则创建user_chain(未找到user_chain

我想知道检查用户链是否存在以及它是否没有创建它的最佳方法是什么。

如果您愿意重新定义您的要求以:

我想确保存在用户链。

那么快速的解决方案可能是:

sudo iptables -N MY_CHAIN || ec=$? && [ ${ec:?} -eq 1 ] || (exit ${ec:?})

上述命令可确保MY_CHAIN存在,并在以下情况下使用0代码退出:
iptables exit code - comment

  • 0 - 创建链MY_CHAIN
  • 1 - iptables 错误Chain already exists.

如果iptables退出的代码与01则上述命令使用该代码退出,例如:

  • 2 - iptables v1.8.7 (nf_tables): chain name MY_CHAIN111111111111111111111111111111111111111' too long (must be under 29 chars)
  • 4 - iptables v1.8.7 (nf_tables): Could not fetch rule set generation id: Permission denied (you must be root)

相关内容

最新更新