WireGuard 教程:WireGuard 的工作原理

时间:2022-09-19 10:29:45

原文链接:https://fuckcloudnative.io/posts/wireguard-docs-theory/

WireGuard 是由 Jason Donenfeld 等人用 C 语言编写的一个开源 威屁恩 协议,被视为下一代 威屁恩 协议,旨在解决许多困扰 IPSec/IKEv2Open威屁恩L2TP 等其他 威屁恩 协议的问题。它与 TincMeshBird 等现代 威屁恩 产品有一些相似之处,即加密技术先进、配置简单。从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6 版本,这意味着大多数 Linux 发行版的用户将拥有一个开箱即用的 WireGuard。

无论你是想破墙而出,还是想在服务器之间组网,WireGuard 都不会让你失望,它就是组网的『乐高积木』,就像 ZFS 是构建文件系统的『乐高积木』一样。

WireGuard 与其他 威屁恩 协议的性能测试对比:

WireGuard 教程:WireGuard 的工作原理

可以看到 WireGuard 直接碾压其他 威屁恩 协议。再来说说 Open威屁恩,大约有 10 万行代码,而 WireGuard 只有大概 4000 行代码,代码库相当精简,简直就是件艺术品啊。你再看看 Open威屁恩 的性能,算了不说了。

WireGuard 优点:

  • 配置精简,可直接使用默认值
  • 只需最少的密钥管理工作,每个主机只需要 1 个公钥和 1 个私钥。
  • 就像普通的以太网接口一样,以 Linux 内核模块的形式运行,资源占用小。
  • 能够将部分流量或所有流量通过 威屁恩 传送到局域网内的任意主机。
  • 能够在网络故障恢复之后自动重连,戳到了其他 威屁恩 的痛处。
  • 比目前主流的 威屁恩 协议,连接速度要更快,延迟更低(见上图)。
  • 使用了更先进的加密技术,具有前向加密和抗降级攻击的能力。
  • 支持任何类型的二层网络通信,例如 ARPDHCPICMP,而不仅仅是 TCP/HTTP。
  • 可以运行在主机中为容器之间提供通信,也可以运行在容器中为主机之间提供通信。

WireGuard 不能做的事:

  • 类似 gossip 协议实现网络自愈。
  • 通过信令服务器突破双重 NAT。
  • 通过*服务器自动分配和撤销密钥。
  • 发送原始的二层以太网帧。

当然,你可以使用 WireGuard 作为底层协议来实现自己想要的功能,从而弥补上述这些缺憾。

本系列 WireGuard 教程分为两个部分,第一部分偏理论,第二部分偏实践。本文是第一部分,下面开始正文教程。

1. WireGuard 术语

Peer/Node/Device

连接到 威屁恩 并为自己注册一个 威屁恩 子网地址(如 192.0.2.3)的主机。还可以通过使用逗号分隔的 CIDR 指定子网范围,为其自身地址以外的 IP 地址选择路由。

中继服务器(Bounce Server)

一个公网可达的对等节点,可以将流量中继到 NAT 后面的其他对等节点。Bounce Server 并不是特殊的节点,它和其他对等节点一样,唯一的区别是它有公网 IP,并且开启了内核级别的 IP 转发,可以将 威屁恩 的流量转发到其他客户端。

子网(Subnet)

一组私有 IP,例如 192.0.2.1-255192.168.1.1/24,一般在 NAT 后面,例如办公室局域网或家庭网络。

CIDR 表示法

这是一种使用掩码表示子网大小的方式,这个不用解释了。

NAT

子网的私有 IP 地址由路由器提供,通过公网无法直接访问私有子网设备,需要通过 NAT 做网络地址转换。路由器会跟踪发出的连接,并将响应转发到正确的内部 IP。

公开端点(Public Endpoint)

节点的公网 IP 地址:端口,例如 123.124.125.126:1234,或者直接使用域名 some.domain.tld:1234。如果对等节点不在同一子网中,那么节点的公开端点必须使用公网 IP 地址。

私钥(Private key)

单个节点的 WireGuard 私钥,生成方法是:wg genkey > example.key

公钥(Public key)

单个节点的 WireGuard 公钥,生成方式为:wg pubkey < example.key > example.key.pub

DNS

域名服务器,用于将域名解析为 威屁恩 客户端的 IP,不让 DNS请求泄漏到 威屁恩 之外。

2. WireGuard 工作原理

中继服务器工作原理

中继服务器(Bounce Server)和普通的对等节点一样,它能够在 NAT 后面的 威屁恩 客户端之间充当中继服务器,可以将收到的任何 威屁恩 子网流量转发到正确的对等节点。事实上 WireGuard 并不关心流量是如何转发的,这个由系统内核和 iptables 规则处理。

如果所有的对等节点都是公网可达的,则不需要考虑中继服务器,只有当有对等节点位于 NAT 后面时才需要考虑。

在 WireGuard 里,客户端和服务端基本是平等的,差别只是谁主动连接谁而已。双方都会监听一个 UDP 端口,谁主动连接,谁就是客户端。主动连接的客户端需要指定对端的公网地址和端口,被动连接的服务端不需要指定其他对等节点的地址和端口。如果客户端和服务端都位于 NAT 后面,需要加一个中继服务器,客户端和服务端都指定中继服务器作为对等节点,它们的通信流量会先进入中继服务器,然后再转发到对端。

WireGuard 是支持漫游的,也就是说,双方不管谁的地址变动了,WireGuard 在看到对方从新地址说话的时候,就会记住它的新地址(跟 mosh 一样,不过是双向的)。所以双方要是一直保持在线,并且通信足够频繁的话(比如配置 persistent-keepalive),两边的 IP 都不固定也不影响的。

Wireguard 如何路由流量

利用 WireGuard 可以组建非常复杂的网络拓扑,这里主要介绍几个典型的拓扑:

① 端到端直接连接

这是最简单的拓扑,所有的节点要么在同一个局域网,要么直接通过公网访问,这样 WireGuard 可以直接连接到对端,不需要中继跳转。

② 一端位于 NAT 后面,另一端直接通过公网暴露

这种情况下,最简单的方案是:通过公网暴露的一端作为服务端,另一端指定服务端的公网地址和端口,然后通过 persistent-keepalive 选项维持长连接,让 NAT 记得对应的映射关系。

③ 两端都位于 NAT 后面,通过中继服务器连接

大多数情况下,当通信双方都在 NAT 后面的时候,NAT 会做源端口随机化处理,直接连接可能比较困难。可以加一个中继服务器,通信双方都将中继服务器作为对端,然后维持长连接,流量就会通过中继服务器进行转发。

④ 两端都位于 NAT 后面,通过 UDP NAT 打洞

上面也提到了,当通信双方都在 NAT 后面的时候,直接连接不太现实,因为大多数 NAT 路由器对源端口的随机化相当严格,不可能提前为双方协调一个固定开放的端口。必须使用一个信令服务器(STUN),它会在中间沟通分配给对方哪些随机源端口。通信双方都会和公共信令服务器进行初始连接,然后它记录下随机的源端口,并将其返回给客户端。这其实就是现代 P2P 网络中 WebRTC 的工作原理。有时候,即使有了信令服务器和两端已知的源端口,也无法直接连接,因为 NAT 路由器严格规定只接受来自原始目的地址(信令服务器)的流量,会要求新开一个随机源端口来接受来自其他 IP 的流量(比如其他客户端试图使用原来的通信源端口)。运营商级别的 NAT 就是这么干的,比如蜂窝网络和一些企业网络,它们专门用这种方法来防止打洞连接。更多细节请参考下一部分的 NAT 到 NAT 连接实践的章节。

如果某一端同时连接了多个对端,当它想访问某个 IP 时,如果有具体的路由可用,则优先使用具体的路由,否则就会将流量转发到中继服务器,然后中继服务器再根据系统路由表进行转发。你可以通过测量 ping 的时间来计算每一跳的长度,并通过检查对端的输出(wg show wg0)来找到 WireGuard 对一个给定地址的路由方式。

WireGuard 报文格式

WireGuard 使用加密的 UDP 报文来封装所有的数据,UDP 不保证数据包一定能送达,也不保证按顺序到达,但隧道内的 TCP 连接可以保证数据有效交付。WireGuard 的报文格式如下图所示:

WireGuard 教程:WireGuard 的工作原理

关于 WireGuard 报文的更多信息可以参考下面几篇文档:

WireGuard 的性能

WireGuard 声称其性能比大多数 威屁恩 协议更好,但这个事情有很多争议,比如某些加密方式支持硬件层面的加速。

WireGuard 直接在内核层面处理路由,直接使用系统内核的加密模块来加密数据,和 Linux 原本内置的密码子系统共存,原有的子系统能通过 API 使用 WireGuard 的 Zinc 密码库。WireGuard 使用 UDP 协议传输数据,在不使用的情况下默认不会传输任何 UDP 数据包,所以比常规 威屁恩 省电很多,可以像 55 一样一直挂着使用,速度相比其他 威屁恩 也是压倒性优势。

WireGuard 教程:WireGuard 的工作原理

关于性能比较的更多信息可以参考下面几篇文档:

WireGuard 安全模型

WireGuard 使用以下加密技术来保障数据的安全:

  • 使用 ChaCha20 进行对称加密,使用 Poly1305 进行数据验证。
  • 利用 Curve25519 进行密钥交换。
  • 使用 BLAKE2 作为哈希函数。
  • 使用 HKDF 进行解密。

WireGuard 的加密技术本质上是 Trevor PerrinNoise 框架的实例化,它简单高效,其他的 威屁恩 都是通过一系列协商、握手和复杂的状态机来保障安全性。WireGuard 就相当于 威屁恩 协议中的 qmail,代码量比其他 威屁恩 协议少了好几个数量级。

关于 WireGuard 加密的更多资料请参考下方链接:

WireGuard 密钥管理

WireGuard 通过为每个对等节点提供简单的公钥和私钥来实现双向认证,每个对等节点在设置阶段生成密钥,且只在对等节点之间共享密钥。每个节点除了公钥和私钥,不再需要其他证书或预共享密钥。

在更大规模的部署中,可以使用 AnsibleKubernetes Secrets 等单独的服务来处理密钥的生成、分发和销毁。

下面是一些有助于密钥分发和部署的服务:

如果你不想在 wg0.conf 配置文件中直接硬编码,可以从文件或命令中读取密钥,这使得通过第三方服务管理密钥变得更加容易:

[Interface]
...
PostUp = wg set %i private-key /etc/wireguard/wg0.key <(cat /some/path/%i/privkey)

从技术上讲,多个服务端之间可以共享相同的私钥,只要客户端不使用相同的密钥同时连接到两个服务器。但有时客户端会需要同时连接多台服务器,例如,你可以使用 DNS 轮询来均衡两台服务器之间的连接,这两台服务器配置相同。大多数情况下,每个对等节点都应该使用独立的的公钥和私钥,这样每个对等节点都不能读取到对方的流量,保障了安全性。

理论部分就到这里,下篇文章将会手把手教你如何从零开始配置 WireGuard,这里会涉及到很多高级的配置方法,例如动态 IP、NAT 到 NAT、IPv6 等等。


Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12离线安装包发布地址http://store.lameleg.com ,欢迎体验。 使用了最新的sealos v3.3.6版本。 作了主机名解析配置优化,lvscare 挂载/lib/module解决开机启动ipvs加载问题, 修复lvscare社区netlink与3.10内核不兼容问题,sealos生成百年证书等特性。更多特性 https://github.com/fanux/sealos 。欢迎扫描下方的二维码加入钉钉群 ,钉钉群已经集成sealos的机器人实时可以看到sealos的动态。

WireGuard 教程:WireGuard 的工作原理

WireGuard 教程:WireGuard 的工作原理的更多相关文章

  1. 转载&colon;【Oracle 集群】RAC知识图文详细教程&lpar;三&rpar;--RAC工作原理和相关组件

    文章导航 集群概念介绍(一) ORACLE集群概念和原理(二) RAC 工作原理和相关组件(三) 缓存融合技术(四) RAC 特殊问题和实战经验(五) ORACLE 11 G版本2 RAC在LINUX ...

  2. 全网最全最细的appium自动化测试环境搭建教程以及appium工作原理

    一.前言 ​ 对于appium自动化测试环境的搭建我相信90%的自学者都是在痛苦中挣扎,在挣扎中放弃,在放弃后又重新开始,只有10%的人,人品比较好,能够很快并顺利的搭建成功.appium 自动化测试 ...

  3. WireGuard 教程:使用 DNS-SD 进行 NAT-to-NAT 穿透

    原文链接:https://fuckcloudnative.io/posts/wireguard-endpoint-discovery-nat-traversal/ WireGuard 是由 Jason ...

  4. C&num;微信开发小白成长教程一(公众平台的工作原理与调试环境部署,附视频)

    黑夜给了我黑色的眼睛,我决定录视频到天明.半年前的现在,我还在苦逼着加着班,半年后的今天我依旧苦逼着加着班.不过现在的是为自己加班,作为一个资深程序小白,一个月前我光荣的成了一个不称职的资本家,不称职 ...

  5. 【CC2530入门教程-06】CC2530的ADC工作原理与应用

    第6课  CC2530的ADC工作原理与应用 广东职业技术学院  欧浩源 一.A/D转换的基本工作原理 将时间上连续变化的模拟量转化为脉冲有无的数字量,这一过程就叫做数字化,实现数字化的关键设备是AD ...

  6. AppScan工作原理&amp&semi;操作教程

    一.AppScan的工作原理 对一个综合性的大型网站来说,可能存在成千上万的页面.以登录界面为例,至少要输入用户名和密码,即该页面存在两个字段,当提交了用户名和密码等登录信息,网站需要检查是否正确,这 ...

  7. git教程1-git工作原理与初始化仓库

    一.git工作原理 1.git是版本控制器,因此管理的是版本,每一次提交commit就是新建一个版本. 2.分支:git主分支可以存放一个阶段已经完成好的版本,而修改版本则放置在次分支上. 3.融合: ...

  8. 全网最全最细的fiddler使用教程以及工作原理

    目录:导读 一.Fiddler抓包工具简介 二.Fiddler工作原理 三.Fiddler安装 四.Fiddler界面介绍​ 五.Fiddler菜单栏介绍 六.Fiddler工具栏介绍 七.Fiddl ...

  9. 【夯实Nginx基础】Nginx工作原理和优化、漏洞

    本文地址 原文地址 本文提纲: 1.  Nginx的模块与工作原理    2.  Nginx的进程模型    3 . NginxFastCGI运行原理        3.1 什么是 FastCGI   ...

随机推荐

  1. JavaScript排序算法——归并排序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. c&num; winform 关闭窗体时同时结束线程实现思路

    Thread th = new Thread(Excute); th.IsBackground = true;这样就解决问题了. 这个属性的意思就是把线程设置为后台线程. 然后关闭进程的同时,线程也会 ...

  3. Log4j 2&period;0 使用说明

      原文地址:http://blog.csdn.net/welcome000yy/article/details/7962447 Log4j 2.0 使用说明(1) 之HelloWorld 最近刚接触 ...

  4. 【BZOJ3211】【并查集&plus;树状数组】花神游历各国

    Description   Input   Output 每次x=1时,每行一个整数,表示这次旅行的开心度 Sample Input 4 1 100 5 5 5 1 1 2 2 1 2 1 1 2 2 ...

  5. Python自动化开发-基础语法

    1.编码 计算机只能处理数字,如果要处理文本,就必须先把文本转换为数字才能处理.解决思路:数字与符号建立一对一映射,用不同数字表示不同符号. ASCII(American Standard Code ...

  6. POJ 3673 Cow Multiplication

    Cow Multiplication Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 13312   Accepted: 93 ...

  7. 手动安装sublime text3 文本编辑器是控制台

    1 本来想安装一个体积小.功能又强大的文本编辑器,百度了一圈sublime text3 的口碑不错,然后就安装试试吧, 下了以后安装成功后,看到介绍sublime text3功能强大是因为他可以安装多 ...

  8. IDEA ----Apachemaven连接私服,mavenWed工程 、以及Tomcat配置和项目的部署

    1.Apachemaven连接私服, 首相先下载Apachemaven文件(压缩包和解压后的) 打开maven下的conf文件下的settin.xml, 配置setting.xml文件 其他信息随便写 ...

  9. English trip V1 - B 14&period; There Are Flowers in My Office 我办公室里有花 Teacher&colon;Lamb Key&colon; There be&lpar;is&sol;are&rpar;

    In this lesson you will learn to describe a room or place. 这节课讲学习描述一个房间或地方 课上内容(Lesson) 1. Where do ...

  10. 『MXNet』im2rec脚本使用以及数据读取

    一.im2rec用法简介 首先看文档: usage: im2rec.py [-h] [--list] [--exts EXTS [EXTS ...]] [--chunks CHUNKS] [--tra ...