Estimated Reading Time: 6 minutes

编者按

曾经使用 ZeroTier 方案组网,要求两端存在直连路由,任何一端在 NAT/Firewall 背后都会造成体验极差,中转使用的 Moon 服务器部署,从来就没成功过… 前期使用 FRP 方案做内网穿透,用户态进程带来了不稳定性,同时没有跨版本的后向兼容保障,实际使用下来仍然提心吊胆且体验不佳。中期测试过 OpenVPN 方案,由于前几年免流软件的火热,导致 CMCC 对其网络下的 OpenVPN 类软件“用药过猛”,QoS 几乎严重到无法使用,造成了极大的不便。考虑到整体的成本、通信安全、传输速率、稳定性、法律合规性的要求,在结合最近 Wireguard 顺利合入 Linux Kernel 主线的东风,本次尝试了初步体验。实际效果不错,穿国内的 NAT 也好、穿国际的 Wall 也好,体验都还令人满意。

但这里需要注意的是,这类软件大多默认使用 UDP 作为传输层协议,国内运营商普遍 UDP QoS 较重,需要根据各地实际情况使用、部署。

关于 OpenWrt 的部署

OpenWrt 上的部署仅提出几个客户端部署的痛点,本人不建议在路由器端部署 Wireguard 服务端(虽然 Peer 是对等的,即并不存在 Client 和 Server 的概念)。依赖:kmod-wireguard , luci-app-wireguard

首先依然常规操作,此处以 Lean 的固件为例:

  • 如果您在使用路由器级别的梯子,请修改 /etc/init.d/shadowsocksr 中的 235 行,pdnsd 的 query_method 为 udp_tcp 。您的 pdnsd 的版本应当在 1.2.5 以上,修改此处是为了确保流媒体解锁和 DNS 正常服务。
  • 网络 – 接口 – 添加接口 – 类型 WireGuard VPN – 名字 wg0,跳转页面之后正常配置,务必勾选 “添加路由到目标 IP” 的选项。
  • 接下来将此接口分配到 vpn 区域,如不存在,请新建区域为 vpn。
  • 网络 – 防火墙 – vpn 区域 – 编辑:Input->accept,output->accept,Forward->accept,Masquerading->yes,MSS clamping->no;允许从源区域 lan 转发,允许转发到目标区域 wan lan
  • 网络 – 防火墙 – lan 区域 – 编辑:Masquerading->yes;允许从源区域 vpn 转发,允许转发到目标区域 wan vpn
  • 重启接口即可使用

安装依赖

Arch Linux

$ sudo pacman -S wireguard-tools wireguard-arch # If you use linux kernel.

Debian

$ sudo -i
# echo "deb http://deb.debian.org/debian/ unstable main" > /etc/apt/sources.list.d/unstable.list
# printf 'Package: *\nPin: release a=unstable\nPin-Priority: 90\n' > /etc/apt/preferences.d/limit-unstable
# apt update
# apt install wireguard

Others

自己看官网去:点我跳转

注意事项

如果下一步启动 Wireguard 时出现提示不支持的链路类型错误,请尝试手动加载内核模块:modprobe wireguard,并将模块名称添加到/etc/modules-load.d/中任意配置文件中确保开机自动加载。

创建密钥对

$ sudo -i
# cd /etc/wireguard
# wg genkey | tee privatekey | wg pubkey > publickey
# chmod 600 privatekey

开启转发

请不要省略此步!rp_filter 必须配置为 2,松散检查。若配置为 0,不检查,仍然无效,此操作是为了后面的进阶路由做下准备。若不需要进阶路由,可以不配置 rp_filter 选项。

$ sudo -i
# cat <<EOF >/etc/sysctl.d/99-forward.conf
net.ipv4.tcp_fastopen = 3
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.core.default_qdisc = fq
net.ipv4.tcp_congestion_control = bbr
net.core.somaxconn = 2048
net.ipv4.conf.all.rp_filter=2
net.ipv4.conf.default.rp_filter=2
EOF
# sysctl -p /etc/sysctl.d/99-forward.conf

配置对等双端 (Peers)

Wireguard 中各个 host 是对等的 P2P 结构,故不存在绝对的 Server 和 Client 之说。这里我们假设 Wireguard 工作在一个 Wireguard 类型的网卡设备 wg0 上,同时兼容 IPv4 和 IPv6,配置文件示例如下,保存在 /etc/wireguard/wg0.conf#开头的为注释,<>为占位内容,请自行替换 :

假设这个服务器使用 10.11.0.0/24 作为 Wireguard 服务端,同时使用 10.10.0.2/32 作为 10.10.0.0/24 的一个 Wireguard 客户端,配置如下:

[Interface]
Address = 10.11.0.1/24, 10.10.0.2/32
PrivateKey = <privatekey 文件中的内容>
ListenPort = <自定义服务器监听端口> #服务端配置示例,纯客户端可不存在此项

# note - substitute eth0 in the following lines to match the Internet-facing interface
# if the server is behind a router and receive traffic via NAT, this iptables rules are not needed
# PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <物理网卡> -j MASQUERADE
# PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <物理网卡> -j MASQUERADE

[Peer] #服务端配置示例,写入客户端1配置
#Client1
PublicKey = <10.11.0.0/24 客户端1的公钥>
AllowedIPs = 10.11.0.2/32 # <10.11.0.0/24 客户端1的私网 IP>
PersistentKeepalive = <NAT 穿透,建议值:小于25的整数>

[Peer] #客户端配置示例,写入服务端1配置
#Server1
PublicKey = <10.10.0.1/32 服务端1的公钥>
AllowedIPs = 10.10.0.0/24  # <路由子网流量到此网卡>
Endpoint = <服务器公网IP与监听端口>
PersistentKeepalive = <NAT 穿透,建议值:小于25的整数>

内网穿透加强

PersistentKeepalive = <NAT 穿透,建议值:小于25的整数> 为 NAT 穿透选项,Wireguard 原生支撑 NAT 穿透,由于 UDP 协议不存在连接特性,大部分防火墙一般放行间隔默认为 25s,此项保证 KeepAlive 心跳以此间隔发送,确保连接长时间正常工作。建议设置此值为 小于 25 的整数,单位秒。

启动上线

$ sudo wg-quick up wg0

如果没有报错,添加开机自启,否则检查安装、配置文件、内核模块加载情况:

$ sudo systemctl enable wg-quick@wg0.service

参考资料

  • Arch Linux Wiki
  • Wireguard Official Site

最后修改日期:2020年3月11日

作者

留言

发表您的高见,产生思维碰撞