【运维】Wireguard+OpenVPN解决跨地区VPN的连接稳定性问题

首先我们要搞清楚一个问题,Wireguard 和 OpenVPN 的区别在哪里

  1. Wireguard 基于 UDP 协议,继承于内核中,由于加密协议简单(但安全),开销较小,性能较高

  2. OpenVPN 基于 TCP 或 UDP 协议,由 SSL/TLS 实现身份加密,没有 Wireguard 效率高,但是支持多种管理方式

在实际使用上,TCP 和 UDP 也有较大区别

  1. TCP:可以提供更可靠的连接,因为它具有确认和重传机制,能够处理丢包和错误。适用于对数据完整性和可靠性要求较高的场景。

  2. UDP:UDP 可以提供更快的速度和较低的延迟,适用于实时应用程序和视频流等对延迟敏感的情况。UDP 模式还可以避免 TCP 拥塞控制的限制,适用于高带宽环境

UDP 在实际使用上可能会被 QOS 限速,但是在长距离、高延迟的 VPN 环境中还是可以发挥不错的效果,不容易出现 TCP 经常断连的情况。

实现方案

在某个实际应用场景中,我需要将在 B 地不同地区访问位于 A 地的局域网,A 地与 B 地物理相隔较远并且网络条件较差,但是对业务实时性没有太多要求,并且 A 地存在 NAT

方案一

全部走 OpenVPN,对 A-B 两地互联的机器使用 UDP 协议,确保可以通讯
B 地对 B 地其他地区使用 TCP 协议,确保连接稳定性
方案一可以参考
Windows 上使用 OpenVPN 实现于异地访问公司内网资源(Tunnel 方式、公网服务器 frp 转发)

方案二

在 A-B 两地之间使用 Wireguard
在 B 地服务器是用 OpenVPN 供 B 地其他地区使用
网络结构如下

A地内网<--->A地服务器<- Wireguard-UDP ->B地服务器<- OpenVPN TCP/UCP ->B地其他地区用户

两方案相比,方案一更加简单,但是没有方案二稳定,并且 AB 两地如果存在高带宽情况用 OpenVPN 可能会消耗大量资源,在技术难度上方案二要设置转发,需要对两个 VPN 进行分别配置
最终选择方案二进行

Wireguard 部分

脚本安装(建议)

安装 OpenVPN(好像 Wireguard 也可以这样用,但是是端对端的,配置转发也很麻烦,所以不建议使用脚本了)

wget https://git.io/wireguard -O wireguard-install.sh && bash wireguard-install.sh

安装后我们直接导入服务端即可,然后在服务端执行

# /etc/wireguard/wg0.conf
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

如果出现有转发问题可以手动加入下方手动安装中的

PreUp = iptables -A FORWARD -i tun0 -j ACCEPT; iptables -A FORWARD -o tun0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE

手动安装

安装 wireguard 并开启内核转发,其中在 linux 内核版本大于 5.6 时(Ubuntu 为大于 5.4)wireguard-dkms 有可能已经继承进内核中,就无需再安装了

sudo apt-get update
sudo apt-get install wireguard wireguard-dkms wireguard-tools -y
sudo vi /etc/sysctl.conf
# 将net.ipv4.ip_forward=0改成net.ipv4.ip_forward=1
# 或者将net.ipv4.ip_forward=1注释去除
sysctl -w net.ipv4.ip_forward=1

生成密钥并且写入配置文件(注意最后出来的公钥)
在正常的 Peer(对等)模式下,需要定义每个对等方的配置信息,包括公钥、IP 地址、端口号等

对等端不能使用同样的密钥,不然会和我一样 debug 一晚上

(umask 077 && printf "[Interface]\nPrivateKey = " | sudo tee /etc/wireguard/wg0.conf > /dev/null)
wg genkey | sudo tee -a /etc/wireguard/wg0.conf | wg pubkey | sudo tee /etc/wireguard/publickey

将配置文件补充完整,端口默认就是 51820,记得在防火墙放行对应端口,由于我们其中一方无法访问到另一方,我们就将在公网的当作服务端,NAT 后的为客户端,服务端可以不设置 EndPoint

sudo vi /etc/wireguard/wg0.conf
# /etc/wireguard/wg0.conf
[Interface]
PrivateKey = <自动生成的不用手动填写>
Address = 10.0.0.1/24
# 客户端则为Address = 10.0.0.2/24
PreUp = iptables -A FORWARD -i tun0 -j ACCEPT; iptables -A FORWARD -o tun0 -j ACCEPT; iptables -t nat -A POSTROUTING -o wg0 -j MASQUERADE
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE
# 自动设置网卡转发
ListenPort = 51820
[Peer]
PublicKey = <填写对等端的公钥,或者cat /etc/wireguard/publickey>
AllowedIPs = 10.0.0.2/32,<要转发的网段>
# 客户端则为Address = 10.0.0.1/32,10.8.0.0/24(下方OpenVPN的网段)
Endpoint = <服务端的IP地址>:51820
# 上面的Endpoint服务端不用写
PersistentKeepalive = 25
# 保持NAT映射关系

然后启用 wireguard

sudo wg-quick up wg0

OpenVPN 部分

如果使用 UDP 网络较差建议更换成 TCP

UDP 相比于 TCP 连接稳定性相对较差,但是为什么 wireguard 要用 UDP 呢。
因为相比于连接稳定性差,我更在意能不能连上!

脚本安装(建议)

安装 OpenVPN(好像 Wireguard 也可以这样用,但是是端对端的,配置转发也很麻烦,所以不建议使用脚本了)

wget https://git.io/vpn -O openvpn-install.sh && bash openvpn-install.sh
# wget https://git.io/wireguard -O wireguard-install.sh && bash wireguard-install.sh

下载下来后直接设置,全部默认后修改配置

vi /etc/openvpn/server/server.conf
# v/etc/openvpn/server/server.conf
push "route 10.0.0.0 255.255.0.0"
push "route <要转发的网段> <网段对应的掩码>"
# 增加上述两句即可

新建的 ovpn 文件可以把 remote 修改成自己的域名,方便随时修改 dns 记录

手动安装

其实上方的 Wireguard 是我在写博客的中途手动安装的,吃了不少屎,所以我就不再吃一次了
所以我放下几个链接
OpenVPN 配置使用
OpenVPN 服务部署及使用文档
基于 WireGuard 和 OpenVPN 的混合云基础架构建设

成果

通过 OpenVPN 成功连接并且访问学校内网


碎碎念

在那天晚上,我调代码调到了 5 点多,由于转发一直不生效,我在怀疑是不是不应该使用 Wireguard+OpenVPN 这种组合方式进行,一度想转为全 OpenVPN 形式。
Tracert 也没有消息,服务端在两协议上都是能连通的,让人百思不得其解。
头疼(生理上的),吃药(赶紧睡觉)
睡到 7 点多,起来发现,挂在后台的 ping 居然 ping 通了,tracert 也能正常跟踪网关了,重启了一下也正常。
莫非是遇上了自己会修 bug 的 linux 了吗

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇