前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【运维】Wireguard+OpenVPN解决跨地区VPN的连接稳定性问题

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

作者头像
正汰
发布于 2024-01-16 13:23:19
发布于 2024-01-16 13:23:19
4.7K00
代码可运行
举报
运行总次数:0
代码可运行

首先我们要搞清楚一个问题,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地其他地区使用 网络结构如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A地内网<--->A地服务器<- Wireguard-UDP ->B地服务器<- OpenVPN TCP/UCP ->B地其他地区用户

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

Wireguard部分

脚本安装(建议)

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
wget https://git.io/wireguard -O wireguard-install.sh && bash wireguard-install.sh

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
\#/etc/wireguard/wg0.conf
sudo wg-quick up wg0
sudo systemctl enable wg-quick@wg0

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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有可能已经继承进内核中,就无需再安装了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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一晚上

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sudo wg-quick up wg0

OpenV**部分

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

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

脚本安装(建议)

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
vi /etc/openvpn/server/server.conf
#v/etc/openvpn/server/server.conf
push "route 10.0.0.0 255.255.0.0"
push "route <要转发的网段> <网段对应的掩码>"
#增加上述两句即可

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

手动安装

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

成果

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

碎碎念

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-11-8,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
Redis中的String类型
PS:「value最多存512MB上限」,Redis字符串类型用于场景这里举几个栗子,缓存,计数器(播放量和浏览量等),分布式锁等等。
爱敲代码的猫
2020/04/22
1.4K0
Redis入门手记
建立一个名为bar的键 127.0.0.1:6379> set bar 1 OK # 获取Redis中所有的键,keys命令需要遍历Redis中所有的键。当键的数量过多时,不建议使用。 127.0.0.1:6379> KEYS * 1) "bar" 判断键是否存在(如果键存在返回整数1,否则返回整数0) 127.0.0.1:6379> exists bar (integer) 1 127.0.0.1:6379> exists note (integer) 0 删除键 语法:del key [key ...]
暖月寒星
2020/03/10
4170
【Redis篇】String类型命令详讲以及它的使用场景
Redis的基本使用命令(GET,SET,KEYS,EXISTS,DEL,EXPIRE,TTL,TYPE)_php redis get exists-CSDN博客
用户11369558
2024/12/24
1850
【Redis篇】String类型命令详讲以及它的使用场景
redis字符串类型详解及应用场景分析
常用命令 设置值 set key value [ex seconds] [px milliseconds] [nx|xx] 选项说明: ex seconds 设置秒级过期时间 px milliseconds 设置毫秒级过期时间 nx 键不存在时才设置成功,用于添加 xx 键存在时才设置成功,用于更新 除了set选项,redis还提供了setnx,作用与nx选项相同 127.0.0.1:6379> exists hello (integer) 0 127.0.0.1:6379> set hell
章鱼喵
2018/06/27
4830
Redis字符串类型的API
看Redis相关文章上经常会说到Redis有五种基础数据类型,三种高级数据类型,三种高级数据类型中有Bitmap位图结构;
似水流年o
2022/03/02
4680
Redis | Redis 字符串相关命令
Redis 支持多种数据结构,比如 字符串、列表、集合、有序集合 和 哈希 等数据结构。本次我整理了关于 字符串 相关的命令,也就是关于 Strings 相关的命令,如下图。
码农UP2U
2020/08/26
3880
Redis | Redis 字符串相关命令
深入剖析Redis系列:Redis数据结构之字符串
字符串类型 是 Redis 最基础的数据结构。字符串类型 的值实际可以是 字符串(简单 和 复杂 的字符串,例如 JSON、XML)、数字(整数、浮点数),甚至是 二进制(图片、音频、视频),但是值最大不能超过 512MB。
用户5546570
2019/06/06
3990
深入剖析Redis系列:Redis数据结构之字符串
Redis 字符串(Strings) 复习
字符串是Redis最简单的储存类型,它存储的值可以是字符串、整数或者浮点数,对整个字符串或者字符串的其中一部分执行操作;对整数或者浮点数执行自增(increment)或者自减(decrement)操作。
陈大剩博客
2023/03/06
4070
Redis 字符串(Strings) 复习
Redis 系列(2) —— Redis 的字符串
设置 Redis 值的命令格式为 set key value [ex seconds | px milliseconds | keepttl] [nx|xx]
求和小熊猫
2021/09/10
3920
Redis 学习笔记 3.2 字符串类型
字符串类型是 Redis 中其他4种数据类型的基础,其他数据类型只是组织字符串的形式不同。例如: 列表类型是以列表的形式来组织字符串; 集合类型是以集合的形式来组织字符串。
twowinter
2020/04/17
3100
Redis字符串(STRING)介绍
上篇文章我们介绍了五种数据类型中一些通用的命令,本文我们来看看STRING数据类型独有的操作命令。 本文是Redis系列的第三篇文章,了解前面的文章有助于更好的理解本文: ---- 1.Linux上安装Redis 2.Redis中的五种数据类型简介 ---- STRING APPEND 使用APPEND命令时,如果key已经存在,则会直接在value后追加值,如果key不存在,则会先创建一个value为空字符串的key,然后再追加: 127.0.0.1:6379> APPEND k1 hello (int
江南一点雨
2018/04/03
6980
Redis中的String类型常用方法(图文例子)
一、set命令 作用:赋值操作; 格式:set key value [expiration EX seconds|PX milliseconds] [NX|XX] EX seconds -- Set the specified expire time, in seconds. PX milliseconds -- Set the specified expire time, in milliseconds. NX -- Only set the key if it does not already
掉发的小王
2022/07/11
5630
Redis 字符串介绍及相关命令
Redis 的命令及其选项时不区分大小写的(键以及值是区分大小写的),本文中采用 [] 表示可选项,命令中的关键字使用大写,参数值使用小写以便区分
三产
2021/01/12
5550
Redis学习笔记(字符串类型)
3.递增数字,当要操作的键不存在时会默认键值为0,所以第一次递增后的结果是1。当键值不是整数时Redis会提示错误
编程随想曲
2022/04/21
2460
①Redis String 字符串类型【命令汇总】
set key value [NX|XX] [GET] [EX seconds|PX milliseconds|EXAT unix-time-seconds|PXAT unix-time-milliseconds|KEEPTTL]
.29.
2023/11/17
1990
①Redis String 字符串类型【命令汇总】
Redis-03Redis数据结构--全局命令及字符串string
在了解具体的数据结构类型之前,我们有必要了解下Redis提供的操作key的全局命令、 数据结构和内部编码、 单线程命令处理机制,都有助于加深对Redis的理解。
小小工匠
2021/08/17
5630
3.Redis常用命令:String
字符串类型是Redis中最为基础的数据存储类型,它在Redis中是二进制安全的,这便意味着该类型可以接受任何格式的数据,如JPEG图像数据或Json对象描述信息等。在Redis中字符串类型的Value最多可以容纳的数据长度是512M。 1、SET key value  此命令用于在指定键设置值 redis 127.0.0.1:6379> set name tom OK redis 127.0.0.1:6379> get name "tom" 2、GET key 用于获取指定键的值 redis 127.0.0
陈树义
2018/04/13
6530
实例讲解redis字符串类型
字符串类型简介 字符串类型是Redis中最基本的数据类型,能存储任何形式的字符串 字符串类型 相关命令 命令 行为 GET key 获取值 SET key value 设置值 DEL key 删除值(
章鱼喵
2018/06/27
6490
2024 RedisAnd Mysql基础与进阶操作系列(15-1)作者——LJS[你个小黑子这都还学不会嘛?你是真爱粉嘛?真是的 ~;以后请别侮辱我家鸽鸽]
Redis数据类型之string类型及操作 1.string 类型及操作 简介
盛透侧视攻城狮
2024/10/22
1030
Redis - string类型操作
以个人信息为例操作string类型 设置操作: set:         set key value                    创建key-value名值对 setn
Aichen
2018/05/18
9040
相关推荐
Redis中的String类型
更多 >
LV.0
这个人很懒,什么都没有留下~
目录
  • 实现方案
    • 方案一
    • 方案二
  • Wireguard部分
    • 脚本安装(建议)
    • 手动安装
    • 对等端不能使用同样的密钥,不然会和我一样debug一晚上
  • OpenV**部分
    • 如果使用UDP网络较差建议更换成TCP
    • 脚本安装(建议)
    • 手动安装
  • 成果
  • 碎碎念
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档