iptables-将入站流量转发到内部ip(docker接口)

亚历山大 C

我有一个特定于iptables的问题。我在计算机上定义了以下网络接口:

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
   valid_lft forever preferred_lft forever
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether f8:ca:b8:5c:59:b5 brd ff:ff:ff:ff:ff:ff
inet 172.16.214.45/24 brd 172.16.214.255 scope global dynamic eno1
   valid_lft 773635sec preferred_lft 773635sec
3: wlp3s0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether 80:00:0b:d7:a8:c5 brd ff:ff:ff:ff:ff:ff
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
link/ether 02:42:bf:b2:fa:86 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
   valid_lft forever preferred_lft forever

我有一个活动的docker容器正在ip 172.17.0.2上侦听(已连接到docker0接口)

我想做两件事:

  1. 将我的计算机上端口8443上的所有传入数据包转发到其端口8443上的docker容器ip 172.17.0.2
  2. 将lo接口上的所有回送数据包转发到端口8443上的docker容器ip 172.17.0.2

我已经做到了,但是在环回接口上进行测试时它不起作用

iptables -t nat -I PREROUTING -i lo -d 127.0.0.1 -p tcp --dport 8443 -j DNAT --to-destination 172.17.0.2:8443

$ curl https://localhost:8443
curl: (7) Failed to connect to localhost port 8443: Connection refused

$ curl -k https://172.17.0.2:8443
{
  "paths": [
    "/api"
  ]
}

有经验的iptables员工有任何迹象表明我在做什么错吗?

AB

有两个问题(实际上是一个未问到的第三个问题,我将通过一个简单的,即使不是最好的解决方案也要解决,以防万一,以待彻底解决):

本地启动的数据包不转发/路由

本地启动的数据包不转发(路由)。因此,这些数据包永远不会看到nat/PREROUTING链。查看Netfilter和通用网络中的数据包流,以了解内核中数据包生命周期中发生的情况。本地数据包来自“本地进程”。

因此,除了对从“外部”到达的数据包nat/PREROUTING执行“ DNATfor 规则外,它还应如下所示:

iptables -t nat -I PREROUTING -i eno1 -p tcp --dport 8443 -j DNAT --to-destination 172.17.0.2:8443

您还必须使用nat/OUTPUT链。输出时,其语法仅允许传出接口,因此将其更改为:

iptables -t nat -I OUTPUT -o lo -p tcp --dport 8443 -j DNAT --to-destination 172.17.0.2:8443

最初的数据包和流将实际重新路由到另一个接口(我怀疑上一个链接的原理图中的“重新路由检查”可能未正确放置)。

这将适用于属于主机的任何IP(即172.16.214.45和172.17.0.1),但...

禁止在lo接口外部看到IP范围127.0.0.0/8

Linux内核具有特定的设置,可以防止将127.0.0.0/8范围内的任何IP路由到该lo接口以外的任何其他位置,并且如果“尝试”使用其他接口,则丢弃任何此类数据包作为火星源,正确的是:远程系统(即使是容器)也不会接受源127.0.0.1和目标172.17.0.2的传入数据包,至少是因为它不知道在哪里答复。

因此,除了必须之外,还必须对数据包进行一个SNAT(或简单的MASQUERADE)处理DNAT,这一次是在nat/POSTROUTING遍历链中进行的(请参见前面的示意图):

iptables -t nat -I POSTROUTING -s 127.0.0.1 -d 172.17.0.2 -j MASQUERADE

这仍然是不够的:顾名思义,nat/POSTROUTING发生路由之后(实际上是在之后发生的重新路由检查DNAT),并且数据包已经作为火星源被丢弃。

对于像这样的特殊情况,可以通过按接口切换来覆盖localnet限制route_localnet

echo 1 > /proc/sys/net/ipv4/conf/docker0/route_localnet

现在,路由堆栈允许源为127.0.0.1的数据包通过,并且在通过虚拟线路连接到容器之前,根据先前的规则将其源数据更正为172.17.0.1:它可以工作。

您真的应该避免任何需要第二种情况的情况,因为这是不必要的复杂性:对于任何测试,使用属于主机而不是127.0.0.1的IP就足够了。同样,如果docker0要删除并重新创建接口,则该route_localnet设置将丢失,并且将其设置为默认值也不明智。

发夹

不会被问到,但是如果您在同一LAN中添加第二个系统(这里是一个容器),则lan到主机到相同lan重定向会出现问题(除非Docker已在网络级别处理此问题)。

nat/PREROUTING我在答案开头写规则仅处理eno1接口。我添加了此-i eno1限制是有原因的:如果没有限制,则如果172.17.0.0/16网络中的其他容器尝试连接到例如172.16.214.45:8443(或172.17.0.1:8443),则该数据包将被重定向至172.17.0.2。然后172.17.0.2将直接答复源:另一个容器,并完全绕过主机及其NAT规则。该容器将看到来自未知来源的回复数据包,并拒绝它(使用TCP RST)。因此,最好不要完全处理它,而要处理不好。Docker可能提供了直接将服务解析到另一个容器的IP /端口而不涉及主机的特定方法。

无论如何,如果有需要,有几种方法可以解决此问题,通常是权衡取舍,从简单的NAT(丢失源IP或必须将其转换为虚拟网络以进行记录)到复杂的网桥和/或路由器设置(可拦截)局域网通信。

这是一个简单的解决方案,其中的源使用SNAT编辑NETMAP到虚拟网络10.17.0.0/16。一个简单的先决条件:10.17.0.0/16可能必须在主机上路由(即使未真正使用),也可以在默认路由(可能是这种情况),特定路由或在该虚拟网络中具有IP的主机上进行路由。这个目的。具有此IP的数据包仅存在于docker0的网络内部

-i eno1PREROUTING上面规则中删除后,添加此新规则:

iptables -t nat -I POSTROUTING -s 172.17.0.0/16 -d 172.17.0.0/16 -j NETMAP --to 10.17.0.0/16

现在,从LAN到同一LAN的重定向将起作用,目标容器的日志显示源IP在10.17.0.0/16范围内。

当然,也应避免发夹情况。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

iptables将所有流量转发到接口

来自分类Dev

使用iptables根据源IP地址将流量动态转发到虚拟接口

来自分类Dev

iptables将流量转发到vpn隧道(如果打开)

来自分类Dev

使用iptables将流量转发到服务器

来自分类Dev

iptables 不会将任何流量转发到 HAProxy

来自分类Dev

将流量转发到 iptables 中的自定义密钥链

来自分类Dev

iptables端口使用两个接口将公共网络转发到专用网络

来自分类Dev

iptables / nftables:将 UDP 数据转发到多个目标

来自分类Dev

使用iptables使流量单向

来自分类Dev

iptables阻止本地流量

来自分类Dev

iptables NAT转发设置

来自分类Dev

使用iptables转发出站流量端口

来自分类Dev

配置iptables防火墙以转发流量

来自分类Dev

使用iptables将辅助网络接口流量以及端口转发重定向到tun0(OpenVPN)

来自分类Dev

IPtables不会阻止IP

来自分类Dev

配置iptables以将流量重定向到特定的IP地址

来自分类Dev

IPTables-只允许特定IP地址的Docker端口转发

来自分类Dev

iptables出站阻止拒绝入站

来自分类Dev

使用iptables将网络流量从一台计算机转发到另一台计算机

来自分类Dev

ipTables:允许传出流量的规则

来自分类Dev

使用iptables限制传出流量

来自分类Dev

iptables:透明的TCP流量代理

来自分类Dev

使用iptables限制UDP流量

来自分类Dev

iptables 不会阻止转发到主机本身的另一个 IP

来自分类Dev

使用Iptables转发TCP连接

来自分类Dev

iptables防火墙转发

来自分类Dev

SSH隧道/转发和iptables

来自分类Dev

IPtables无法转发用户错误

来自分类Dev

从LAN端口转发到OpenVPN客户端(iptables?)