这篇文章创建于 2022-08-08 日,距今已有 848 天,请注意甄别内容是否已经过时!

0. 前情提要

家中的路由器为斐讯 K2P,之前运行 hiboy 佬的 Padavan 固件已一年有余,也配置了 IPTV 组播转单播等服务,期间除了升级固件和小区停电从未重启,十分稳定。近期由于部分上网需求,加之 MTK 放出了 SDK HWNAT 源码(coolsnowwolf/lede #9450恩山无线论坛),似乎 OpenWrt 又变得可以一试了。于是一顿操作猛如虎,选好了需要的插件之后,发现,诶,以前连回家维护网络时候常用的 OpenVPN 居然因为 K2P 的 16M SPI Flash 太小已经塞不进去了,固件超容,只能找个替代方案。

OpenVPN 屎山代码全责

万幸的是,padavanonly/immortalwrt 采用的是 Linux 5.10,对 WireGuard 完美支持,并且由于 WireGuard 已经是 Linux 5.6+ 内核的一部分,用户态的工具无需占用太多空间,完全可以塞得下,理论上性能也会很不错,对于 MT7621 这类低性能路由器 SoC 十分友好。(当然,对于老版本内核,大雕 / Lean 早就把 WireGuard backport 回去了,所以也是支持的)

于是,我就把 OpenVPN 及其依赖扬了 :)
什么?你问我为什么不用 Lean 的 LEDE?Lean LEDE 虽然也引入了 MTK SDK 的 HWNAT 驱动,但实测下来跑 WAN to WiFi 的时候, CPU 占用比 padavanonly/MeIsReallytBa 的 ImmortalWrt 还是要高,并且速度也更差,跑满的时候 600Mbps 的宽带,ImmortalWrt 能跑 70~75MiB/s,到 Lean OpenWrt/LEDE 就只剩 60MiB/s 了,并且 CPU 占用还要高出 25~40%。而且,helloworld 这段时间在 Lean LEDE 上是炸的,听友人讲,软路由没事,所有硬路由全遭殃,我实测也是如此…… 对不起了雕哥,不是我不想用,是现在真用不了。
需要:一台能运行 OpenWrt / ImmortalWrt 和 WireGuard 的路由器、有 IPv4 / v6 公网 IP 的宽带、域名或 DDNS。

1. 开始折腾

首先当然是编译固件了。当然也可以用 MeIsReallyBa 佬编译好的*,如果是自己编译可以使用 padavanonly/immortalwrt,定制自己所需功能。具体操作,网络上已经有很多教程,这里不再赘述。小站之前的编译教程会择日进行更新(挖坑 1/1)。
需要注意的是,由于新版 MTK SDK 需要占用一定空间,如果编译时选择了 Xray-core,由于 Xray-core 二进制所占空间在 1.5.5 之后大幅增加,可用空间会非常吃紧(Xray-core 一个就占据了大概 6.9MiB 左右,未压缩是 21MiB),加上必须的 UPnP 等插件,对于 K2P 的 16MiB SPI Flash 来说基本上所剩无几,编译时需特别注意。

当然也可以用笔者编译好的:(蓝奏云
sha256sum: c41db8b5344fdbbe1aa75411d298485b4cc7aca50ea4b3dda9e98c15cd10b66b

或者 GitHub Actions CI
集成了 ShadowsocksR Plus+ (Xray-core),UPnP,KMS 服务器,SQM QoS,DDNS (Cloudflare),WOL,上网时间控制,MTK SDK HWNAT,udpxy,以及,本次要用到的 WireGuard。
至于空间有多紧张呢?刷好以后还剩下 256K 可用 :)
root@K2P:~# df -hT
Filesystem           Type            Size      Used Available Use% Mounted on
/dev/root            squashfs       12.5M     12.5M         0 100% /rom
tmpfs                tmpfs          58.5M      1.3M     57.2M   2% /tmp
/dev/mtdblock6       jffs2         640.0K    424.0K    216.0K  66% /overlay
overlayfs:/overlay   overlay       640.0K    424.0K    216.0K  66% /
tmpfs                tmpfs         512.0K         0    512.0K   0% /dev

2. 配置 WireGuard 服务端

2.1 生成密钥对

这部份主要利用 WireGuard 的 wg 工具进行操作。
关于 WireGuard 所用到的密钥,分为服务端公钥/私钥,客户端公钥/私钥,以及预共享密钥五部分。
通过 SSH 登录路由器后台,依次执行以下命令,并将生成的密钥保存到安全的地方:
mkdir wireguard && cd wireguard
umask 077
wg genpsk > preshared.key   #生成预共享密钥
wg genkey | tee server_private.key | wg pubkey > server_public.key  #生成服务器私钥和公钥
wg genkey | tee peer_private.key | wg pubkey > peer_public.key  #生成客户端 / Peer 私钥和公钥
至此,在路由器的 /root/wireguard 目录下生成了五个文件,分别为:preshared.key 预共享密钥、server_private.key 服务器私钥、server_public.key 服务器公钥、peer_private.key 客户端私钥、peer_public.key 客户端公钥。可依次使用 cat 命令查看,并将这些密钥文件保存到安全位置。

00-keys.jpg

注意: /root 并不是 OpenWrt 升级时默认保留的目录,升级固件后会丢失,请务必保存好密钥文件,否则丢失后需要重新生成。

2.2 在 OpenWrt / ImmortalWrt WebUI 上进行配置

登录路由器 Web 后台。

选择 网络 - 接口 - 添加新接口
01-newlink.jpg

接口名称任意,本处起名为 wg,协议选择 WireGuard VPN,点击提交
02-wg-link.JPG

私钥填写先前获取的服务器私钥server_private.key),监听端口任意,本处示例填写为 23456IP 地址 填写任意私有地址均可,注意不要与其他连接冲突且需要为 IP-CIDR 格式,本处填写为 172.16.1.1/24
03-wg-new.jpg

此时如下方没有 Peer 信息,点击页面底部的添加。如有可直接进行修改。
04-addpeer.jpg

选择 页面底部 - 更多选项 - 预共享密钥 - 添加,也可添加 Peer 描述(可选),方法相同,名称任意。
05-addpreshared.jpg

公钥填写先前获取的客户端公钥peer_public.key),预共享密钥填写先前获取的预共享密钥preshared.key允许的 IP 和先前服务器 IP 地址在同一网段且不冲突即可,IP-CIDR 格式,本处填写 172.16.1.0/24。如需固定 IP,也可填写为 172.16.1.2/32。勾选路由允许的 IP持续 Keep-Alive 填写 25端点主机端点主机两项不填写。
06-peer.jpg

回到页面顶部,选择防火墙设置,新建一个防火墙区域wg。如已有其他 VPN 接口,也可选择 VPN 区域,后面配置时注意修改。
点击保存并应用
07-firewall-new.jpg

接下来配置端口映射,选择 网络 - 防火墙 - 流量规则
08-port-rule.jpg

找到页面下方的 打开路由器端口,添加一条流量规则:
名称任意,协议选择 UDP,外部端口和先前设置的服务器监听端口一致,本处为23456,点击添加,然后点击页面底部的保存&应用
09-allow-wireguard-port.jpg

选择网络 - 防火墙 - 常规设置,找到先前添加的 wg 区域(与前文添加的防火墙区域一致,如果你选择了 VPN 区域,这里选 vpn),点击 修改
16-firewall.jpg

端口触发 中的 允许来自源区域的转发 中,勾选 wan 区域,点击保存&应用
17-fw-zone-rule.jpg

回到 网络 - 防火墙- 常规设置,找到 wan 区域,点击 修改。和上面操作类似,在 允许转发到目标区域 中,勾选 wg 接口,点击 保存&应用
18-ex-allow-wan-forward.jpg

回到 网络 - 接口,找到先前添加的 wg,点击连接,重新连接 wireguard 接口。至此,路由器端配置完成。

2.3 配置文件编写

以下仅供参考。
[Interface]
Address = 172.16.1.2/32    #对应客户端分配的内网 IP
PrivateKey = +CrLlMagyRSnq0oQjogfP/7MpROL1uVcaTUJIMdOZ0M=     # 客户端私钥 / peer_private.key
DNS = 119.29.29.29     # 建议填写公共 DNS 服务器 IP

[Peer]
PublicKey = vF8PTU71qTQKVoKPKTIkV+7a/5wDkHqOEtd2agANSHo=     # 服务端公钥 / server_public.key
AllowedIPs = 0.0.0.0/0
# 填写 192.168.2.0/24 这类内网段则仅可访问局域网
# 填写 0.0.0.0/0 即同时可访问局域网和公网(所有流量走 WireGuard VPN)
PresharedKey = 0O+oUq0Yz5ef1SIHV35hqUkcy1EPuepLovtj8melU/g=     # 预共享密钥
Endpoint = my.ddns.domain:23456     # DDNS 域名:端口号
PersistentKeepalive = 25
保存文件为 wireguard.conf,后面在客户端导入。

注意,这里的 Interface 和 Peer 和 WebUI 中配置的是反过来的,因为对于客户端来说,服务端才是远程 Peer。

2.4 客户端配置

2.4.1 Android 手机 - WireGuard 官方应用

Google PlayF-Droid 下载并安装 WireGuard 官方应用。

点击右下角的 + 号,选择导入配置或压缩包,选择先前编写的配置文件,会提示导入了xx配置文件。然后点击上方开关进行连接,可点击配置文件查看详情。
10-import.jpg11-imported.jpg
12-connect.jpg

如您的手机已 Root,可点击右上角三个点(设置) - 高级 - 启用内核模块,可提高性能。
14-android-kmod.jpg

此时可在路由器 WebUI 状态 - WireGuard 状态 中查看连接详情。
13-status.jpg

2.4.2 Android 手机 - SagerNet

下载并安装 SagerNet。
Google PlayGitHub releaseF-droid

点击右上角添加 - 从文件导入,选择先前编写的配置文件。
15-sagernet.jpg

然后点击右下角的小飞机图标进行连接即可,此时可在路由器后台查看连接情况,方法同上。

Enjoy.
小 tip:如果路由器开启了 ShadowsocksR Plus+,可在访问控制 - 接口控制中,勾选 wg 接口,这样远程连入的客户端就也能走代理了。注意潜在的 DNS 泄露风险。

3. 参考 / Credits

Quick Start - WireGuard
OpenWRT 配置 WireGuard 服务端及客户端配置教程

标签: 技术, GNU/Linux, OpenWrt, ImmortalWrt, WireGuard

已有 3 条评论

  1. jks jks

    这个源码默认的wireguard界面没有‘生成密钥’的选项,有没有思路可以做到像新版的一样有这个功能?

  2. Jacques Jacques

    请問摶主,padavanonly/immortalwrt这个源是18.06嗎?

    1. 算是 ImmortalWrt 18.06-k5.4 分支的魔改版。添加了 MTK SDK / a.k.a. 闭源驱动 的支持。

添加新评论