Docker在管理员添加规则之上插入了iptables Postrouting规则

6

我不得不在NAT表的POSTROUTING链中添加一些iptables条目,以允许Docker容器通过主机机器的不同源地址/源接口(to_source)访问互联网。

现在一切正常。

例如:

target     prot opt source               destination
SNAT       all  --  100.100.8.0/22       10.1.2.3       to:100.64.0.5

但是,当Docker服务重新启动时,它会在我的条目上方插入MASQUERADE规则,因此我上面的修复方法就被掩盖了。现在,Docker容器无法访问互联网。
例如:
target     prot opt source               destination
MASQUERADE  all  --  100.100.8.0/22       0.0.0.0/0
SNAT        all  --  100.100.8.0/22       10.1.2.3       to:100.64.0.5

有没有办法使我的POSTROUTING规则在docker重启后始终保持在链顶部?

3个回答

0

在正确的时间创建规则非常重要 - 在Docker容器启动后,因为这是Docker创建MASQUERADE规则的时候。

使用带有延迟的cron @reboot 不可靠,因为每当您重新启动容器(或启动新容器)时,规则将处于错误的顺序。

我的解决方案是一个脚本,由cron执行,它将检查我的规则的位置,并在必要时重新插入它们。

# we attach a unique comment to our rule so that we can check its position later
unique_comment="docker SNAT source IP"

insert_rules() {
    # put your rules here.  Make sure the first rule is tagged with $unique_comment so it can be identified.
    sudo iptables -t nat -I POSTROUTING 1 -s 172.17.0.0/12 -j SNAT --to-source 1.2.3.4 -m comment --comment "$unique_comment"
    sudo iptables -t nat -I POSTROUTING 2 -s 192.168.0.0/16 -j SNAT --to-source 1.2.3.4
}

delete_rules() {
    pos=$1
    # delete the first two rules from POSTROUTING.  Adjust if necessary.
    sudo iptables -t nat -D POSTROUTING $pos
    sudo iptables -t nat -D POSTROUTING $pos
}


pos=$(sudo iptables -t nat -L POSTROUTING -v -n --line-numbers|grep "$unique_comment" | awk '{ print $1 }')
if [ "$pos" == "1" ]; then
    : # correct position; nothing to do
elif [ "$pos" == "" ]; then
    # rule does not exist; add it.
    insert_rules
else
    # rule is not first; re-insert it.
    delete_rules $pos
    insert_rules
fi

现在创建一个定时任务,按照您的需要频繁地执行此脚本(例如每1或2分钟)。

0
如果您的主机上安装了Ubuntu,您可以在启动docker守护程序后使用iptables-save实用程序将iptables规则保存到文件中。然后,一旦您清除了旧规则,您可以使用iptables-restore和保存的规则文件简单地恢复原始的docker规则。
如果您不想恢复所有旧的iptables规则,您可以修改保存的规则文件,只保留您需要的规则。

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接