WireGuard
一、WireGuard 介绍
我想先把WireGuard用法细节写清楚,但是也没有找到一个系统的教程,以下写的都是我拼凑来的知识,可能并不准确。
WireGuard 就是VPN(virtual private network),据说它比传统VPN高效、易用、全平台。有一点很重要,WireGuard 是点对点网络(peer-to-peer),又称对等网络。WireGuard 组成的网络中,每台设备的地位的平等的,每一台运行了WireGuard 的设备叫做一个peer,我这个peer想去连接另一个peer,另一个peer称为对端。
WireGuard能用来干什么?抛弃传统用法不谈,网上的up主会教你用它来实现那种功能,我感觉这完全不合适,且不说性能和当下实现那种功能的协议相比有多少差距,用那种功能你需要手动维护需要经过隧道的各个网站的ip,费力不讨好。我感觉对我们家用网络来说,很实用的一个功能就是异地组局域网,当然你需要一个有公网的设备。不同于frp那种端口转发,虚拟局域网有些优势,比如有些服务不只用一个端口(比如ftp),有些服务不知道工作在那个端口(如parsec),这些情况用frp都没办法实现。
和普通网络传输差不多,配置中有四点需要明确:
- 我想去加入WireGuard 这个小圈子,我本身需要一个地址
- 我想连接另一个peer,我需要知道对端的地址
- 我想和对端建立连接,我需要通过对端的认证,即对方让我连接我才能连接。对端愿意和我连接会给我一把钥匙;同样,别人想和我连接,也需要给他的钥匙。
- 我需要制定一个规则,哪些请求需要通过WireGuard隧道,哪些请求不需要
⚠️还有一个事情比较迷惑,我是一台服务器提供一些服务,对端是一台手机,只会出现对端连接我的情况,而我不会主动去连接对端,那么我需要知道对端的信息吗?不需要!

有了这些知识,我们可以组一个简单的VPN,如上图,此时有一个问题:主机A一边连着主机B一边连着主机C,但是B和C不直接相连,B和C能进行通信吗?**可以!**需要注意的是隧道不是一直开着的,默认好像几秒就关闭了。假如A是唯一有公网的设备,也就是需要B和C主动去连接A才能建立连接,B想通过A连接C的话,要保证C和A之间的隧道还开着。如果A到C的隧道关闭了,因为A不能主动连接A,所以不能直接由B接通C。所以,在NAT后面的设备想保持在线,应该设置PersistentKeepAlive = 25,表示每25秒向对端发送一次请求。
注意事项
- 对端配置的两个必选项:对端公钥、需要经过隧道传输的请求。虽说是对等网络,但是如果A主机提供服务,B主机只是接受服务,那么A主机可以不知道B主机的地址和ip,只需要B主机知道A主机然后主动请求A主机。所以对于接受服务的peer,还有一个必选项:对端(提供服务端)的地址和端口。
- 预共享密钥所有的peer都相同。可以不设置,但是如果一个设置了,对端也一定要设置为同样的否则不能连接。
- 虚拟网段随便写,但是尽量控制在局域网保留的地址范围内,比如10.0.0.0/8、172.16.0.0/12或192.168.0.0/16。
- peer中
允许的ip意思是:1.当出向包的目的 IP 为 AllowedIPs 定义的网段时,将该包从 VPN 隧道发送出去
2.当从 VPN 隧道进来的包的源 IP 不匹配 AllowedIPs 定义的网段时,直接将包丢弃
https://devld.me/2020/07/27/wireguard-setup/ - 允许的ip中一定要添加上wg网段吗?**不用!**比如我的路由器内网网段是10.1.1.0/24,wg网段设置的是10.0.0.0/24。我用手机的wg地址10.0.0.2/32,手机配置的对端允许的ip只填10.1.1.0/24不填10.0.0.0/24可以吗?**可以!**比如我路由器下有一个nas(10.1.1.5/32),我完全可以直接访问10.1.1.5/32。
- 服务端的
允许的ip一定要包含整个wg网段,比如我的10.0.0.5:2280提供一个服务,10.0.0.8/32通过10.0.0.1/32访问这个服务,那么在10.0.0.5中填写的对端应该包含所有会访问这个服务wg地址,如果peer允许的ip为10.0.0.1/32那么,10.0.0.8将无法访问这个服务,必须是10.0.0.1/32,10.0.0.8/32或者10.0.0.1/24 0.0.0.0/0和::/0分别表示ipv4和ipv6下所有请求都代理
二、各平台配置WireGuard
2.1 OpenWRT
注意事项:
- 对端中路由允许的IP一定要打开,这应该就是字面意思,如果不路由,来的请求不知道往哪里去,要发送的请求也不知道往哪里发。
- 每次修改之后需要保存应用且重启接口
- 如果是OpenWRT下的内网设备要访问WG网段的其他设备,只是OpenWRT配置成了一个节点(请求需要经过OpenWRT转发,内网设备不在wireguard允许的路由之内)。那么在防火墙那里,WG端口到wan的ip动态伪装一定要打开,这个功能应该就是MASQUERADE,如果不伪装,请求的原地址是内网的地址,会被被请求的wireguard直接丢弃。(已经验证过)
- 如果外网(通过wireguard,10.0.0.6)想通过openwrt(10.0.0.5:88)访问内网的nas(10.1.1.2:80)怎么设置端口转发呢?注意不是将wan口的88端口转发到lan的10.1.1.2:80,而是将内网区域(因为wg在内网区域)的88端口转发到10.1.1.2:80。
2.1 Ubuntu 20.04
-
安装
sudo apt update sudo apt install wireguard此时会生成一个空文件夹/etc/wireguard
-
生成配置文件
新建/etc/wireguard/wg0.conf,填入如下内容[Interface] PrivateKey = kNKyXB7bnTpix4JaDwu4i5cxxxxxxxxxxWZTqDA65Fo= ListenPort = 5000 Address = 10.0.0.7/32 [Peer] PublicKey = 4v5R/MmTOtiGOCQdD5tkzLGsc0VhY+Z1NZlTK9HQAhc= # PresharedKey not used AllowedIPs = 10.0.0.0/24 Endpoint = xxx.xxx:7150 # PersistentKeepAlive not defined -
启用wireguard接口
sudo wg-quick up wg0 sudo ufw allow 5000/udp -
查看wg0的状态。
sudo wg show wg0 ip a show wg0注意,只是启用虚拟接口是不会有图中最下面两行(latest handshake和transfer)的,需要有流量流经接口才会出现,比如你可以ping一下对端(如果对端可ping)。

-
开机自启动
sudo systemctl enable wg-quick@wg0 -
请求转发
如果linux端只是做wireguard内网的一个普通节点,以上的配置就足够了。但是,如果你想做一个连接外网的节点,比如所有的peer(比如手机)可以通过这个peer(云服务器)访问互联网,那么还需要额外的操作。
默认情况下,当Linux服务器接收到一个手机访问百度的请求,是会被直接丢弃的,因为请求的目的地址并不是本服务器。所以,手机想通过Linux服务器访问百度,需要通过Linux服务器的转发。
首先需要打开Linux内核的ipv4数据包转发功能,修改/etc/sysctl.conf,配置参数net.ipv4.ip_forward=1,或者使用命令sudo sysctl -w net.ipv4.ip_forward=1。这相当于一个总开关,sysctl -p使配置生效。
接下来,按照下图,MANGLE表视为透明的话,需要配置filter表的FORWARD链和nat的POSTROUTING链,根据https://www.myfreax.com/how-to-set-up-wireguard-vpn-on-ubuntu-20-04/提供的两个参数配置,在wireguard启动和停止的钩子上配置这两条转发规则。PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE
iptables -A FORWARD -i %i -j ACCEPT是将就是做filter表的FORWARD,不指定表名的时候默认是filter,%i是wireguard的占位符,执行的时候会替换为当前正在配置的实际的WireGuard接口名称;iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE是做nat表的POSTROUTING链,ens3表示能访问互联网的网络接口,一般是eth0,可以通过命令ip -o -4 route show to default | awk '{print $5}'获取,MASQUERADE是SNAT的一种情况表示转发时将请求的源地址换成本网卡的地址。**但是!**当防火墙ufw没开的时候,不需要第一个命令,只需要第二个命令即可。

2.3 Windows和Android以及其他可视化平台
没啥好说的,填入配置文件,启动代理即可。
注意:
- Windows默认禁止ping,想要ping的话需要禁用防火墙或者在
防火墙-入站规则-文件和打印机共享(回显请求)启用允许。 - 使用远程桌面的话记得在设置中启用远程桌面。 如果密码为空需要设置本地组策略:计算机配置 > Windows 设置 > 安全设置 > 本地策略 > 安全选项 > 账户: 使用空密码的本地账户只允许进行控制台登录 > 禁用。
三、实战一:FRP加WireGuard

我会实现上图所示的wireguard网络,首先我有一台OpenWRT设备放在家里,内网网段是10.1.1.0/24,OpwnWRT下面有UnRAID(10.1.1.2),jellyfin(10.1.1.2:8096)等。给OpenWRT分配的wireguard地址是10.0.0.1/32,wireguard所有监听端口设置为5000;工位有一台电脑,分配的wireguard地址是10.0.0.2/32;随身一部手机,分配的wireguard地址是10.0.0.3/32。这三台设备都在大内网中,没有办法互相访问。可巧我还有一台腾讯云的服务器,公网地址192.144.214.11(当然是我乱写的ip),但是我不想给它也装wireguard做对端,因为上面我已经跑了一个frp server,我将openwrt的wireguard监听端口5000映射到服务器的7150,这样就相当于每次我访问192.144.214.11:7150,实际访问的是openwrt的5000端口。使用OpenWRT系统来统一路由也很自然。
这样我相当于有三个peer,家庭网络中的OpenWRT(peer1),手机( peer2) ,工位电脑(peer3)。虽说各个peer地位相等,但是手机和工位电脑不能相互访问,所以OpenWRT设备还是充当了一个枢纽。我要实现的功能:
- 在家庭网中和手机在移动网络中随时访问工位电脑,主要是使用它的远程桌面。
- 在手机和工位电脑可以访问家庭网络中的NAS和影音服务器。
四、实战二、纯WireGuard
服务端linux需要开启ipv4转发,否则服务器会丢弃所有目的地址不为本机的请求。使用sysctl net.ipv4.ip_forward查看转发状态,如果结果为0则为不转发,需要设置为1:
# 编辑 /etc/sysctl.conf
vim /etc/sysctl.conf
# 修改 net.ipv4.ip_forward 为 1
net.ipv4.ip_forward = 1
# 使其生效
sysctl -p
参考
- WireGuard基本原理
- 安装wreguard
- 加密方式
- windows配置
- iptables
- google 地址段
Comments ()