Docker 公开的端口可从主机使用,但不能从 iptables 受限容器中的其他机器使用

Docker 公开的端口可从主机使用,但不能从 iptables 受限容器中的其他机器使用

我有一个带有 VPN 的自定义容器,容器内有以下 iptables 规则:

# Flush all existing rules and chains
iptables -F
iptables -X

# Set default policies to DROP
iptables -P INPUT DROP
iptables -P OUTPUT DROP
iptables -P FORWARD DROP

# Allow loopback traffic (localhost)
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT

# allow vpn to be connected
iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

while IFS=' ' read -r host port; do
    iptables -A OUTPUT -o eth0 -p udp --dport $port -d $host -j ACCEPT
done < "/tmp/entries"

iptables -A OUTPUT -o ${VPN_DEVICE} -j ACCEPT

# allow vnc to be connected
iptables -A INPUT -i eth0 -p tcp --dport 5800 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 5800 -m state --state ESTABLISHED -j ACCEPT

# allow deluge to be connected
iptables -A INPUT -i eth0 -p tcp --dport 8112 -m state --state NEW,ESTABLISHED -j ACCEPT
iptables -A OUTPUT -o eth0 -p tcp --sport 8112 -m state --state ESTABLISHED -j ACCEPT

# allow deluge to access external world
iptables -A INPUT -i ${VPN_DEVICE}  -p tcp --dport 6881:6891 -j ACCEPT
iptables -A OUTPUT -o ${VPN_DEVICE}  -p tcp --dport 6881:6891 -j ACCEPT
iptables -A INPUT -i ${VPN_DEVICE}  -p udp --dport 6881:6891 -j ACCEPT
iptables -A OUTPUT -o ${VPN_DEVICE}  -p udp --dport 6881:6891 -j ACCEPT

整个想法是默认丢弃所有进/出流量;仅允许 eth0 的 vpn 服务器输出流量;允许 eth0 公开端口 5800 和 8112 以访问我的服务;通过 VPN 设备将 torrent 客户端公开到外部世界。

此外,我还有以下撰写文件来启动上述带有 iptables 规则的容器:

version: "2.1"
services:
  vpn:
    build: ./
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
    volumes:
      - ./volumes/vpn-config:/vpn-config
      - ./volumes/deluge-config:/deluge-config
      - ./volumes/downloads:/downloads
      - ./volumes/firefox-profile:/config
      - ./volumes/downloads:/config/downloads
    ports:
      - 40001:5800
      - 40002:8112
    restart: unless-stopped

这里的主要问题 - 端口 40001 和 40002 在主机上运行良好,但在来自同一网络的其他机器上无法运行。而其他容器的暴露端口则正常(使用 nginx hello-world 容器进行测试)。

这里有什么可疑的地方我可以更改或注意以确保端口 40001 和 40002 可以从其他机器访问吗?

答案1

好的,原始问题与 iptables 无关,一切都与路由有关。假设我有192.168.31.0/24主机外部网络。

默认情况下,docker 添加这样的路由:

default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link  src 172.17.0.2

然后 Openvpn 添加类似这样的内容,通过 vpn 的默认路由:

0.0.0.0/1 via 1.2.3.4 dev tun0 # this comes from openvpn
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 scope link  src 172.17.0.2

在第一种情况下,所有数据包都192.168.31.0/24将发往172.17.0.1主机,主机会将其重新路由到适当的位置。

VPN 连接后,所有这些流量都将转到1.2.3.4。它仍然适用于主机,因为172.17.0.0/16存在来自 docker 的路由。

不幸的是,我不知道优雅的路由/iptables 解决方案可以自动解决此问题。

简单的解决方案是启动代理服务器(通过附加的docker-compose服务; http或TCP,或任何合适的服务)以代理暴露给外界的端口。

相关内容