0%

OpenVpn服务端与客户端之间双向访问

当我们搭建OpenVpn服务端后,用OpenVpn客户端连接到服务端后,客户端可以访问服务端的vpn地址(如10.8.0.1),可以访问服务端的内网地址(如192.168.0.28)。服务端可以访问客户端的vpn地址(如10.8.0.6),但是无法访问客户端的内网地址(如192.168.1.10)。本文将在 这篇 文章的基础上,让服务端可以访问客户端的内网地址,实现不同网段的两台机器无感互通。

如下图所示:

这篇 文章中,我们已经能从vpn客户端访问vpn服务端的内网ip地址、vpn ip地址,以及内网其他机器的内网ip地址(通过在vpn服务端开启ip转发并设置iptables的SNAT转发),以及从vpn服务端访问vpn客户端的vpn ip地址(如果无法访问,请在客户端和服务端都添加防火墙规则,允许这些ip地址以及相应协议的访问,比如ping的icmp协议)。

现在我们要实现从vpn服务端访问vpn客户端的内网地址 192.168.1.10,从而打通vpn服务端和客户端的跨网段访问。

下面将用Ubuntu22.04作为vpn服务端以及vpn客户端。

一、配置vpn服务端

只需要把 /etc/openvpn/server.conf 配置文件设置为如下内容:

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 端口和协议
port 26
proto tcp
dev tun

# 证书和密钥
ca /etc/openvpn/ca.crt
cert /etc/openvpn/server/myserver.crt
key /etc/openvpn/server/myserver.key # This file should be kept secret
dh /etc/openvpn/dh.pem

# 分配的客户端IP范围
server 10.8.0.0 255.255.255.0
ifconfig-pool-persist /var/log/openvpn/ipp.txt

# 推送给客户端的配置
# 推送给客户端添加静态路由,让访问192.168.0.0/27网段都走vpn客户端虚拟网卡
push "route 192.168.0.0 255.255.255.224"

# 让客户端DNS服务器走下面两个
push "dhcp-option DNS 114.114.114.114"
push "dhcp-option DNS 8.8.8.8"

# 开启客户端配置目录
# 文件名与客户端证书和密钥名相同
# 如 /etc/openvpn/ccd/client001 为client001.key/client001.crt客户端的配置
client-config-dir /etc/openvpn/ccd

# 设置vpn服务端的静态路由,让访问客户端的192.168.1.0/24网段时走vpn服务端虚拟网卡
# 只有设置这个选项,同时设置ccd中的iroute,vpn服务端才能正确的访问到客户端的192.168.1.0/24
route 192.168.1.0 255.255.255.0
route 172.16.2.0 255.255.255.0

client-to-client
duplicate-cn
keepalive 10 120
tls-auth ta.key 0 # This file is secret
cipher AES-256-CBC
comp-lzo
max-clients 30
persist-key
persist-tun

# 日志
status /var/log/openvpn/openvpn-status.log
log /var/log/openvpn/openvpn.log
verb 3

创建ccd目录:

mkdir /etc/openvpn/ccd

在里面创建 client001 文件:

1
2
3
4
cd /etc/openvpn/ccd
vim client001
# 添加一行内容
iroute 192.168.1.0 255.255.255.0

重启openvpn服务端:

systemctl restart openvpn@server

二、配置vpn客户端

客户端配置内容为如下,我的客户端机器也是Ubuntu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# cat /etc/openvpn/client/client001.ovpn
client
dev tun
proto tcp
remote 139.226.106.214 10198
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
verb 3
ca /etc/openvpn/ca.crt
cert /etc/openvpn/client/client001.crt
key /etc/openvpn/client/client001.key
tls-auth /etc/openvpn/ta.key 1
comp-lzo
route 192.168.0.0 255.255.255.224

要注意客户端需要 ca.crt, client001.crt, client001.key, ta.key 这几个文件,ca.crt 和 ta.key 是公用的,但是不同的客户端需要创建自己的crt和key文件,如 myclient.crt, myclient.key(创建方法见 这篇 )。

然后启动vpn客户端:

openvpn --config /etc/openvpn/client/client001.ovpn

为什么选择Ubuntu作为客户端?

我测试了Windows10和MacOS来运行openvpn客户端,按照上文的方法,vpn服务端都无法ping通客户端的内网ip地址,只有Ubuntu可以。不知道什么原因,也许是另外两个系统上openvpn的版本不对,或者防火墙设置有问题,或者系统的路由表没设置好。最终只有Ubuntu没有问题。

三、测试互相ping通

在vpn客户端上ping服务端地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ping vpn服务端内网地址,ok
root@ubt22-local:~# ping -c2 192.168.0.28
PING 192.168.0.28 (192.168.0.28) 56(84) bytes of data.
64 bytes from 192.168.0.28: icmp_seq=1 ttl=64 time=24.5 ms
64 bytes from 192.168.0.28: icmp_seq=2 ttl=64 time=17.1 ms

--- 192.168.0.28 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 17.105/20.794/24.484/3.689 ms

# ping vpn服务端vpn地址,ok
root@ubt22-local:~# ping -c2 10.8.0.1
PING 10.8.0.1 (10.8.0.1) 56(84) bytes of data.
64 bytes from 10.8.0.1: icmp_seq=1 ttl=64 time=24.2 ms
64 bytes from 10.8.0.1: icmp_seq=2 ttl=64 time=17.2 ms

--- 10.8.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 17.209/20.688/24.168/3.479 ms

在vpn服务端ping客户端地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ping 客户端vpn地址,OK
root@82tf0002:~# ping -c2 10.8.0.6
PING 10.8.0.6 (10.8.0.6) 56(84) bytes of data.
64 bytes from 10.8.0.6: icmp_seq=1 ttl=64 time=18.3 ms
64 bytes from 10.8.0.6: icmp_seq=2 ttl=64 time=15.9 ms

--- 10.8.0.6 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 15.923/17.109/18.295/1.186 ms

# ping 客户端内网地址,OK
root@82tf0002:~# ping -c2 192.168.1.10
PING 192.168.1.10 (192.168.1.10) 56(84) bytes of data.
64 bytes from 192.168.1.10: icmp_seq=1 ttl=64 time=16.6 ms
64 bytes from 192.168.1.10: icmp_seq=2 ttl=64 time=125 ms

--- 192.168.1.10 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 16.605/70.666/124.727/54.061 ms

1、在vpn服务端开启ip转发和添加ip转发规则:

1
2
3
4
5
6
7
8
9
10
# 编辑文件
vim /etc/sysctl.conf
# 开启ip转发
net.ipv4.ip_forward=1

# 执行命令使修改生效
sysctl -p

# 添加转发规则
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens3 -j SNAT --to-source 192.168.0.28

然后就能在vpn客户端ping vpn服务端内网的其他机器:ping -c2 192.168.0.4

2、在vpn客户端开启ip转发和添加ip转发规则:

方法与上文【1、在vpn服务端开启ip转发和添加ip转发规则】一样,但转发规则要改成:

iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o ens33 -j SNAT --to-source 192.168.1.10

这里的ens33要改成你的vpn客户端内网ip 192.168.1.10所在的网卡设备(命令 ifconfig 或 ip addr 可以看到)。然后在vpn服务端ping vpn客户端内网其他机器,成功✅:

1
2
3
4
5
6
7
8
root@82tf0002:~# ping -c2 192.168.1.8
PING 192.168.1.8 (192.168.1.8) 56(84) bytes of data.
64 bytes from 192.168.1.8: icmp_seq=1 ttl=63 time=16.9 ms
64 bytes from 192.168.1.8: icmp_seq=2 ttl=63 time=72.4 ms

--- 192.168.1.8 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1002ms
rtt min/avg/max/mdev = 16.865/44.653/72.441/27.788 ms

完毕!