只有1个公网IP怎么玩?OpenVPN跨网络组网实战指南
很多朋友会遇到这样的情况:手上有三台机器——机器A、机器B、机器C,它们各自处于不同的网络中,只有机器A拥有公网IP,机器B和机器C要么在NAT后面,要么在完全隔离的内网里,外面根本访问不到。
这时候问题来了:怎么让这三台机器像在同一个局域网里一样互相通信?
用OpenVPN就能搞定!把有公网IP的机器A作为VPN服务端,机器B和机器C作为客户端拨入,三台机器就在同一个虚拟内网里了
网络拓扑图
先看一下整体架构:
核心思路很简单:机器B和机器C主动向机器A发起VPN连接,建立加密隧道后,三台机器就在同一个虚拟子网(如10.8.0.0/24)里了。
完整配置步骤
第一步:机器A(服务端)配置
在机器A上编辑OpenVPN服务端配置文件(通常是/etc/openvpn/server.conf):
1 | # 开启客户端之间互访 |
如果机器B和机器C各自还有自己的内网子网需要互通(比如机器B后面还连着一个192.168.1.0/24的局域网),还需要在服务端配置中添加路由推送:
1 | # 推送路由给所有客户端 |
第二步:生成客户端证书和配置文件
在机器A上为机器B和机器C分别生成证书。OpenVPN是通过证书中的Common Name(CN) 来识别不同客户端的
假设:
- 机器B的证书CN为
client-b - 机器C的证书CN为
client-c
第三步:机器B和机器C(客户端)连接
在机器B和机器C上,使用各自的客户端配置文件连接VPN。
连接成功后,三台机器都会被分配到10.8.0.0/24网段内的IP。假设:
- 机器A(服务端):
10.8.0.1 - 机器B(客户端):
10.8.0.6 - 机器C(客户端):
10.8.0.10
此时,机器B可以直接ping 10.8.0.10访问机器C,机器C也可以ping 10.8.0.6访问机器B
进阶:固定IP分配
如果希望每台客户端每次连接都拿到相同的IP(比如机器B固定是10.8.0.6,机器C固定是10.8.0.10),可以用client-config-dir功能。
服务端配置添加
在/etc/openvpn/server.conf中添加:
1 | client-config-dir /etc/openvpn/ccd |
创建CCD目录:
1 | mkdir -p /etc/openvpn/ccd |
为每个客户端创建配置文件
在/etc/openvpn/ccd/目录下,以客户端的CN值命名文件
1 | ifconfig-push 10.8.0.6 255.255.255.0 |
为机器C(CN为client-c)创建/etc/openvpn/ccd/client-c:
1 | ifconfig-push 10.8.0.10 255.255.255.0 |
重启服务端后,机器B每次连接都会拿到10.8.0.6,机器C每次都会拿到10.8.0.10。
如果客户端后面还有子网(Site-to-Site)
如果机器B或机器C后面还连接着其他设备或子网(比如机器B后面有一个192.168.1.0/24的局域网),想让机器A也能访问这些设备,就需要用到路由推送 + iroute。
服务端配置
在/etc/openvpn/server.conf中添加路由:
1 | # 告诉系统,访问192.168.1.0/24要走VPN |
客户端CCD配置
在机器B的CCD文件(/etc/openvpn/ccd/client-b)中添加:
1 | # 告诉OpenVPN,192.168.1.0/24这个子网在机器B后面 |
route是告诉操作系统路由表怎么走,iroute是告诉OpenVPN内部路由怎么走,两者缺一不可。
客户端B开启转发和NAT
为了让来自VPN的流量能到达机器B后面的子网,机器B还需要:
1. 开启IP转发:
1 | echo 1 > /proc/sys/net/ipv4/ip_forward |
2. 放行转发流量:
1 | iptables -I FORWARD -i tun0 -j ACCEPT |
3. 启用NAT(关键!):
如果机器B后面的子网设备不知道如何回包给VPN客户端,就需要做NAT
1 | iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 192.168.1.0/24 -j MASQUERADE |
常见问题排查
1. 客户端连不上服务端
- 确认机器A的防火墙放行了UDP/TCP 端口
- 确认客户端配置文件中的
remote地址是机器A正确的公网IP - 检查证书是否正确
2. 客户端能连上但ping不通其他客户端
- 检查服务端是否配置了
client-to-client - 检查客户端的防火墙是否放行了tun网卡的流量
3. 能ping通VPN IP但ping不通客户端后面的子网
- 检查服务端是否配置了
route和iroute - 检查客户端是否开启了IP转发(
ip_forward=1) - 检查客户端是否配置了正确的iptables NAT规则
4. 固定IP不生效
- 确认CCD文件名与客户端证书的CN值完全一致(区分大小写)
- 确认
client-config-dir路径正确 - 查看OpenVPN日志找线索:
tail -f /var/log/openvpn.log







