很多朋友会遇到这样的情况:手上有三台机器——机器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
2
# 开启客户端之间互访
client-to-client

如果机器B和机器C各自还有自己的内网子网需要互通(比如机器B后面还连着一个192.168.1.0/24的局域网),还需要在服务端配置中添加路由推送:

1
2
3
# 推送路由给所有客户端
push "route 192.168.1.0 255.255.255.0"
push "route 192.168.2.0 255.255.255.0"

第二步:生成客户端证书和配置文件

在机器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
2
# 告诉系统,访问192.168.1.0/24要走VPN
route 192.168.1.0 255.255.255.0

客户端CCD配置

在机器B的CCD文件(/etc/openvpn/ccd/client-b)中添加:

1
2
# 告诉OpenVPN,192.168.1.0/24这个子网在机器B后面
iroute 192.168.1.0 255.255.255.0

route是告诉操作系统路由表怎么走,iroute是告诉OpenVPN内部路由怎么走,两者缺一不可。

客户端B开启转发和NAT

为了让来自VPN的流量能到达机器B后面的子网,机器B还需要:

1. 开启IP转发:

1
2
3
4
echo 1 > /proc/sys/net/ipv4/ip_forward
# 永久生效
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
sysctl -p

2. 放行转发流量:

1
2
iptables -I FORWARD -i tun0 -j ACCEPT
iptables -I FORWARD -o 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不通客户端后面的子网

  • 检查服务端是否配置了routeiroute
  • 检查客户端是否开启了IP转发(ip_forward=1
  • 检查客户端是否配置了正确的iptables NAT规则

4. 固定IP不生效

  • 确认CCD文件名与客户端证书的CN值完全一致(区分大小写)
  • 确认client-config-dir路径正确
  • 查看OpenVPN日志找线索:tail -f /var/log/openvpn.log