Skip to content

在 OpenWRT 上使用 WireGuard 异地组网

前言

此前我一直在使用的远控方法是简单的将服务通过路由器的端口转发功能转发转发到内网指定 IP 端口。配合 DDNS,这种方法无疑是最简单的,但是它存在很严重的安全性问题。所有不同协议的不同服务,均以裸奔的形式跑在公网,这是很恐怖的一件事,尤其是在经历了几次爆破之后。

很多人经常说自己的隐私不值钱,不会有黑客来入侵。这是一个典型的错误认知,现如今绝大多数黑客攻击都不是为了窃取数据,他们要的是大量的肉鸡,用于挖矿或者 DDOS 攻击。不要觉得这是危言耸听,一些挖矿脚本甚至植入了浏览器脚本中,你打开某个网页的时候可能就已经在帮人挖矿了。

在之前我已经对基于 HTTP 的服务进行了一次改造,使用 Ngnix,将内网所有基于 HTTP 的服务统一通过群晖 NAS 进行反代,并添加 Let's Encrypt 的 SSL 证书实现 HTTPS 加密,再取消相关服务的端口转发。

但是这种方案只能用在基于 HTTP 协议的服务上,对于 SSH、RDP 等其他协议的服务则无能为力。这些服务大多有一个相同的特点,就是基本只有自己会用到,所以特别适合使用 VPN 方式构建加密隧道来访问,而 WireGuard 就是一个很好的选择。

需求

  1. 使用 WireGuard,让远程设备可以直接访问家庭内网网段(192.168.0.0/24)。
  2. 仅访问家庭内网网段(192.168.0.0/24)时才经过WireGuard隧道,其他连接不要经过隧道。

准备

  • 在 OpenWRT 中安装 WireGuard 相关软件包;
  • 拥有公网 IPv4 或全球单播的 IPv6。

「服务端」设置

WireGuard 并不严格区分「服务端」和「客户端」,WireGuard 采用的是对等(peer-to-peer)的架构,每个参与者都是一个对等方(Peer)。

所以你会发现 WireGuard 的「客户端」和「服务端」配置内容差别不大,不要因此感到意外。但在实际的网络通信中因为通信方向的不同,还是要区分出形式上的「服务端」和「客户端」。

此处的「服务端」指代OpenWRT一端的 Peer,「客户端」指代 Windows、Linux、Android 等终端设备的 Peer。

添加 WireGuard VPN 接口

OpenWRT 上的 WireGuard 有一个好处,就是「服务端」的大多数配置都可以在图形界面完成,而无需直面 .config 文件。以下是OpenWRT上「服务端」的配置指南。

  1. LuCI -> 网络 -> 接口中点击添加接口。名称自拟,协议选择 WireGuard VPN,点击创建接口
  2. 在新接口的编辑页面中
    1. 点击常规设置
      1. 点击生成新的密钥对,生成一对新的密钥。
      2. IP地址要选择一个和OpenWRT所在网段(即家庭内网网段:192.168.0.0/24)不同网段的IP,例如:192.168.10.1/24
    2. 点击防火墙设置,选择lan区域。
    3. 保存。
  3. 保存并应用。

设置防火墙规则

如果我们只完成 WireGuard VPN 接口的添加就连接到 WireGuard 隧道,你会发现虽然你可以通过隧道访问 OpenWRT,但是家庭内网网段(192.168.0.0/24)下的其他设备仍然无法访问。

这是因为我们缺乏转发规则,家庭内网网段(192.168.0.0/24)下其他设备的的数据包无法正确路由,解决办法是添加一行 NAT 规则。

  1. LuCI -> 网络 -> 防火墙中点击自定义规则
  2. 在最后添加一行:
    iptables -t nat -A POSTROUTING -s 192.168.10.0/24 -o br-lan -j MASQUERADE

    解释:对于源地址在 192.168.10.0/24 子网内的所有数据包,在它们通过 br-lan 接口离开网络时,进行地址伪装(MASQUERADE),即将它们的源地址更改为路由器的出口地址。这样做的目的是使这些数据包看起来像是来自路由器本身,而不是内部网络,使得外部网络中的响应能够正确返回到内网。

「客户端」设置

使用 OpenWRT 的 WireGuard 的另一个好处是,「客户端」的大多数配置都可以在图形界面下生成,我们没必要从零开始撰写 .config 文件。

获取对端配置

  1. LuCI -> 网络 -> 接口中点击刚才创建的 WireGuard VPN 接口的编辑
  2. 选择对端 -> 添加对端
  3. 在编辑对端的页面中
    1. 点击生成新的密钥对,生成一对新的密钥。
    2. (可选)点击生成预共享密钥对,生成一个新的预共享密钥。
    3. 允许的 IP中添加一个在刚才设置网段内的 IP 地址,例如:192.168.10.2
    4. 点击生成配置。
  4. 在生成配置的页面中
    1. 修改链接端点,此处默认是你网卡的 IPv4 或 IPv6 地址,你应该将其更改为公网可访问的 IP 地址或 DDNS 域名。
    2. 修改允许的 IP,修改为OpenWRT所在网段(192.168.0.0/24)。
    3. 可以复制最下面生成的配置内容,或扫描页面左侧的二维码。配置内容参考:
    [Interface]
    PrivateKey = 2N3CN6H/lXka5OZqM2BTlyLUAGFzlnviMDsWHBj1O2w=
    Address = 192.168.5.2
    # ListenPort not defined
    DNS = 192.168.0.25
    
    [Peer]
    PublicKey = OG6PpNT2zvXcreP0T53C7txUnrRpCbInRLgKSBJXEzM=
    PresharedKey = 0/tj4JuWXgDm2rNt1SE2IHc55J/FjU2iSRvZdz5i/+0=
    AllowedIPs = 192.168.0.0/24
    Endpoint = ddns.com:59943
    # PersistentKeepAlive not defined

    关于「客户端」配置的进一步解释说明和注意事项:

    • 这当中的各种 Key 都是自动生成的,跟着教程来不会在这上面出错;
    • [Interface]Address 是 WireGuard 虚拟网络下的 IP 地址,在「添加 WireGuard VPN 接口」中有设置。
    • [Peer]AllowedIPs 是分流的关键,此处默认是 0.0.0.0/0::/0,代表所有的 IPv4 和 IPv6 地址。对于我们的需求来说,只需要家庭内网网段(192.168.0.0/24)通过隧道即可,所以此处应修改为对应的 192.168.0.0/24,如果有其他需求,也可继续添加其他地址。

疑难解答

创建对端后无法连接

一些奇奇怪怪的 Bug,可能需要重启 WireGuard 相关服务。个人建议直接 reboot OpenWRT。