如何让宿主机流量通过Docker中的OpenVPN容器转发

在使用Docker部署OpenVPN服务时,我们可能需要让宿主机的流量通过OpenVPN容器进行转发,以便访问客户端的本地网络。本文将详细介绍如何实现这一目标。

1. 场景概述

假设我们已经在Docker中成功部署了OpenVPN服务,并且客户端已经能够通过VPN连接到服务器。现在,我们希望宿主机能够通过OpenVPN容器访问客户端的本地网络中的服务(例如HTTP服务)。

2. 网络接口分析

在开始配置之前,我们需要了解宿主机上的网络接口配置。假设宿主机上有以下网络接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
br-33c729955b7a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
inet6 fe80::42:7fff:fe21:a9c4 prefixlen 64 scopeid 0x20<link>
ether 02:42:7f:21:a9:c4 txqueuelen 0 (Ethernet)
RX packets 1382 bytes 733116 (715.9 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 1066 bytes 723645 (706.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:72:96:ca:3c txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.31.5.105 netmask 255.255.240.0 broadcast 172.31.15.255
inet6 fe80::216:3eff:fe0a:25c prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:0a:02:5c txqueuelen 1000 (Ethernet)
RX packets 699637252 bytes 389466408831 (362.7 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 561942941 bytes 534275026195 (497.5 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

3. 确定OpenVPN容器的IP地址

要让宿主机的流量通过OpenVPN容器进行转发,我们需要找到OpenVPN容器的实际IP地址。可以通过以下命令查看OpenVPN容器的网络配置:

1
docker inspect openvpn

在输出中,找到NetworkSettings部分,查看容器的IP地址。例如:

1
2
3
4
5
6
7
8
9
"NetworkSettings": {
"Networks": {
"bridge": {
"IPAddress": "172.18.0.2",
"IPPrefixLen": 16,
"Gateway": "172.18.0.1"
}
}
}

在这个例子中,OpenVPN容器的IP地址是172.18.0.2

4. 配置宿主机的路由

使用OpenVPN容器的IP地址,配置宿主机的路由表,将特定的流量通过OpenVPN容器转发。例如,假设客户端的本地网络是192.168.173.0/24,可以添加以下路由:

1
ip route add 192.168.173.0/24 via 172.18.0.2 dev br-33c729955b7a

如果添加路由时出现错误 RTNETLINK answers: File exists,表示该路由已经存在。可以通过以下命令删除现有路由:

1
ip route del 192.168.173.0/24 via 172.18.0.2 dev br-33c729955b7a

然后重新添加路由:

1
ip route add 192.168.173.0/24 via 172.18.0.2 dev br-33c729955b7a

5. 开启IP转发

在宿主机上开启IP转发功能,以便允许流量通过VPN隧道:

1
echo 1 > /proc/sys/net/ipv4/ip_forward

为了使该设置在重启后仍然有效,可以编辑/etc/sysctl.conf文件,添加以下内容:

1
net.ipv4.ip_forward = 1

然后运行以下命令应用更改:

1
sysctl -p

6. 配置iptables规则

确保iptables规则允许流量通过OpenVPN容器:

1
2
iptables -A FORWARD -i br-33c729955b7a -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o br-33c729955b7a -j ACCEPT

7. 验证配置

在宿主机上,尝试访问客户端的本地网络中的服务,例如:

1
curl http://192.168.173.10

如果能够成功访问,说明配置成功。

8. 注意事项

  • 确保客户端的防火墙允许从VPN网络访问本地服务。
  • 确保OpenVPN服务端和客户端的配置正确,特别是路由和防火墙设置。
  • 如果使用的是较新的Linux发行版,可能需要使用nftables代替iptables

通过以上步骤,你可以让宿主机的流量通过Docker中的OpenVPN容器进行转发,从而访问客户端的本地网络中的服务。希望这篇文章对你有所帮助。


你可以将这篇文章发布到你的技术博客上,分享给更多需要的人。

–杂记–

Route Configurations Below

push “route 192.168.173.0 255.255.255.0”
route 192.168.173.0 255.255.255.0

push “route 172.31.5.105 255.255.255.255” # 向客户端推送本地局域网的路由,客户端访问 172.31.5.105 会走 vpn 网络
client-to-client

docker ps #列出docker名称 ,下面以openvpn为例

生成客户端证书

docker exec openvpn easyrsa build-client-full CLIENTNAME nopass

生成客户端配置

docker exec openvpn ovpn_getclient CLIENTNAME > CLIENTNAME.ovpn

路径: /www/dk_project/dk_app/dk_openvpn/conf/pki/private

拨号名称: ovpn_kainy
服务器地址/域名: .kainy.cn
服务器端口:3
4
认证方式:静态密钥(ts-auth)
线路:自动
隧道协议:UDP
隧道类型:TUN
加密算法:AES-256-GCM
Lz0压缩:开启
MTU:1500

以下内容从 CLIENTNAME.ovpn 中取

静态密钥(ts-auth):
CA正书:
客户端证书:

分享到:

评论完整模式加载中...如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理