专栏
天翼云开发者社区

wireguard基本原理和最佳实践

2023-04-06 14:19:10 1308阅读

 

Wireguard是什么

  • WireGuard 是用 C 语言编写的一个开源 XXX 协议,被视为下一代 协议。
  • 从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6 版本,这意味着拥有一个开箱即用的 WireGuard (巨大的优势)。

进一步了解

 

Wireguard的优点

  • 高性能: 更高的bandwidth ,更低ping time ,从下图可见

    与常用的openXXX对比一下,可发现原来带宽是257,而wireguard带宽则达到1011, 延时则从1541下降到0.403 

  • 更低的攻击面 ,OpenXXX,大约有 10 万行代码,而 WireGuard 只有大概 4000 行代码,代码库相当精简。
  • 配置精简,每个主机只需要 1 个公钥和 1 个私钥
  • 可以运行在主机中为容器之间提供通信,也可以运行在容器中为主机之间提供通信 (非常好)

 

wireguard工作原理

     WireGuard 以 UDP 实现,但是运行在第三层 —— IP 层。每个 Peer 都会生成一个 wg0 虚拟网卡,同时服务端会在物理网卡上监听 UDP 51820 端口。应用程序的包发送到内核以后,如果地址是虚拟专用网内部的,那么就会交给 wg0 设备,WireGuard 就会把这个 IP 包封装成 WireGuard 的包,然后在 UDP 中发送出去,对方的 Peer 的内核收到这个 UDP 包后再反向操作,解包成为 IP 包,然后交给对应的应用程序。 WireGuard 实现的虚拟网卡就像 eth0 一样,可以使用标准的 Linux 工具操作,像是 ip, ifconfig 之类的命令。所以 WireGuard 也就不用实现 QoS 之类的功能,毕竟其他工具已经实现了。这也很符合 Unix 哲学——Do one thing and do it well.

    从上面可以看出,wg是ip-over-udp,内存是ip包,而且wg是一个interface,只不过一般的interface是添加二层头,但是wg添加的是udp隧道头,接下来就通过实验来验证该说法。

 

最佳实践

   wireguard是非常优秀的XXX技术,但是只看原理还是少点什么,也是纸上来的终觉浅,还是实操一下比较好。

 

 

场景1: 容器内部(直连)

目的:  实现容器A 和 容器B 通过wireguard接口通信,通过最简单的方式了解wireguard的基本原理。

拓扑如下所示: 容器A和容器B 通过docker0网桥进行通信。通过wg1.conf 和 w2.conf 两个配置文件创建了wg1和wg2 这2个wireguard类型的接口

在容器A上ping容器B ,则容器B上抓包报文如下所示: 

基于上述报文可发现,wireguard类型的报文确实是基于udp的,外层是upd报文,内层是加密了的( encrypted_packet)报文, 更进一步,它的通信方式如是所示:

容器A和容器B ,内层是通过wg1和wg2这2个网口进行通信,被加密之后作为udp的数据(data/payload)在网络中传输。

 

场景2: 私网到公网

拓扑结构和场景1类似,只需要把endpoint替换成具体的公网IP和端口即可, 原理和场景1相同。

 

场景3:中心辐射型(hub-and-spoke)

中心辐射型, 也叫 中继模式,也即是说中继服务器与各个peer之间是可以互通,但是peer之间是放问不了的,还需要通过中继服务器,并且在中继服务器上配置iptables转发来实现peer之间的互通。

1. alice 首先和中心节点建立起wiregaurd隧道, 中心节点一般是具备公网IP的,而alice通常在私有网络中。

2. bob 首先也和中心节点建立起wiregaurd隧道, 中心节点一般是具备公网IP的,而bob通常也在私有网络中。

3. 在中心节点上配置iptable是规则,来转发 alice和bob的报文,从而建立起alice和bob的wireguard隧道。

 

   由于alice和bob的通信需要经过中心节点的中转,中心节点会成为通信的瓶颈;同时如果流量都经过中心节点的中转也会带来额外的成本,同时也会造成额外的网络延迟。所以能否不需要经过中心节点的中转,实现alice和bob的直接通信呢?这就涉及到p2p打洞的问题了。

 

场景4: 私网到私网(p2p打洞)

 

oh , 通过stun server发现,我所在的NAT出口是symmetric类型,所以我的网络环境不支持p2p打洞,要实现p2p打洞要求NAT网关是非对称类型的。

 

场景5:  在k8s中的应用

在AWS云上面已经有了具体落地 , 可把 WireGuard 看成是另一个具有加密功能的 overlay

可以看到 3 种流量:

  • 同一主机上 Pod 到 Pod 未被加密的流量(绿色线条)。
  • 不同主机上的 Pod 到 Pod 被加密的流量 (红色线条)。
  • 主机到主机的流量也会被加密 (红色线条)。

 

进一步的 ,在 kube-vip (类似 haproxy + keepalived) 也已经支持,具体可参考    https://kube-vip.io/

同时在CNI插件中也已经支持 :  flannel用来组网,calico用来加密 ,具体可参考如下实现

https://github.com/flannel-io/flannel/blob/master/pkg/backend/wireguard/wireguard.go#L50

https://docs.tigera.io/calico/latest/network-policy/encrypt-cluster-pod-traffic#install-wireguard

 

  • 0
  • 0
  • 0
0 评论
0/1000
评论(0) 发表评论
Top123

Top123

10 篇文章 3 粉丝
关注

wireguard基本原理和最佳实践

2023-04-06 14:19:10 1308阅读

 

Wireguard是什么

  • WireGuard 是用 C 语言编写的一个开源 XXX 协议,被视为下一代 协议。
  • 从 2020 年 1 月开始,它已经并入了 Linux 内核的 5.6 版本,这意味着拥有一个开箱即用的 WireGuard (巨大的优势)。

进一步了解

 

Wireguard的优点

  • 高性能: 更高的bandwidth ,更低ping time ,从下图可见

    与常用的openXXX对比一下,可发现原来带宽是257,而wireguard带宽则达到1011, 延时则从1541下降到0.403 

  • 更低的攻击面 ,OpenXXX,大约有 10 万行代码,而 WireGuard 只有大概 4000 行代码,代码库相当精简。
  • 配置精简,每个主机只需要 1 个公钥和 1 个私钥
  • 可以运行在主机中为容器之间提供通信,也可以运行在容器中为主机之间提供通信 (非常好)

 

wireguard工作原理

     WireGuard 以 UDP 实现,但是运行在第三层 —— IP 层。每个 Peer 都会生成一个 wg0 虚拟网卡,同时服务端会在物理网卡上监听 UDP 51820 端口。应用程序的包发送到内核以后,如果地址是虚拟专用网内部的,那么就会交给 wg0 设备,WireGuard 就会把这个 IP 包封装成 WireGuard 的包,然后在 UDP 中发送出去,对方的 Peer 的内核收到这个 UDP 包后再反向操作,解包成为 IP 包,然后交给对应的应用程序。 WireGuard 实现的虚拟网卡就像 eth0 一样,可以使用标准的 Linux 工具操作,像是 ip, ifconfig 之类的命令。所以 WireGuard 也就不用实现 QoS 之类的功能,毕竟其他工具已经实现了。这也很符合 Unix 哲学——Do one thing and do it well.

    从上面可以看出,wg是ip-over-udp,内存是ip包,而且wg是一个interface,只不过一般的interface是添加二层头,但是wg添加的是udp隧道头,接下来就通过实验来验证该说法。

 

最佳实践

   wireguard是非常优秀的XXX技术,但是只看原理还是少点什么,也是纸上来的终觉浅,还是实操一下比较好。

 

 

场景1: 容器内部(直连)

目的:  实现容器A 和 容器B 通过wireguard接口通信,通过最简单的方式了解wireguard的基本原理。

拓扑如下所示: 容器A和容器B 通过docker0网桥进行通信。通过wg1.conf 和 w2.conf 两个配置文件创建了wg1和wg2 这2个wireguard类型的接口

在容器A上ping容器B ,则容器B上抓包报文如下所示: 

基于上述报文可发现,wireguard类型的报文确实是基于udp的,外层是upd报文,内层是加密了的( encrypted_packet)报文, 更进一步,它的通信方式如是所示:

容器A和容器B ,内层是通过wg1和wg2这2个网口进行通信,被加密之后作为udp的数据(data/payload)在网络中传输。

 

场景2: 私网到公网

拓扑结构和场景1类似,只需要把endpoint替换成具体的公网IP和端口即可, 原理和场景1相同。

 

场景3:中心辐射型(hub-and-spoke)

中心辐射型, 也叫 中继模式,也即是说中继服务器与各个peer之间是可以互通,但是peer之间是放问不了的,还需要通过中继服务器,并且在中继服务器上配置iptables转发来实现peer之间的互通。

1. alice 首先和中心节点建立起wiregaurd隧道, 中心节点一般是具备公网IP的,而alice通常在私有网络中。

2. bob 首先也和中心节点建立起wiregaurd隧道, 中心节点一般是具备公网IP的,而bob通常也在私有网络中。

3. 在中心节点上配置iptable是规则,来转发 alice和bob的报文,从而建立起alice和bob的wireguard隧道。

 

   由于alice和bob的通信需要经过中心节点的中转,中心节点会成为通信的瓶颈;同时如果流量都经过中心节点的中转也会带来额外的成本,同时也会造成额外的网络延迟。所以能否不需要经过中心节点的中转,实现alice和bob的直接通信呢?这就涉及到p2p打洞的问题了。

 

场景4: 私网到私网(p2p打洞)

 

oh , 通过stun server发现,我所在的NAT出口是symmetric类型,所以我的网络环境不支持p2p打洞,要实现p2p打洞要求NAT网关是非对称类型的。

 

场景5:  在k8s中的应用

在AWS云上面已经有了具体落地 , 可把 WireGuard 看成是另一个具有加密功能的 overlay

可以看到 3 种流量:

  • 同一主机上 Pod 到 Pod 未被加密的流量(绿色线条)。
  • 不同主机上的 Pod 到 Pod 被加密的流量 (红色线条)。
  • 主机到主机的流量也会被加密 (红色线条)。

 

进一步的 ,在 kube-vip (类似 haproxy + keepalived) 也已经支持,具体可参考    https://kube-vip.io/

同时在CNI插件中也已经支持 :  flannel用来组网,calico用来加密 ,具体可参考如下实现

https://github.com/flannel-io/flannel/blob/master/pkg/backend/wireguard/wireguard.go#L50

https://docs.tigera.io/calico/latest/network-policy/encrypt-cluster-pod-traffic#install-wireguard

 

文章来自专栏

云原生最佳实践

10 篇文章 1 订阅
0 评论
0/1000
评论(0) 发表评论
  • 0
    点赞
  • 0
    收藏
  • 0
    评论