OpenVPN 组内网

需求场景:需要在本地直接访问阿里云服务器所有机器的内网 ip 和静态 DNS 解析域名。
对比了阿里的 vpn 付费网关和 Cloudflare Zero Trust、 WireGuard、ZeroTier、OpenVPN、SSLVPN 等服务和协议,各有优缺点,这里记录一下通过 OpenVPN 使本地客户端访问服务器内网。
网上可参考的文章:
使用openvpn连通多个机房内网 | 小小郭的博客
企业级OpenVPN搭建 | Maxbit
OpenVPN 服务器一键安装脚本:openvpn-install · GitHub
WireGuard VPN 服务器一键安装脚本: wireguard-install · GitHub
IPsec VPN 服务器一键安装脚本: setup-ipsec-vpn · GitHub
OpenVPN 客户端下载:OpenVPN Connect - VPN For Your Operating System | OpenVPN
由于手搓安装好了 OpenVPN 之后才看到一键安装脚本,下面内容作为手动安装参考记录。
OpenVPN 组内网
环境准备
- 服务器环境:阿里云,内网网段
172.17.211.0/24
- 服务器角色:VPN 服务器(172.17.211.81),其他内网设备(172.17.211.82,172.17.211.83)
- 需求:通过 OpenVPN 连接后,能够访问所有内网设备并使用静态域名(ddp1, ddp2, ddp3)
服务器和客户端最好都配置 hosts
文件。
- linux 在
/etc/hosts
- windows 在
C:\Windows\System32\drivers\etc\hosts
1
2
3172.17.211.81 ddp1
172.17.211.82 ddp2
172.17.211.83 ddp3
OpenVPN 服务器配置
安装 OpenVPN 和 Easy-RSA
1
2sudo apt-get update
sudo apt-get install openvpn easy-rsa设置 Easy-RSA
1
2make-cadir ~/openvpn-ca
cd ~/openvpn-ca配置 Easy-RSA 变量
编辑 vars 文件,设置所需的变量:vim ~/openvpn-ca/vars
1
2
3
4
5
6set_var EASYRSA_REQ_COUNTRY "CN"
set_var EASYRSA_REQ_PROVINCE "hn"
set_var EASYRSA_REQ_CITY "zz"
set_var EASYRSA_REQ_ORG "Awehome"
set_var EASYRSA_REQ_EMAIL "[email protected]"
set_var EASYRSA_REQ_OU "IT Department"source vars
构建 CA 和生成服务器证书及密钥:
1
2
3
4
5
6
7
8# 初始化 PKI
./easyrsa init-pki
# 生成 CA,你会被提示输入 CA 的名称,按默认值即可
./easyrsa build-ca nopass
# 生成服务器证书和密钥,按提示输入服务器的Common Name,通常使用 `server`作为请求文件名。
./easyrsa gen-req server nopass
# 签署服务器证书,提示确认请求并输入 CA 密码,按提示操作。
./easyrsa sign-req server server生成 Diffie-Hellman 参数、HMAC 签名密钥和客户端证书
1
2
3
4
5
6
7./easyrsa gen-dh
# 生成 HMAC 签名密钥
openvpn --genkey secret ta.key
./easyrsa gen-req client1 nopass
./easyrsa sign-req client client1配置 OpenVPN 服务:
vim /etc/openvpn/server.conf
我这里配置了分配给客户端的 ip 段,和阿里云局域网一个网段,目的是访问其他局域网机器。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
26port 1194 # OpenVPN 服务器端口
proto udp # 使用 UDP 协议
dev tun # 使用 TUN 设备(隧道模式)
ca ca.crt # CA 证书路径
cert server.crt # 服务器证书路径
key server.key # 服务器密钥路径
dh dh.pem # Diffie-Hellman 参数路径
# server 10.8.0.0 255.255.255.0 # OpenVPN 默认的分配给客户端的IP范围
server 172.17.211.240 255.255.255.240 # 使用一个小的与内网相同的网段上的地址池,例如172.17.211.240到172.17.211.254
ifconfig-pool-persist ipp.txt # 保持客户端IP地址池
# push "redirect-gateway def1 bypass-dhcp" # 将客户端的默认网关重定向到VPN
push "dhcp-option DNS 8.8.8.8" # 推送DNS配置给客户端
push "dhcp-option DNS 8.8.4.4" # 推送DNS配置给客户端
push "route 172.17.211.0 255.255.255.0" # 推送内网路由到客户端,确保加入vpn后能访问内网资源
keepalive 10 120 # 保持VPN连接
auth SHA256 # 使用 SHA256 进行认证
tls-auth ta.key 0 # 使用 HMAC 签名密钥
cipher AES-256-CBC # 使用 AES-256-CBC 加密
user nobody # 使用非特权用户
group nogroup # 使用非特权用户组
persist-key # 保持密钥持久化
persist-tun # 保持隧道持久化
status /var/log/openvpn/status.log # 状态日志文件路径
log-append /var/log/openvpn/openvpn.log # 日志文件路径
verb 3 # 日志详细级别
tls-server # 这行确保OpenVPN在服务器模式下运行push "redirect-gateway def1 bypass-dhcp"
如果需要只有访问特定内网段的流量才通过 VPN,其它流量仍通过本地网络访问互联网,需要注释掉这行。如果你希望将所有流量都通过 VPN,需要保留这行配置。我这里注释掉了。
分配给客户端的子网 172.17.211.240
到 172.17.211.254
网络地址:
172.17.211.240
(不可用)可用地址:
172.17.211.241
到172.17.211.254
(14 个地址)广播地址:
172.17.211.255
(不可用)
需要通过ifconfig
查看,确保服务器上面,子网没有与现有网络冲突。复制证书和密钥到 OpenVPN 目录:
这些生成的证书在~/openvpn-ca/
下,证书文件夹pki
1
sudo cp pki/ca.crt pki/private/server.key pki/issued/server.crt pki/dh.pem ta.key /etc/openvpn/
配置防火墙和路由
- 启用 IP 转发:
编辑/etc/sysctl.conf
文件1
sudo sysctl -w net.ipv4.ip_forward=1
应用配置
1 | sudo sysctl -p |
确保包含 net.ipv4.ip_forward = 1
防火墙配置:
允许防火墙通过 OpenVPN 端口1
2
3sudo ufw allow 1194/udp
sudo ufw allow OpenSSH
sudo ufw enable # 内网防火墙我觉得不要开了记得阿里云安全组开启
1194/udp
端口配置 iptables:
按需配置
方案一:VPN 客户端通过服务器访问互联网,即所有流量都通过 VPN(用这个就行,后续在客户端配置中忽略从服务器推送的路由)
最新测试,必须添加这个,不然访问不了集群其他机器。
1 | sudo iptables -t nat -A POSTROUTING -s 172.17.211.240/28 -o eth0 -j MASQUERADE |
方案二:在访问特定网段(如内网172.17.211.0/24)时走 VPN,而其他流量仍走本地网络
1 | sudo iptables -A FORWARD -s 172.17.211.240/28 -d 172.17.211.0/24 -j ACCEPT |
允许从 VPN 客户端(172.17.211.240/28)发往内网服务器(172.17.211.0/24)的流量通过防火墙。
允许内网服务器(172.17.211.0/24)发往 VPN 客户端(172.17.211.240/28)的流量通过防火墙。
-A FORWARD
:将规则添加到 FORWARD 链中,FORWARD 链处理转发的流量。-s 172.17.211.240/28
:指定源地址范围,即从 VPN 客户端分配的 IP 地址池发出的流量(172.17.211.240 到 172.17.211.254)。-d 172.17.211.0/24
:指定目标地址范围,即内网服务器所在的 IP 地址范围(172.17.211.0 到 172.17.211.255)。-j ACCEPT
:允许这些符合条件的流量通过。
删除 iptables 规则:-A
是添加,-D
是删除。
例如删除方案一的规则
1 | sudo iptables -t nat -D POSTROUTING -s 172.17.211.240/28 -o eth0 -j MASQUERADE |
添加方案二
1 | sudo iptables -A FORWARD -s 172.17.211.240/28 -d 172.17.211.0/24 -j ACCEPT |
- 检查和保存 iptables 规则:
检查 iptables1
2sudo iptables -L -v -n
sudo iptables -t nat -L -v -n
1 | Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) |
若一切正常,保存规则以在重启后保持
1 | sudo apt-get install iptables-persistent |
- 启动 OpenVPN 服务:
1
2
3
4
5
6sudo systemctl start openvpn@server
sudo systemctl enable openvpn@server
# 查看状态
sudo systemctl status openvpn@server
# 重启
sudo systemctl restart openvpn@server
客户端配置
- 创建客户端配置目录和基础配置文件
1
2mkdir -p ~/client-configs/keys
chmod -R 700 ~/client-configs
创建 base.conf
文件:
请将 YOUR_SERVER_IP
替换为服务器公网 IP 地址。
推送内网路由,只有访问内网 172.17.211.0/24
的流量会通过 VPN。route-nopull
是关键配置,不添加后续客户端会无法访问互联网。
1 | client |
- 创建 make_config.sh 脚本
在~/client-configs
目录中创建make_config.sh
脚本:
路径为~/client-configs/make_config.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Ensure the client-configs directory exists
mkdir -p /root/client-configs/files
# Generate the client configuration file
KEY_DIR=/root/client-configs/keys
OUTPUT_DIR=/root/client-configs/files
BASE_CONFIG=/root/client-configs/base.conf
cat ${BASE_CONFIG} \
<(echo -e '<ca>') \
/root/openvpn-ca/keys/ca.crt \
<(echo -e '</ca>\n<cert>') \
${KEY_DIR}/${1}.crt \
<(echo -e '</cert>\n<key>') \
${KEY_DIR}/${1}.key \
<(echo -e '</key>\n<tls-auth>') \
/root/openvpn-ca/keys/ta.key \
<(echo -e '</tls-auth>') \
> ${OUTPUT_DIR}/${1}.ovpn
1 | # 添加可执行权限 |
- 生成客户端配置文件:
1
2
3
4cd ~/client-configs
mkdir -p ~/client-configs/files
# 如果是重新生成,只需要执行这条
sudo ~/client-configs/make_config.sh client1
注意:想要修改客户端配置文件,应该在 base.conf
文件中修改,然后执行 ./make_config.sh
。手动修改 client1.ovpn
是不能用的。
测试
下载客户端:OpenVPN Connect - VPN For Your Operating System | OpenVPN
- 连接 VPN 并测试:
- 从服务器
~/client-configs/files/client1.ovpn
下载client1.ovpn
配置文件,使用 OpenVPN 客户端导入并连接。 - 验证连接是否成功,本地执行如果在 ipv4路由表中可以看到
1
route print # Windows
说明配置文件正确添加了 VPN 服务器推送的路由,通过 ping 测试内网设备:1
172.17.211.0 255.255.255.0 10.8.0.5 10.8.0.6 257
1
2ping 172.17.211.82
ping 172.17.211.83
- 从服务器
常见问题与解决
修改过配置记得重启 openvpn
1 | sudo systemctl restart openvpn@server |
查看 OpenVPN 服务的状态:
1 | sudo systemctl status [email protected] |
查看 OpenVPN 服务的日志:
1 | sudo journalctl -xeu [email protected] |
日志文件
1 | sudo cat /var/log/openvpn/openvpn.log |
- 客户端无法 ping 通内网设备:
- 确认服务器上 iptables 规则正确配置。
- 确认内核 IP 转发已启用。
- 确认防火墙允许 OpenVPN 流量。
备注
- 选择合理的 IP 地址池:在配置 VPN 时,确保使用的 IP 地址池不会与内网其他设备冲突。
- 保持配置文件的一致性:服务端和客户端的配置文件必须匹配,特别是加密和认证参数。
- 测试和验证:在每一步完成后进行测试,以便尽早发现并解决问题。
- 记录日志:查看 OpenVPN 日志有助于快速定位和解决问题。
最终所有的文件位置参考
root 目录下:
etc 目录下:
1 | root@ddp1 :/etc/openvpn# ls |
var 目录下:
1 | root@ddp1 :/var/log/openvpn# ls |
后记
更换公网和内网 ip
更换服务器了,公网 ip 和内网 ip 变了
如果内网 ip 网段变了,修改 /etc/openvpn/server.conf
VPN 分配给客户端的 IP 地址范围。我这里没变不做修改。
公网 IP 配置:
修改 /root/client-configs/base.conf
中的公网 IP,重新生成客户端配置文件
1 | cd /root/client-configs |
重启 openvpn
1 | sudo systemctl restart openvpn@server |
更换端口
国内小流量使用一般不会有问题。大流量或者协议特征容易被检测时可能会被封端口或 ip。
针对想要更默认的 1194
端口,防止被封,或已经被封端口需要更换。
修改服务器配置文件
1 | vim /etc/openvpn/server.conf |
关于新端口的建议,建议使用高位端口,运行这条命令查询端口是否已经被占用 sudo lsof -i:PORT
修改客户端配置文件模板
1 | vim /root/client-configs/base.conf |
重新生成客户端配置文件
1 | cd ~/client-configs |
修改防火墙规则
1 | sudo iptables -I INPUT -p udp --dport 新的端口号 -j ACCEPT |
重启服务
1 | sudo systemctl restart openvpn@server |
证书问题
检查证书有效期
1 | openssl x509 -in /path/to/certificate.crt -noout -dates |
例如,检查 server.crt
的有效期:
1 | openssl x509 -in /etc/openvpn/server.crt -noout -dates |
服务器证书有效期从2024年6月12日到2026年9月15日
续期或重新生成证书
生成新的服务器证书:
1 | cd ~/openvpn-ca |
将新生成的证书和密钥复制到相应的目录:
1 | sudo cp pki/ca.crt pki/private/server.key pki/issued/server.crt pki/dh.pem /etc/openvpn/ |
重新启动 OpenVPN 服务:
1 | sudo systemctl restart openvpn@server |
重新生成客户端配置文件,确保使用新的证书:
1 | cd ~/client-configs |