我有以下设置:
如何允许 docker bridge 网络上的 docker 容器与 tun0 网络上的 openvpn 客户端通信?
我希望能够以透明的方式在 docker1(10.10.0.3)和连接到 vpn(172.19.0.x 范围)的客户端之间进行基于 tcp 的通信。
我需要在 docker (networking / iptables / ...) 端和主机 (iptables ) 上设置什么?
我一直在使用 Kyle Manna ( https://github.com/kylemanna/docker-openvpn ) 提供的非常好的 Docker 容器。我正在使用所谓的“偏执”文档来设置我的 OpenVPN 服务器,但在我看来,这应该是标准方式而不是偏执方式。
为了允许选定的 Docker 容器和 VPN 客户端之间的双向连接,您需要创建一个 Docker 网络,您将在该网络上附加应该允许 VPN 客户端访问的容器。VPN 服务器将成为这些容器之一。
VPN 服务器应具有client-to-client
, topology subnet
, dev tun0
(或其他 tun 设备)并已push "route <docker net IP> <docker net mask>"
配置。
VPN 服务器的主机应配置为支持将 IP 数据包从一个子网转发到另一个子网。这意味着将 sysctl ip_forward 设置为 1(如果您安装了 Docker,应该是这种情况),允许来自 tun 设备的数据包通过 iptables FORWARD 链并设置正确的路由。这可以用以下命令总结:
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via <IP address of OpenVPN server container>
Run Code Online (Sandbox Code Playgroud)
无论如何,这里是我用来设置服务器的选项:
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://<FQDN> -N -d -c -p "route <docker net IP> <docker net range>" -e "topology subnet"
Run Code Online (Sandbox Code Playgroud)
这应该会生成一个类似于以下内容的服务器配置文件:
server 192.168.255.0 255.255.255.0
verb 3
key /etc/openvpn/pki/private/vpn.example.com.key
ca /etc/openvpn/pki/ca.crt
cert /etc/openvpn/pki/issued/vpn.example.com.crt
dh /etc/openvpn/pki/dh.pem
tls-auth /etc/openvpn/pki/ta.key
key-direction 0
keepalive 10 60
persist-key
persist-tun
proto udp
# Rely on Docker to do port mapping, internally always 1194
port 1194
dev tun0
status /tmp/openvpn-status.log
user nobody
group nogroup
client-to-client
### Push Configurations Below
push "dhcp-option DNS 8.8.8.8"
push "route 172.20.20.0 255.255.255.0"
### Extra Configurations Below
topology subnet
Run Code Online (Sandbox Code Playgroud)
我现在举一个具体的例子。在这个例子中,我将在主机 vpn.example.com 上的 Docker 中运行上面提到的 OpenVPN 服务器。此容器附加到 Docker 网络 docker-net-vpn。下面是命令(在这个例子中,我直接在服务器上生成服务器配置,我跳过了 CA 生成,请按照上面提到的项目的偏执文档代替):
$ docker network create --attachable=true --driver=bridge --subnet=172.20.20.0/24 --gateway=172.20.20.1 docker-net-vpn
$ docker run --rm --net=none -it -v $PWD/files/openvpn:/etc/openvpn kylemanna/openvpn:2.4 ovpn_genconfig -u udp://vpn.example.com -N -d -c -p "route 172.20.20.0 255.255.255.0" -e "topology subnet"
$ docker run --detach --name openvpn -v $PWD/files/openvpn:/etc/openvpn --net=docker-net-vpn --ip=172.20.20.2 -p 1194:1194/udp --cap-add=NET_ADMIN kylemanna/openvpn:2.4
$ sudo sysctl -w net.ipv4.ip_forward=1
$ sudo iptables -A FORWARD -i tun+ -j ACCEPT
$ sudo ip route add 192.168.255.0/24 via 172.20.20.2
Run Code Online (Sandbox Code Playgroud)
第一个命令创建一个专用的新 Docker 网络,它定义了一个新的子网。我们将把 OpenVPN 服务器连接到这个网络。
第二个使用与第一个命令中定义的相同子网创建 OpenVPN 配置。
第三个创建 OpenVPN 服务器。它附加到新创建的 Docker 网络并使用固定 IP。
第四条和第五条命令配置IP转发。
最后一条命令通过 OpenVPN 容器固定 IP 添加一条通往 VPN 客户端配置的新路由。
笔记
我没试过,但是应该可以限制iptables的FORWARD规则。Docker 网络创建创建了一个新的桥接设备。该网桥以br-<ID>
Docker 网络 ID 的前 12 个字符的 ID命名。此 ID 可通过 获得docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12
。因此,以下命令可能更具限制性(因此在安全方面更好),但仍应允许路由我们的流量:
$ NET_VPN_BRIDGE="br-$(docker network inspect -f '{{.Id}}' docker-net-vpn | cut -b-12)"
$ sudo iptables -A FORWARD -i tun+ -o ${NET_VPN_BRIDGE} -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
26524 次 |
最近记录: |