语境
我一直在使用来自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>
无论如何,这是我用来设置服务器的选项:
$ 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"
这将生成类似于以下内容的服务器配置文件:
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
具体例子
我现在将举一个具体的例子。在此示例中,我将在主机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
第一条命令创建一个专用的新Docker网络,该网络定义了一个新子网。我们将OpenVPN服务器连接到该网络。
第二个使用与第一个命令中定义的子网相同的子网创建OpenVPN配置。
第三个创建OpenVPN服务器。它连接到新创建的Docker网络并使用修复IP。
第四和第五命令配置IP转发。
最后一条命令通过OpenVPN容器固定IP向VPN客户端配置添加新路由。
注意
我还没有尝试过,但是应该可以限制iptables的FORWARD规则。Docker网络的创建创建了一个新的桥接设备。该桥的名称br-<ID>
是Docker网络ID的前12个字符。可以使用获取此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
tap
,坚果tun
,到目前为止,我已经进行了超过12个小时的工作,但没有成功。