原文连接:fuckcloudnative.io/posts/wireg…html
WireGuard
是由 Jason Donenfeld
等人用 C
语言编写的一个开源 威屁恩 协议,被视为下一代 威屁恩 协议,旨在解决许多困扰 IPSec/IKEv2
、Open威屁恩
或 L2TP
等其余 威屁恩 协议的问题。它与 Tinc
和 MeshBird
等现代 威屁恩 产品有一些类似之处,即加密技术先进、配置简单。从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6
版本,这意味着大多数 Linux 发行版的用户将拥有一个开箱即用的 WireGuard。node
不管你是想破墙而出,仍是想在服务器之间组网,WireGuard 都不会让你失望,它就是组网的『乐高积木』,就像 ZFS 是构建文件系统的『乐高积木』同样。linux
WireGuard 与其余 威屁恩 协议的性能测试对比:git
能够看到 WireGuard 直接碾压其余 威屁恩 协议。再来讲说 Open威屁恩
,大约有 10 万行代码,而 WireGuard 只有大概 4000
行代码,代码库至关精简,简直就是件艺术品啊。你再看看 Open威屁恩
的性能,算了不说了。github
WireGuard 优势:windows
ARP
、DHCP
和 ICMP
,而不只仅是 TCP/HTTP。WireGuard 不能作的事:安全
固然,你可使用 WireGuard 做为底层协议来实现本身想要的功能,从而弥补上述这些缺憾。bash
本系列 WireGuard 教程分为两个部分,第一部分偏理论,第二部分偏实践。本文是第一部分,下面开始正文教程。服务器
链接到 威屁恩 并为本身注册一个 威屁恩 子网地址(如 192.0.2.3)的主机。还能够经过使用逗号分隔的 CIDR 指定子网范围,为其自身地址之外的 IP 地址选择路由。网络
一个公网可达的对等节点,能够将流量中继到 NAT
后面的其余对等节点。Bounce Server
并非特殊的节点,它和其余对等节点同样,惟一的区别是它有公网 IP,而且开启了内核级别的 IP 转发,能够将 威屁恩 的流量转发到其余客户端。
一组私有 IP,例如 192.0.2.1-255
或 192.168.1.1/24
,通常在 NAT 后面,例如办公室局域网或家庭网络。
这是一种使用掩码表示子网大小的方式,这个不用解释了。
子网的私有 IP 地址由路由器提供,经过公网没法直接访问私有子网设备,须要经过 NAT 作网络地址转换。路由器会跟踪发出的链接,并将响应转发到正确的内部 IP。
节点的公网 IP 地址:端口,例如 123.124.125.126:1234
,或者直接使用域名 some.domain.tld:1234
。若是对等节点不在同一子网中,那么节点的公开端点必须使用公网 IP 地址。
单个节点的 WireGuard 私钥,生成方法是:wg genkey > example.key
。
单个节点的 WireGuard 公钥,生成方式为:wg pubkey < example.key > example.key.pub
。
域名服务器,用于将域名解析为 威屁恩 客户端的 IP,不让 DNS请求泄漏到 威屁恩 以外。
中继服务器(Bounce Server)和普通的对等节点同样,它可以在 NAT
后面的 威屁恩 客户端之间充当中继服务器,能够将收到的任何 威屁恩 子网流量转发到正确的对等节点。事实上 WireGuard 并不关心流量是如何转发的,这个由系统内核和 iptables
规则处理。
若是全部的对等节点都是公网可达的,则不须要考虑中继服务器,只有当有对等节点位于 NAT 后面时才须要考虑。
在 WireGuard 里,客户端和服务端基本是平等的,差异只是谁主动链接谁而已。双方都会监听一个 UDP 端口,谁主动链接,谁就是客户端。主动链接的客户端须要指定对端的公网地址和端口,被动链接的服务端不须要指定其余对等节点的地址和端口。若是客户端和服务端都位于 NAT 后面,须要加一个中继服务器,客户端和服务端都指定中继服务器做为对等节点,它们的通讯流量会先进入中继服务器,而后再转发到对端。
WireGuard 是支持漫游的,也就是说,双方无论谁的地址变更了,WireGuard 在看到对方重新地址说话的时候,就会记住它的新地址(跟 mosh 同样,不过是双向的)。因此双方要是一直保持在线,而且通讯足够频繁的话(好比配置 persistent-keepalive
),两边的 IP 都不固定也不影响的。
利用 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 使用加密的 UDP 报文来封装全部的数据,UDP 不保证数据包必定能送达,也不保证按顺序到达,但隧道内的 TCP 链接能够保证数据有效交付。WireGuard 的报文格式以下图所示:
关于 WireGuard 报文的更多信息能够参考下面几篇文档:
WireGuard 声称其性能比大多数 威屁恩 协议更好,但这个事情有不少争议,好比某些加密方式支持硬件层面的加速。
WireGuard 直接在内核层面处理路由,直接使用系统内核的加密模块来加密数据,和 Linux 本来内置的密码子系统共存,原有的子系统能经过 API
使用 WireGuard 的 Zinc
密码库。WireGuard 使用 UDP 协议传输数据,在不使用的状况下默认不会传输任何 UDP 数据包,因此比常规 威屁恩 省电不少,能够像 55 同样一直挂着使用,速度相比其余 威屁恩 也是压倒性优点。
关于性能比较的更多信息能够参考下面几篇文档:
WireGuard 使用如下加密技术来保障数据的安全:
ChaCha20
进行对称加密,使用 Poly1305
进行数据验证。Curve25519
进行密钥交换。BLAKE2
做为哈希函数。HKDF
进行解密。WireGuard 的加密技术本质上是 Trevor Perrin
的 Noise
框架的实例化,它简单高效,其余的 威屁恩 都是经过一系列协商、握手和复杂的状态机来保障安全性。WireGuard 就至关于 威屁恩 协议中的 qmail
,代码量比其余 威屁恩 协议少了好几个数量级。
关于 WireGuard 加密的更多资料请参考下方连接:
WireGuard 经过为每一个对等节点提供简单的公钥和私钥来实现双向认证,每一个对等节点在设置阶段生成密钥,且只在对等节点之间共享密钥。每一个节点除了公钥和私钥,再也不须要其余证书或预共享密钥。
在更大规模的部署中,可使用 Ansible
或 Kubernetes 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离线安装包发布地址store.lameleg.com ,欢迎体验。 使用了最新的sealos v3.3.6版本。 做了主机名解析配置优化,lvscare 挂载/lib/module解决开机启动ipvs加载问题, 修复lvscare社区netlink与3.10内核不兼容问题,sealos生成百年证书等特性。更多特性 github.com/fanux/sealo… 。欢迎扫描下方的二维码加入钉钉群 ,钉钉群已经集成sealos的机器人实时能够看到sealos的动态。