Decentralization? We're still early!

Privacy Router Stack:基于 OpenWrt 和 AmneziaWG 的隐私路由

  • Privacy Router Stack:基于 OpenWrt 和 AmneziaWG 的隐私路由

    發布人 Brave 2026-02-13 12:26

    在传统的网络架构中,你的每一个设备——手机、电脑、智能电视、游戏主机、IoT 设备——都将流量明文暴露给 ISP(互联网服务提供商)。即使你使用了 HTTPS,ISP 仍然可以看到你访问了哪些域名(通过 DNS 查询和 SNI 信息)、何时访问、访问了多久、传输了多少数据。这些元数据足以构建出你完整的在线行为画像。

    VPN 应用程序可以解决单台设备的隐私问题,但它有明显的局限性:

    • 📱 每台设备都需要单独安装和配置 VPN 客户端
    • 🎮 游戏主机、智能电视、IoT 设备等通常无法安装 VPN 应用
    • 💥 VPN 应用崩溃时,Kill Switch 也随之失效——因为它运行在应用层,App 死了,保护就没了
    • 🔢 大多数 VPN 服务限制同时连接设备数量(如 Mullvad 限 5 台)

    隐私路由器从根本上解决了这些问题。 它在网络的入口处——路由器层面——建立加密隧道,所有经过路由器的流量自动受到保护。无论是你的笔记本、手机、智能音箱还是扫地机器人,连上 WiFi 就受保护,零配置、零感知、零遗漏


    核心项目:privacy-first-network

    本文围绕一个优秀的开源项目展开——privacy-first-network(作者:yoloshii)。这是一个完整的隐私优先路由器技术栈,将多项成熟的开源技术整合为一个可一键部署的解决方案。

    🏗️ 技术栈全景

    ┌──────────────────────────────────────────────┐
    │               你的所有设备                     │
    │  💻 电脑  📱 手机  🎮 主机  📺 电视  🏠 IoT    │
    └───────────────────┬──────────────────────────┘
                        │ 连接 WiFi / 有线
                        ▼
    ┌──────────────────────────────────────────────┐
    │          OpenWrt 隐私路由器                    │
    │                                              │
    │  ┌─────────────────────────────────────────┐ │
    │  │ 🛡️ 防火墙 Kill Switch                   │ │
    │  │ VPN 断开 → 流量自动阻断(路由表级别)      │ │
    │  └─────────────────────────────────────────┘ │
    │  ┌─────────────────────────────────────────┐ │
    │  │ 🔒 WireGuard / AmneziaWG 隧道           │ │
    │  │ 全流量加密 + 可选 DPI 混淆               │ │
    │  └─────────────────────────────────────────┘ │
    │  ┌─────────────────────────────────────────┐ │
    │  │ 🧹 AdGuard Home + DNS-over-HTTPS        │ │
    │  │ 广告拦截 + DNS 加密 + 防追踪             │ │
    │  └─────────────────────────────────────────┘ │
    │  ┌─────────────────────────────────────────┐ │
    │  │ 🔄 Watchdog 自动恢复                     │ │
    │  │ 隧道断线 → 自动检测 → 自动重连           │ │
    │  └─────────────────────────────────────────┘ │
    └───────────────────┬──────────────────────────┘
                        │ 加密隧道
                        ▼
    ┌──────────────────────────────────────────────┐
    │          VPN 服务器(如 Mullvad)              │
    │          你的真实 IP 被隐藏                    │
    └──────────────────────────────────────────────┘

    📋 核心功能清单

    功能说明
    🌐 全设备保护智能电视、游戏主机、IoT、手机、电脑……连上就保护
    🛡️ 防火墙级 Kill SwitchVPN 掉线时路由表无出口,流量自动阻断,不依赖任何软件进程
    🔒 WireGuard 加密隧道Linux 内核原生支持,高性能、低延迟、代码精简
    🥷 AmneziaWG DPI 绕过流量混淆,抵御深度包检测,突破 VPN 封锁
    🧹 AdGuard Home DNS 过滤全网广告拦截 + DNS-over-HTTPS 加密
    🔄 Watchdog 自动恢复隧道故障自动检测并重启
    🤖 AI 辅助部署项目自带 Agent 指令,支持 Claude Code 等 AI 工具辅助部署

    🤝 VPN 服务商兼容性

    privacy-first-network 兼容任何支持 WireGuard 协议的 VPN 服务商,包括但不限于:

    • Mullvad VPN(€5/月,匿名注册,无需邮箱)
    • IVPN(注重隐私,支持 Multihop)
    • ProtonVPN(瑞士公司,有免费计划)
    • AirVPN(老牌隐私 VPN,支持端口转发)
    • 或任何自建的 WireGuard 服务器

    为便于进行技术演示,以下文章内容基于Mullvad VPN。


    部署架构与选择

    privacy-first-network 提供三种部署架构,适应不同的网络环境和技术水平:

    方案 A:完全替换路由器(推荐新手)

    互联网 ── 光猫(桥接模式) ── OpenWrt 路由器(拨号+VPN+WiFi)

    适用场景: 你愿意用 OpenWrt 路由器完全替代现有路由器。OpenWrt 负责一切——PPPoE 拨号(或 DHCP 获取 IP)、路由、DHCP 服务、DNS、防火墙、VPN 隧道、WiFi。这是最简洁的架构,所有流量必经 VPN,无泄漏可能。

    优点:

    • ✅ 架构最简单,维护成本最低
    • ✅ 所有流量 100% 经过 VPN
    • ✅ 单点控制,一台设备搞定一切

    缺点:

    • ❌ 需要路由器性能足够强(同时跑 VPN 加密 + WiFi + AdGuard Home)
    • ❌ WiFi 覆盖取决于 OpenWrt 路由器的天线性能

    方案 B:双路由器模式(推荐进阶用户)

    互联网 ── 光猫 ── 主路由(原有路由器) ── OpenWrt(VPN网关)
                                                             │
                                              设备网关指向 OpenWrt IP

    适用场景: 你不想放弃现有路由器的 WiFi 性能(比如 WiFi 7 旗舰路由),但想给部分或全部设备加上 VPN 保护。OpenWrt 设备只负责 VPN 网关功能。

    具体做法: 在需要 VPN 保护的设备上,将网关地址和 DNS 服务器手动指向 OpenWrt 路由器的 IP。不需要 VPN 的设备继续用原路由器的网关。这样可以实现设备级别的分流

    优点:

    • ✅ 保留现有路由器的 WiFi 性能
    • ✅ 可以灵活选择哪些设备走 VPN
    • ✅ OpenWrt 设备可以用低功耗硬件(如树莓派)

    缺点:

    • ❌ 架构稍复杂,两台设备需要维护
    • ❌ 设备需要手动配置网关(或通过 DHCP 选项自动分配)

    方案 C:Docker 容器模式(适合极客/NAS 用户)

    互联网 ── 路由器 ── NAS/服务器(运行 Docker VPN 容器)
                             │
                  设备网关指向容器 IP

    适用场景: 你已经有一台 24 小时运行的 Linux 服务器、NAS(群晖/威联通/Unraid)或虚拟机,不想额外购置硬件。通过 Docker 容器运行 VPN 网关,现有路由器不做任何改动。

    优点:

    • ✅ 无需额外硬件
    • ✅ Docker 部署简单,更新方便
    • ✅ 可利用服务器的强大算力

    缺点:

    • ❌ 依赖服务器持续运行
    • ❌ 与方案 B 类似,需要手动配置设备网关

    核心组件深度解析

    组件一:WireGuard —— 隧道协议

    📖 WireGuard 是什么

    WireGuard 是一种现代 VPN 协议,由 Jason A. Donenfeld 设计,2020 年正式合并进 Linux 内核主线(5.6+)。相比 OpenVPN 和 IPSec,WireGuard 的核心代码仅约 4000 行(OpenVPN 约 10 万行),极大降低了审计难度和攻击面。

    值得特别注意的是,Mullvad VPN 已宣布将于 2026 年 1 月 15 日全面停止 OpenVPN 服务器运营,届时 WireGuard 将成为其唯一支持的隧道协议。这一决定印证了行业向 WireGuard 迁移的大趋势。

    ⚙️ 加密原语

    用途算法
    密钥交换Curve25519 (ECDH)
    数据加密ChaCha20-Poly1305 (AEAD)
    哈希BLAKE2s
    密钥派生HKDF

    这套加密组合是 Daniel J. Bernstein 等顶级密码学家设计的"safe by default"方案——没有可协商的密码套件,意味着不存在降级攻击的可能

    🚀 性能优势

    WireGuard 运行在 Linux 内核空间(而非用户空间),避免了频繁的上下文切换。在 ARM 处理器上,ChaCha20 比 AES 更快(除非硬件有 AES-NI 指令),这使得 WireGuard 在路由器等嵌入式设备上的性能尤其出色。

    在 OpenWrt 上安装 WireGuard:

    opkg update
    opkg install luci-proto-wireguard
    # 此命令会自动安装以下依赖:
    # - kmod-wireguard   (内核模块)
    # - wireguard-tools   (用户态工具: wg, wg-quick)
    # - luci-proto-wireguard (LuCI 界面支持)

    🔧 配置要点

    从 Mullvad 官网(Account → WireGuard configuration)生成配置文件后,在 OpenWrt 的 LuCI 界面中:

    1. 进入 网络 → 接口 → 添加新接口
    2. 协议选择 WireGuard VPN
    3. 点击 "导入配置",粘贴 .conf 文件内容
    4. 系统自动填入私钥、地址、Peer 等信息

    手动补充设置(导入后不会自动配置的项目):

    • Persistent Keep Alive:设为 25(秒)——这是为了维持 NAT 映射,防止隧道因空闲超时断开
    • 勾选 Route Allowed IPs——让所有流量走 WireGuard 隧道
    • 高级设置 中勾选 Force link——即使隧道暂时不通也保持接口"在线"状态,防止路由表错误切换

    组件二:Kill Switch —— 防火墙级流量阻断

    📖 为什么 Kill Switch 至关重要

    VPN 隧道不是永不中断的。服务器重启、网络波动、ISP 干扰都可能导致隧道瞬间断开。如果没有 Kill Switch,断开的那几秒钟内,你的真实 IP 地址和 DNS 查询就会泄漏给 ISP。

    🔑 应用层 vs 防火墙层 Kill Switch

    这是理解 privacy-first-network 方案价值的关键:

    应用层 Kill Switch(VPN App 方案):

    VPN App 进程监控隧道状态
             ↓
      隧道断开 → App 检测到
             ↓
      App 调用系统 API 修改路由规则
             ↓
      阻断流量

    问题在于:如果 VPN App 本身崩溃了(OOM、段错误、系统杀进程),监控进程不复存在,路由规则不会被修改,流量直接走默认的 WAN 出口泄漏出去。这不是理论风险——在 Android 的内存管理机制下,后台 VPN 应用被系统杀掉是常见现象。

    防火墙层 Kill Switch(OpenWrt 方案):

    防火墙规则写死:LAN → 只能转发到 WGZONE
                    LAN → WAN 转发被永久删除
             ↓
      WireGuard 隧道正常 → 流量经 WGZONE → VPN 服务器 → 互联网
             ↓
      WireGuard 隧道断开 → 流量到达 WGZONE → 无出口 → 自动丢弃

    关键区别:防火墙规则存在于内核空间的 netfilter/nftables 中,与任何用户空间进程无关。 即使 WireGuard 进程崩溃、即使路由器 CPU 负载 100%、即使 OpenWrt 的管理界面无法访问——只要内核还在运行,防火墙规则就在生效,流量就不会泄漏。

    ⚙️ 具体配置

    在 OpenWrt 的 /etc/config/firewall 中,核心逻辑如下:

    # 新建 VPN 防火墙区域
    config zone
        option name 'WGZONE'
        option input 'REJECT'        # 拒绝从 VPN 发起的入站连接
        option output 'ACCEPT'       # 允许向 VPN 发送流量
        option forward 'REJECT'      # 默认拒绝转发
        option masq '1'              # 启用 NAT 伪装
        list network 'wginterface'   # 绑定 WireGuard 接口
    
    # LAN → WGZONE 转发:允许
    config forwarding
        option src 'lan'
        option dest 'WGZONE'
    
    # 关键:不存在 LAN → WAN 的转发规则!
    # 没有这条规则,LAN 流量永远无法直接到达 WAN
    # 这就是防火墙级 Kill Switch 的本质

    通过 LuCI 界面操作:

    1. 网络 → 防火墙 → 新建 Zone,命名为 WGZONE
    2. Input: 拒绝,Output: 允许,Forward: 拒绝
    3. 勾选 Masquerading(NAT 伪装)
    4. 将 WireGuard 接口分配到此 Zone
    5. 编辑 LAN Zone → "Allow forward to destination zones"仅保留 WGZONE删除 WAN

    ⚠️ 注意: 完成此配置后,如果 WireGuard 隧道未连接,路由器下的所有设备将完全无法上网。这正是 Kill Switch 的预期行为——宁可断网也不泄漏。


    组件三:AmneziaWG —— 流量混淆与 DPI 绕过

    📖 为什么需要流量混淆

    WireGuard 虽然加密了数据内容,但它的协议指纹非常明显。WireGuard 的握手包(Handshake Initiation)固定为 148 字节,响应包固定为 92 字节,数据包以固定的 4 字节类型字段开头(1=Initiation, 2=Response, 3=Cookie, 4=Transport)。这些特征就像指纹一样,让深度包检测(DPI)系统可以在毫秒内识别并阻断 WireGuard 流量。

    在网络审查较为严格的国家和地区(如中国、俄罗斯、伊朗),ISP 部署的 DPI 设备可以轻松识别和封锁 WireGuard 连接。即使在审查相对宽松的国家,ISP 也可能出于"网络管理"目的对 VPN 流量进行限速(throttling)。

    🥷 AmneziaWG 的技术原理

    AmneziaWG 是 WireGuard-Go 的一个分支(fork),由 Amnezia VPN 团队开发和维护。它在传输层进行混淆,而加密层完全保持与 WireGuard 一致(Curve25519 + ChaCha20-Poly1305 + BLAKE2s)。这意味着它不会引入任何新的密码学风险。

    AmneziaWG 采用四重混淆机制

    📌 机制一:报头随机化(Header Randomization)

    WireGuard 的消息类型字段是固定值(1/2/3/4),AmneziaWG 将其替换为可配置的随机值。DPI 系统无法再通过检查数据包开头的几个字节来判断是否为 WireGuard 流量。

    📌 机制二:握手包填充(Handshake Size Modification)

    在每个认证包的开头添加随机长度的"垃圾数据"(junk),由 S1 和 S2 参数控制。原本固定 148 字节的握手发起包变为 148 + S1 字节,S1 的值每个客户端都不同。这消除了包大小这一最显著的指纹特征。

    📌 机制三:垃圾包注入(Junk Packet Injection)

    在建立会话之前,客户端会先发送一定数量的无意义 UDP 包。DPI 系统看到的不是"一个标准的 WireGuard 握手序列",而是一堆杂乱无章的 UDP 数据包,其中有些是真实握手、有些是垃圾。参数 Jc(junk count)、Jmin(junk 最小长度)、Jmax(junk 最大长度)均可调节。

    📌 机制四:协议伪装(Protocol Mimicry,v1.5 新增)

    这是 AmneziaWG v1.5 引入的最强混淆能力。流量可以被伪装成常见的 UDP 协议,如 QUIC、DNS 查询、DTLS 等。DPI 系统看到的不是"可疑的加密 UDP 流量",而是看起来完全正常的网络通信。结合 CPS(Custom Protocol Signature)格式,用户甚至可以自定义要模仿的协议签名。

    💡 关键特性:客户端侧混淆

    AmneziaWG 的混淆是完全在客户端侧完成的,兼容任何标准 WireGuard 服务器。这意味着你可以直接将它与 Mullvad、IVPN 等商业 VPN 的标准 WireGuard 服务器配合使用,不需要服务端做任何修改

    🔬 性能影响

    根据 AmneziaWG 开发团队的文档和社区测试反馈:

    • 内核模块实现:性能影响可以忽略不计。混淆操作仅作用于包头而非载荷数据,对整体传输速率的影响通常在 1-3% 以内。
    • 用户空间(Go)实现:可能有额外开销,取决于硬件性能和垃圾包注入量。
    • MTU 调优建议:启用混淆后,建议将 MTU 设置为 1320-1420(取决于网络条件和混淆参数),以优化带宽利用率。
    • 混淆参数(Jc、Jmin、Jmax、S1、S2 等)均可在 Amnezia 应用或配置文件中调节,允许你在"隐蔽性"和"速度"之间找到最佳平衡点。

    ⚙️ 在 OpenWrt 上安装 AmneziaWG

    AmneziaWG 已有适用于 OpenWrt 的安装脚本,由社区成员维护:

    # 自动安装(自动检测路由器架构并安装对应版本)
    sh <(wget -O - https://raw.githubusercontent.com/Slava-Shchipunov/awg-openwrt/refs/heads/master/amneziawg-install.sh)

    安装完成后,在 LuCI 中创建新接口时,协议列表中会出现 AmneziaWG VPN 选项。配置方式与标准 WireGuard 类似,但多了 S1、S2、Jc、Jmin、Jmax 等混淆参数的设置项。

    你也可以使用转换工具,将现有的 Mullvad WireGuard .conf 配置文件自动转换为 AmneziaWG 格式,并添加混淆参数。GitHub 上的 wireguard-dpi-circumvention-converter 项目可以完成这项工作。


    组件四:DNS 安全 —— 多层防护

    DNS 是隐私链条中最容易被忽视的薄弱环节。即使你的数据通道已经被 VPN 加密,如果 DNS 查询泄漏到 ISP 的 DNS 服务器,ISP 仍然能知道你访问了哪些网站。

    privacy-first-network 提供了两种 DNS 方案,可根据需求选择或组合使用:

    🔹 方案一:Mullvad 内置 DNS(简单直接)

    当你通过 WireGuard 连接到 Mullvad 后,可以直接使用 Mullvad 在 VPN 隧道内部提供的 DNS 服务器。这些 DNS 查询走的是已加密的 VPN 隧道,ISP 无法窥探。

    Mullvad 提供了精细的 DNS 内容拦截选项,通过不同的 IP 地址选择不同的拦截级别:

    DNS 地址拦截内容适用场景
    10.64.0.1🔓 无拦截纯 DNS 解析,不过滤任何内容
    100.64.0.1🚫 广告基础广告拦截
    100.64.0.3🚫 广告 + 追踪器日常隐私保护
    100.64.0.7🚫 广告 + 追踪器 + 恶意软件推荐大多数用户
    100.64.0.15🚫 广告 + 追踪器 + 恶意软件 + 成人内容家庭保护模式
    100.64.0.23🚫 广告 + 追踪器 + 恶意软件 + 赌博过滤赌博网站
    100.64.0.47🚫 全部(广告/追踪/恶意/成人/赌博/社交媒体)最严格的过滤

    在 OpenWrt 中配置:网络 → 接口 → LAN → DHCP 服务器 → 高级设置 → DHCP-Options

    6,100.64.0.7

    这条配置会告诉所有通过 DHCP 获取 IP 的设备:"你的 DNS 服务器是 100.64.0.7"。所有设备的 DNS 查询会自动走 VPN 隧道到达 Mullvad 的拦截 DNS。

    ⚠️ Starlink 用户注意: Starlink 使用 CGNAT,其地址范围 100.64.x.x 与 Mullvad 的内容拦截 DNS 地址冲突。如果你使用 Starlink,需要额外添加一条静态路由(网络 → 路由 → 静态 IPv4 路由),确保 100.64.0.7 的流量走 VPN 隧道而非 WAN。

    🔹 方案二:AdGuard Home + DNS-over-HTTPS(进阶方案)

    AdGuard Home 是一个运行在路由器上的 DNS 过滤服务器,相比 Mullvad 内置 DNS,它提供更精细的控制:

    • ✅ 自定义过滤规则(可添加/排除特定域名)
    • ✅ 查询日志和统计面板(可视化了解被拦截的请求)
    • ✅ 支持多种上游 DNS 加密协议(DoH、DoH3、DoT、DoQ)
    • ✅ DNS 缓存(减少重复查询,加速响应)
    • ✅ 支持本地 DNS 重写(自定义域名解析)

    安装 AdGuard Home:

    opkg update
    opkg install adguardhome

    💡 提示: OpenWrt 仓库中的 AdGuard Home 版本可能较旧。建议从 AdGuard Home GitHub Releases 下载最新版二进制文件,替换 /usr/bin/AdGuardHome

    配置 Mullvad 加密 DNS 作为上游:

    在 AdGuard Home 管理界面(http://路由器IP:3000)→ Settings → DNS Settings → Upstream DNS Servers 中填入:

    https://base.dns.mullvad.net/dns-query

    这是 Mullvad 的 DNS-over-HTTPS 地址(含广告 + 追踪器 + 恶意软件拦截)。Mullvad 提供的加密 DNS 服务完全免费,对所有人开放,无论是否为 Mullvad VPN 用户。

    Mullvad 加密 DNS 的完整选项:

    DoH 地址过滤级别
    https://dns.mullvad.net/dns-query无过滤
    https://adblock.dns.mullvad.net/dns-query广告 + 追踪器
    https://base.dns.mullvad.net/dns-query广告 + 追踪器 + 恶意软件
    https://family.dns.mullvad.net/dns-query广告 + 追踪器 + 恶意软件 + 成人内容
    https://all.dns.mullvad.net/dns-query全部过滤

    禁用 dnsmasq 的 DNS 功能:

    安装 AdGuard Home 后,需要将 OpenWrt 默认的 dnsmasq DNS 功能关闭(保留其 DHCP 功能),以避免冲突。在 LuCI 中将 dnsmasq 的监听端口设为 0,或在 /etc/config/dhcp 中设置 option port '0'

    关于在 VPN 隧道内使用 DNS 加密的说明:

    根据 Mullvad 官方文档的建议:当你已经连接到 Mullvad VPN 时,DNS 查询本身已经走在加密的 VPN 隧道内,额外使用 DNS-over-HTTPS 的安全收益是有限的,而且 DoH 会增加约 10-30ms 的延迟。但 AdGuard Home 的价值不仅在于 DNS 加密——它的自定义过滤规则、查询日志、统计面板才是其真正的杀手级功能。因此,即使在 VPN 隧道内,运行 AdGuard Home 仍然有实际意义。


    组件五:Watchdog —— 隧道自动恢复

    VPN 隧道可能因多种原因中断:服务器维护、网络波动、ISP 干扰等。配合 Kill Switch,隧道中断意味着完全断网。Watchdog 脚本的作用就是自动检测隧道状态并尝试恢复。

    ⚙️ 基本实现

    #!/bin/sh
    # /usr/bin/mullvad-watchdog.sh
    # 通过 ping Mullvad 内部 DNS 地址来检测隧道是否存活
    
    PING_TARGET="10.64.0.1"        # Mullvad 内部 DNS
    PING_COUNT=3                    # 发送 3 个 ping 包
    PING_TIMEOUT=5                  # 每个包超时 5 秒
    WG_INTERFACE="wginterface"      # WireGuard 接口名称
    LOG_TAG="mullvad-watchdog"      # 日志标签
    
    if ! ping -c $PING_COUNT -W $PING_TIMEOUT $PING_TARGET > /dev/null 2>&1; then
        logger -t $LOG_TAG "VPN tunnel appears down. Restarting $WG_INTERFACE..."
        ifdown $WG_INTERFACE
        sleep 3
        ifup $WG_INTERFACE
        logger -t $LOG_TAG "$WG_INTERFACE restarted. Waiting for reconnection..."
        sleep 10
    
        # 二次检测:重启后是否恢复
        if ping -c $PING_COUNT -W $PING_TIMEOUT $PING_TARGET > /dev/null 2>&1; then
            logger -t $LOG_TAG "VPN tunnel restored successfully."
        else
            logger -t $LOG_TAG "WARNING: VPN tunnel still down after restart!"
        fi
    fi

    添加 cron 定时任务(每 2 分钟检查一次):

    # 编辑 crontab
    crontab -e
    # 添加以下行:
    */2 * * * * /usr/bin/mullvad-watchdog.sh

    增强版策略(privacy-first-network 项目的做法):

    privacy-first-network 内置了更智能的 watchdog 逻辑:不仅检测隧道是否存活,还会在连续多次重启失败后尝试切换到备用服务器。这避免了因某个 Mullvad 服务器宕机而导致长时间断网的情况。


    进阶功能实现

    🔀 Multihop 双跳 —— 增强隐私

    📖 什么是 Multihop

    Multihop(多跳)是指你的流量经过两个 VPN 服务器才到达互联网。例如:你的设备 → 日本东京服务器(入口)→ 荷兰阿姆斯特丹服务器(出口)→ 互联网。

    好处是:即使入口服务器被攻破(或被执法机构扣押),攻击者也只能看到加密流量指向另一个 VPN 服务器,而无法得知最终出口 IP。Mullvad 的所有 WireGuard 服务器之间都通过 WireGuard 隧道互联,天然支持 Multihop。

    ⚙️ 在 OpenWrt 上配置 Multihop

    Multihop 的配置原理非常巧妙——你只需修改 WireGuard 配置文件中的 EndpointPublicKey

    [Interface]
    PrivateKey = <你的私钥>
    Address = 10.66.x.x/32
    DNS = 100.64.0.7
    
    [Peer]
    # PublicKey = 出口服务器的公钥(如荷兰阿姆斯特丹 nl-ams-wg-001)
    PublicKey = <nl-ams-wg-001 的 WireGuard 公钥>
    AllowedIPs = 0.0.0.0/0
    # Endpoint = 入口服务器的 IP : 出口服务器的 Multihop 端口
    Endpoint = 185.213.154.68:3004
    #          ↑ 日本东京入口 IP   ↑ 荷兰阿姆斯特丹的 Multihop 端口

    关键信息的获取方式:

    1. 访问 Mullvad Servers 页面
    2. 点击某个服务器,可以看到它的 WireGuard 公钥Multihop 端口
    3. 入口服务器使用其 IP 地址,出口服务器使用其 Multihop 端口号

    甚至可以实现三跳: Mullvad 的每个服务器都运行了 SOCKS5 代理。你可以在 Multihop 的基础上,让浏览器通过 SOCKS5 连接第三个服务器,实现三层跳转,每一层使用不同的出口节点。


    🔀 Split Tunneling 分流 —— 策略路由

    📖 为什么需要分流

    不是所有流量都适合走 VPN。一些场景下你可能需要直连:

    • 🎮 游戏主机:VPN 会增加延迟,影响竞技体验
    • 🏦 网银/政务网站:某些网站会因 VPN IP 触发风控
    • 📺 本地流媒体:某些国内视频平台会封锁 VPN IP
    • 💼 远程办公:公司内网可能不允许 VPN 中继

    ⚙️ 使用 PBR(Policy-Based Routing)实现

    OpenWrt 的 pbr 包是目前最成熟的策略路由解决方案:

    opkg install pbr luci-app-pbr

    PBR 的工作原理: 它不驻留在内存中运行,而是创建路由表和 nftables 规则/集合条目。当监控的接口状态变化时,规则会自动更新。这种设计非常轻量且稳定。

    2025 年版本重要变化(v1.2.0+):

    • ⚠️ 完全放弃了 iptables/ipset 支持,仅使用 fw4 nftables
    • 自动检测 WireGuard 服务器接口,确保 VPN 服务器本身的流量走 WAN
    • 新增防泄漏机制:在 PBR 重启或重载期间暂停转发,防止短暂的流量泄漏(间隔约 4-10 秒,取决于 CPU 性能)

    配置示例:

    通过 LuCI(Services → Policy-Based Routing),你可以按以下维度创建路由策略:

    规则维度示例路由方向
    源 IP 地址192.168.1.100(游戏主机)→ WAN(直连)
    源 IP 地址192.168.1.0/24(其余所有设备)→ WGINTERFACE(VPN)
    目标域名*.bilibili.com→ WAN(直连)
    目标域名*(其余所有域名)→ WGINTERFACE(VPN)

    🔐 Post-Quantum 抗量子隧道

    📖 量子计算威胁

    当前的加密算法(如 WireGuard 使用的 Curve25519)基于椭圆曲线离散对数问题,理论上可被足够强大的量子计算机通过 Shor 算法破解。虽然这种量子计算机目前尚不存在,但"先收集、后解密"(Harvest Now, Decrypt Later)的威胁是真实的——攻击者可以今天记录你的加密流量,等未来量子计算机成熟后再解密。

    Mullvad 是业界最早将 Post-Quantum 密钥交换集成到 VPN 产品中的商业服务商之一

    ⚙️ mullvad-upgrade-tunnel 工具

    Mullvad 开源了 wgephemeralpeer 项目,其中包含 mullvad-upgrade-tunnel 工具。它可以在不使用 Mullvad 完整应用的情况下,为任何 wg-quick 管理的 WireGuard 隧道添加抗量子密钥交换。

    工作原理: 在 WireGuard 隧道建立后,mullvad-upgrade-tunnel 通过 gRPC API 与 Mullvad 服务器协商一个基于后量子密码学(目前使用 Kyber/ML-KEM)的预共享密钥(PSK),并注入到 WireGuard 的 Peer 配置中。验证方式是运行 wg 命令后,可以看到 Peer 下方出现 preshared key: (hidden) 字段。

    重要澄清:mullvad-upgrade-tunnel 是用 Go 语言编写的,而非 Rust。最新版本为 v1.0.6(2025 年 2 月发布),使用 Go 1.23.5 编译。

    在 OpenWrt 上部署:

    官方仅提供 x86_64 和 macOS 的预编译二进制文件。对于 ARM 架构的 OpenWrt 路由器,你需要交叉编译

    # 在你的电脑上(非路由器上),需要安装 Go 1.23+
    git clone https://github.com/mullvad/wgephemeralpeer.git
    cd wgephemeralpeer
    
    # 交叉编译到 ARM64(如 GL.iNet Flint 2 的 MT7986)
    GOOS=linux GOARCH=arm64 go build -o mullvad-upgrade-tunnel ./cmd/mullvad-upgrade-tunnel/
    
    # 传输到路由器
    scp mullvad-upgrade-tunnel root@192.168.1.1:/usr/bin/
    
    # 在路由器上赋予执行权限
    ssh root@192.168.1.1 "chmod +x /usr/bin/mullvad-upgrade-tunnel"

    💡 替代方案: 如果你不熟悉交叉编译,可以发邮件给 Mullvad 技术支持(support@mullvadvpn.net),告知你的路由器型号和 CPU 架构,他们会帮你编译对应的二进制文件。


    🔄 服务器快速切换脚本

    在 OpenWrt 上使用 Mullvad 时,切换服务器需要修改 WireGuard Peer 的 Endpoint 和 PublicKey。以下脚本可以一键完成:

    #!/bin/sh
    # /usr/bin/mullvad-switch.sh
    # 用法: mullvad-switch.sh <服务器名称>
    # 示例: mullvad-switch.sh tokyo
    
    # ====== 服务器配置 ======
    # 从 https://mullvad.net/en/servers 获取每个服务器的 IP、公钥和端口
    
    case "$1" in
        tokyo)
            ENDPOINT="185.213.154.68"
            PUBKEY="Ew0CnOsZMJmJHAOM+jCmSgJo5brbGWqR4x/yUBpYRgU="
            ;;
        hongkong)
            ENDPOINT="146.70.xxx.xxx"
            PUBKEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="
            ;;
        amsterdam)
            ENDPOINT="193.32.xxx.xxx"
            PUBKEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="
            ;;
        london)
            ENDPOINT="185.65.xxx.xxx"
            PUBKEY="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx="
            ;;
        *)
            echo "可用服务器: tokyo | hongkong | amsterdam | london"
            echo "用法: $0 <服务器名称>"
            exit 1
            ;;
    esac
    
    # ====== 执行切换 ======
    WG_PEER="wgpeer"           # UCI 中的 Peer 配置名
    WG_IFACE="wginterface"     # WireGuard 接口名
    
    uci set network.${WG_PEER}.endpoint_host="$ENDPOINT"
    uci set network.${WG_PEER}.endpoint_port="51820"
    uci set network.${WG_PEER}.public_key="$PUBKEY"
    uci commit network
    
    ifdown $WG_IFACE && sleep 2 && ifup $WG_IFACE
    
    logger -t mullvad-switch "Switched to $1 ($ENDPOINT)"
    echo "✅ 已切换到 $1"

    Mullvad App 完整功能对照

    对于已经熟悉 Mullvad 桌面/移动端应用的用户,以下是App 功能与 OpenWrt 方案的完整对照,帮助你了解哪些功能可以复刻、哪些无法实现:

    Mullvad App 功能OpenWrt 实现实现方式难度
    ✅ WireGuard 隧道✅ 完全支持kmod-wireguard 内核模块
    ✅ Kill Switch更强(防火墙级)nftables 防火墙规则⭐⭐
    ✅ DNS 内容拦截✅ 完全支持Mullvad DNS / AdGuard Home
    ✅ Multihop 双跳✅ 完全支持修改 Endpoint 配置⭐⭐
    ✅ 自动重连✅ 完全支持Watchdog cron 脚本⭐⭐
    ✅ Split Tunneling✅ 完全支持pbr 策略路由包⭐⭐⭐
    ✅ 服务器切换✅ 完全支持Shell 脚本 + UCI 命令⭐⭐
    ✅ 抗量子隧道 (PQ)⚠️ 可行但需编译mullvad-upgrade-tunnel (Go)⭐⭐⭐⭐
    ✅ 流量混淆⚠️ 替代方案更强AmneziaWG(比 App 内置更强大)⭐⭐⭐
    ✅ DAITA(抗 AI 流量分析)❌ 目前不可能需要 Mullvad 专有实现

    🧬 关于 DAITA:唯一无法复刻的功能

    DAITA(Defense Against AI-guided Traffic Analysis)是 Mullvad 与瑞典卡尔斯塔德大学(Karlstad University)联合开发的前沿技术,旨在对抗基于 AI 的流量分析攻击。

    DAITA 的三大核心技术:

    1. 📐 统一包大小(Constant Packet Sizes): 所有通过 VPN 发送的数据包被填充到相同的固定大小。数据包的大小是重要的指纹特征——特别是小包,DAITA 通过统一包大小消除这一信息。
    2. 📡 随机背景流量(Random Background Traffic): 不可预测地在真实流量中混入虚假数据包。这使得观察者难以区分有意义的网络活动和背景噪声。
    3. 🌀 数据模式扭曲(Data Pattern Distortion): 在你访问网站时,DAITA 会在客户端和 VPN 服务器之间双向发送额外的伪装流量,扭曲原本可识别的流量模式。每个网站会产生独特的数据包时序和大小模式(就像指纹),DAITA 通过注入"噪声"使这些模式无法被可靠识别。

    DAITA v2(2025 年 3 月发布)的重大改进:

    • 🔄 动态配置: 服务器为每个连接随机分配不同的防御配置。两个客户端访问同一个网页,产生的隧道内流量模式完全不同。每次重新连接时,都会从数千种可能的配置中随机选择一种。
    • 📉 开销减半: v2 的虚假包注入量仅为 v1 的一半,但防御效果相同,直接提升了连接速度。
    • 🔧 服务端可更新: 新的防御策略可以在服务端动态更新,无需客户端升级。如果攻击者花费大量资源针对当前的 DAITA 配置训练分析模型,Mullvad 只需更新服务端配置即可使其失效。

    底层框架 Maybenot: DAITA 构建在开源的 Maybenot 框架之上,使用概率状态机来决定何时发送填充包、何时阻塞出站流量。客户端和服务端运行不同的状态机,配合不同的限制参数。

    为什么无法在 OpenWrt 上实现: DAITA 需要客户端和服务端的紧密协作——服务端需要运行对应的 Maybenot 状态机来配合客户端的防御行为。这种协作机制内置在 Mullvad 的专有 VPN 引擎 GotaTun(Rust 编写)中,目前没有开源的独立实现可供移植到 OpenWrt。

    变通方案: 如果你对 DAITA 有刚需,可以在一两台最敏感的设备上运行 Mullvad 客户端应用(使用 DAITA),同时让其余设备通过 OpenWrt 路由器的 WireGuard 隧道获得保护。两者可以共存。


    2025-2026 年隐私监管背景

    理解为什么"全屋隐私路由"在当下比以往任何时候都更有意义,需要了解全球隐私监管的演变趋势。privacy-first-network 项目的 README 中也明确提到了这一背景:

    🌏 全球趋势

    • 🇦🇺 澳大利亚社交媒体禁令:2025 年 12 月生效的年龄验证要求,平台必须验证用户年龄,实质上要求实名上网。
    • 🇺🇸 美国多州年龄验证法案:多个州正在通过针对不同内容类别的年龄验证法案。
    • 🇪🇺 欧盟数字服务法(DSA):扩大了平台责任和数据留存要求。
    • 🌍 各国 ISP 数据留存法规:越来越多的国家要求 ISP 保存用户的浏览记录。

    全屋隐私路由的价值在于: 每一台设备的流量都通过加密隧道传输,ISP 无法记录你的浏览历史,也不存在"逐站点身份验证"的问题。


    常见问题与故障排查

    ❓ VPN 连接成功但速度很慢

    • 🔍 检查路由器 CPU 负载(top 命令),WireGuard 加密是否成为瓶颈
    • 🔍 尝试更换距离更近的 Mullvad 服务器(地理距离是影响延迟的主要因素)
    • 🔍 检查 MTU 设置——默认 1420 可能需要根据你的网络环境调低(尝试 1380 或 1320)
    • 🔍 如果使用 AmneziaWG,尝试减小 Jc(垃圾包数量)和 Jmax(垃圾包最大长度)参数

    ❓ Mullvad 连接检查显示 DNS 泄漏

    • 🔍 确认 DHCP-Options 是否正确设置为 6,100.64.0.7
    • 🔍 检查设备是否手动配置了其他 DNS 服务器(覆盖了 DHCP 分配的 DNS)
    • 🔍 确认 IPv6 已被禁用(IPv6 DNS 查询可能绕过 VPN)
    • 🔍 在 网络 → DHCP/DNS → 常规设置 中,勾选 "忽略解析文件"(Ignore resolve file),防止路由器使用 ISP 提供的 DNS

    ❓ Kill Switch 配置后完全无法上网

    • ✅ 这是正常行为——说明 Kill Switch 正在工作
    • 🔍 检查 WireGuard 接口是否启动(网络 → 接口 → wginterface 状态是否为"已连接")
    • 🔍 确认 Mullvad 配置中的私钥、公钥、Endpoint 是否正确
    • 🔍 尝试重启 WireGuard 接口(ifdown wginterface && ifup wginterface

    ❓ 某些网站/服务无法访问

    • 🔍 某些网站会封锁已知的 VPN IP 地址,尝试切换到其他 Mullvad 服务器
    • 🔍 如果需要访问不支持 VPN 的服务,使用 PBR 策略路由将特定域名或设备配置为直连
    • 🔍 检查 AdGuard Home / Mullvad DNS 拦截是否误杀了合法域名

    ❓ privacy-first-network 项目提供了专门的故障排查文档

    详细的故障排查指南可在项目仓库中找到:TROUBLESHOOTING.md


    延伸阅读与参考资源

    📚 官方文档

    🔧 开源项目

    📰 深度文章

    🗨️ 社区讨论

    Brave 回复 2 weeks ago 1 成員 · 0 回复
  • 0 回复

歡迎留言回复交流。

Log in to reply.

讨论開始
00 回复 2018 年 6 月
現在