我正在尝试以编程方式创建用户链并在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
,但上面的命名使发生的事情变得非常明显。
对于默认表filter
和IPv4
溶液:
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
,那就改变
-
iptables
到ip6tables
-
iptables-save
到ip6tables-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
退出的代码与0
或1
则上述命令使用该代码退出,例如:
-
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)