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

wlwcrazw  于 2023-08-07  发布在  Shell
关注(0)|答案(3)|浏览(179)

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

jxct1oxe

jxct1oxe1#

使用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,但上面的命名使其非常明显。

rqmkfv5c

rqmkfv5c2#

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

uwopmtnx3#

我想知道检查用户链是否存在以及是否不创建它的最佳方法是什么。
如果您愿意重新定义您的要求:
我想确保用户链存在。
那么快速的解决方案可能是:

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)

相关问题