2023-04-06 14:19:10 1380阅读
Wireguard是什么
进一步了解
Wireguard的优点
与常用的openXXX对比一下,可发现原来带宽是257,而wireguard带宽则达到1011, 延时则从1541下降到0.403
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 种流量:
进一步的 ,在 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
2023-04-06 14:19:10 1380阅读
Wireguard是什么
进一步了解
Wireguard的优点
与常用的openXXX对比一下,可发现原来带宽是257,而wireguard带宽则达到1011, 延时则从1541下降到0.403
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 种流量:
进一步的 ,在 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