V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要把任何和邀请码有关的内容发到 NAS 节点。

邀请码相关的内容请使用 /go/in 节点。

如果没有发送到 /go/in,那么会被移动到 /go/pointless 同时账号会被降权。如果持续触发这样的移动,会导致账号被禁用。
Autonomous
V2EX  ›  NAS

分享一个群晖部署 WireGuard, iPhone 用 Loon 连接的实例

  •  
  •   Autonomous · 52 天前 · 2868 次点击
    这是一个创建于 52 天前的主题,其中的信息可能已经有所发展或是发生改变。

    写在前面

    接上一个帖子([https://www.v2ex.com/t/1073068]),请教了大家如何减少暴漏 NAS 的端口,建议比较多的是使用 WireGuard ,遂尝试部署了下,踩了好多坑,终于调通,跟大家分享一下经历

    我的设备情况:

    NAS:群晖 1821+ ,DSM 7.2.1-69057 Update 5 ,内网 IP 是 192.168.1.2; WireGuard 服务端:wg-easy/wg-easy v14.0.0 ; 手机:iPhone 15 ,iOS 17.6 (21G80); WireGuard 客户端:Loon 3.2.2 (749); 有动态公网 IPv4 地址,有一个域名 example.com,通过 DDNS 把公网 IPv4 地址绑定到云服务商,NAS 上安装了泛域名证书。

    在这个实例中,域名、端口号、密码等均为虚构,请根据你的需要修改。


    一、在 NAS 安装部署 WireGuard

    1. 解决内核版本过低问题

    WireGuard 要求 Linux 内核版本高于 5.6 ,但是群晖不满足这个要求,在 NAS 终端执行 uname -r 后看到 4.4.302+

    办法是安装第三方套件源,套件中心 → 设置 → 添加: https://spk7.imnks.com/

    进入社群,搜索 WireGuard 下载,在 NAS 终端执行 sudo sed -i 's/package/root/g' /var/packages/WireGuard/conf/privilege 修复权限问题。

    2. 通过 Container Manager 构建 WireGuardEasy

    2.1. 新建目录 docker/WireGuardEasydocker/WireGuardEasy/config; 2.2. 新建 compose.yml 文件,上传到 docker/WireGuardEasy,内容如下:

    services:
      wg-easy:
        environment:
          - LANG=chs
          - WG_HOST=example.com		# NAS 的域名
          - PASSWORD_HASH=$$2y$$10$$hBCoykrB95WSzuV4fafBzOHWKu9sbyVa34GJr8VV5R/pIelfEMYyG		# 哈希后的密码,下面有介绍怎么生成
          - PORT=51821		# WireGuardEasy 的后台管理端口,TCP 协议的
          - WG_PORT=51820		#WireGuardEasy 的连接端口,UDP 协议的,需要映射暴露到外网。
          - WG_DEFAULT_ADDRESS=10.0.0.1
          - WG_ALLOWED_IPS=10.0.0.0/24,192.168.1.0/24
          - WG_PERSISTENT_KEEPALIVE=25
          - UI_TRAFFIC_STATS=true
          - MAX_AGE=30
          - UI_ENABLE_SORT_CLIENTS=true
    
        image: ghcr.io/wg-easy/wg-easy
        container_name: wg-easy
        volumes:
          - /volume1/docker/WireGuardEasy/config:/etc/wireguard
        ports:
          - "51820:51820/udp"
          - "51821:51821/tcp"
        restart: unless-stopped
        cap_add:
          - NET_ADMIN
          - SYS_MODULE
        sysctls:
          - net.ipv4.ip_forward=1
          - net.ipv4.conf.all.src_valid_mark=1
          
        network_mode: "bridge"
    

    2.2. 用 Container Manager 构建项目; 2.3. 修改后台密码:在 NAS 终端执行 docker run -it ghcr.io/wg-easy/wg-easy wgpw YOUR_PASSWORD,得到 PASSWORD_HASH='$2a$12$ptdssPxwS2vKlXCPcYP3juENfkuhJPGamBQM7utsUJ8Gv7LP8tjm6' 将单引号去除,在每一个 $ 前再添加一个 $,加工成 $$2a$$12$$ptdssPxwS2vKlXCPcYP3juENfkuhJPGamBQM7utsUJ8Gv7LP8tjm6 填入 compose.yml 文件的环境变量 PASSWORD_HASH 中,清除项目,再构建项目。

    3. 对后台管理界面配置反向代理

    因为本人有强迫症,不喜欢浏览器提示 HTTP 不安全,所以都会给后台管理界面套一个 HTTPS 反代,通过域名访问,消除安全警告。

    • 描述:WireGuardEasy
    • 来源协议:HTTPS
    • 来源主机名:wg.example.com
    • 来源端口:443
    • 启用 HSTS
    • 目的地协议:HTTP
    • 目的地主机名:localhost
    • 目的地端口:51821
    • 如果设置了访问控制文件,且允许远程登后台的话,需要放行 172.16.0.0/12,这是因为容器的网络模式为 bridge10.0.0.0/24 出容器后地址会被 NAT 成 172.16.0.0/12 ,本质上是容器在访问 NAS 的资源。

    4. 配置防火墙

    网关路由器设置 UDP 51820 端口转发至群晖,群晖防火墙放行 UDP 51820 端口,群晖防火墙无需再对 10.0.0.0/24172.16.0.0/12 的来源地址放行,因为容器已经在防火墙之后了。

    5. 后台管理

    5.1. 访问 https://wg.example.com,密码 YOUR_PASSWORD ,进入管理后台; 5.2. 新建客户端,重要!!把 IP 改为 10.0.0.2,不得占用 10.0.0.1 ; 5.3. 显示二维码,让手机扫码。


    二、在手机连接 WireGuard

    我使用的是 Loon ,这是一款功能强大的网络代理工具,通过策略组、分流规则、Wi-Fi 规则可以实现内外网自动切换,日常使用基本无感。

    1. 添加本地节点

    用 Loon 添加本地节点,扫码添加,名称为 NAS_WireGuard,删除默认添加的 1.1.1.1 DNS 。

    2. 设置 DNS 映射

    因为本人有强迫症,不喜欢浏览器提示 HTTP 不安全,所以一律通过域名访问内网资源,消除安全警告,所以就需要配置本地 DNS ,这里使用 Loon 的 DNS 映射功能。

    DNS 映射规则有顺序,从上到下匹配,要确保 ssid 那条在最顶。

    ssid:ChinaNet-Home = server:192.168.1.1		# 当手机连入家里的 Wi-Fi:ChinaNet-Home 时,将 DNS 服务器设为路由器的 IP ,由路由器负责把 `example.com` 解析到 NAS 的内网 IP
    critical-service.example.com = 192.168.1.2			# 将 critical-service 服务的主机名指向 NAS 的内网 IP
    wg.example.com = 192.168.1.2			## 将 WireGuard 管理后台的主机名指向 NAS 的内网 IP
    

    第一条映射规则的作用是,当手机在家时,把 NAS 的域名解析到内网 IP ; 后面的规则作用是,当手机不在家时,将几个关键服务的主机名解析到内网 IP ,配合 WireGuard 隧道访问; 当手机不在家时,非关键服务的主机名还是通过云服务商解析,通过传统的 DDNS 访问,不走隧道。

    3. 添加策略组

    服务器 = ssid,default=NAS_WireGuard,cellular=NAS_WireGuard,"ChinaNet-Home"=DIRECT,url = http://www.gstatic.com/generate_204
    

    添加一个名为 服务器 的策略组。当手机连入家里的 Wi-Fi:ChinaNet-Home 时,访问 NAS 一律直连,当手机用其他 Wi-Fi 或蜂窝网络时,就走本地节点 NAS_WireGuard,隧道访问,url 是测延迟的链接。

    4. 设置分流规则

    AND,((OR,((DEST-PORT,1234),(DEST-PORT,443))),(DOMAIN-SUFFIX,example.com)),服务器
    AND,((OR,((DEST-PORT,5000),(DEST-PORT,5001))),(DOMAIN-SUFFIX,example.com)),DIRECT
    

    设置两个嵌套的分流规则: 第一条规则:当访问 wg.example.com:443critical-service.example.com:1234 时,交给 服务器 策略组进一步处理,用来保护关键服务配合 WireGuard 隧道访问; 第二条规则:当访问 file.example.com:5000music.example.com:5001 时,通过传统的 DDNS 访问,不走隧道,需要防火墙放行这两个端口。

    5. 取消默认的绕过路由 (bypass-tun) 和绕过代理 (skip-proxy)

    在 bypass-tun 和 skip-proxy 中,要删除 example.com192.168.0.0/16192.168.1.0/24,确保这些域名和内网地址通过 Loon 的处理


    最后的效果

    只要手机的 Loon 一直开启,无论身在何处,都可以访问 wg.example.com:443critical-service.example.com:1234 这两个关键服务,端口在公网不可见,没有 DNS 解析问题; file.example.com:5000music.example.com:5001 这两个非关键服务的端口在公网仍然可见,满足资源共享的需求。

    唯一美中不足的是,当手机从内网切到外网时,做不到无缝衔接,需要等待几秒钟才能建立 WireGuard 连接,甚至要手动关闭 Loon 再开启,有无优化的办法?

    36 条回复    2024-11-02 07:14:30 +08:00
    Autonomous
        1
    Autonomous  
    OP
       52 天前
    淦,怎么排版成这个鬼样子,自己都看不下去了
    Jhma
        2
    Jhma  
       52 天前
    有二次认证的 VPN 才比较安全,特别是 PC 上的各类 vpn 配置文件包括 wg 别人拿到也能连接,像这位老兄的二次认证还可以,https://www.bilibili.com/video/BV1YDWpe6EQg
    Autonomous
        3
    Autonomous  
    OP
       52 天前 via iPhone
    @Jhma 好吧,看来我又要折腾一阵子了
    Ja22
        4
    Ja22  
       52 天前 via iPhone
    太麻烦了,不如直接挂 ss ,[看我写的]( https://blog.liqiye.com/posts/76168112/)
    MYDB
        5
    MYDB  
       52 天前
    有公网,应该 nas 上起个 xui docker 更好
    Autonomous
        6
    Autonomous  
    OP
       52 天前 via iPhone
    @Ja22 我试过 ss ,连接后延迟大于 wireguard ,而且不知道如何访问内网资源,不清楚是不是容器限制的原因
    Autonomous
        7
    Autonomous  
    OP
       52 天前 via iPhone
    @MYDB 搜了一下,x-ui 确实强大,但是它 3 年没更新,类似的项目还有 3x-ui 不知道怎么样
    需要改 nginx ,但是群晖不好改这个,图形界面能改 nginx 的地方太少
    SenLief
        8
    SenLief  
       52 天前
    用公网的情况下我直接用的是的 socks5
    bigshawn
        9
    bigshawn  
       52 天前
    我是直接 docker 跑 ss ,1 分钟不到就部署完成了。
    Autonomous
        10
    Autonomous  
    OP
       52 天前
    @SenLief
    @bigshawn
    我用 docker 跑 ss 也能通,但是无法通过 ip 访问内网,不知道要配置什么东西
    Ja22
        11
    Ja22  
       52 天前 via iPhone
    @Autonomous 看我博客里的内容,你要去删 xray 配置文件,xui 只是别人做了个 gui ,你可以直接去用 xray
    Autonomous
        12
    Autonomous  
    OP
       51 天前
    @Ja22 谢谢,我已经调通了,这个 3x-ui 确实强大,支持多种协议,界面友好,而且还在积极开发。

    之前弄的 WireGuard 也不是完全没有用,至少让我了解分流规则、策略组
    l4ever
        13
    l4ever  
       51 天前
    wg 是 udp ,国内运营商都限速的,特别是跨省 udp 流量。不建议你折腾。
    ljsh093
        14
    ljsh093  
       51 天前 via iPhone
    Wg 不会被限速阻断吗,我的 hk 小鸡半天被断
    Autonomous
        15
    Autonomous  
    OP
       51 天前 via iPhone
    @l4ever
    @ljsh093 确实有阻断,我已经换到 trojan 了
    Jays
        16
    Jays  
       51 天前 via Android
    @Autonomous 如何实现的访问 内网其他主机或设备呢?
    Autonomous
        17
    Autonomous  
    OP
       51 天前 via iPhone
    @Jays wireguard 部署好后可以访问服务器本身的资源,但是内网其他设备不可达,猜测是容器 bridge 模式的限制,不过我不需要访问其他设备,就没有再管这些。你可以考虑换成 host 模式运行,理论上更好
    nt0p
        18
    nt0p  
       50 天前 via iPhone
    “WireGuard 要求 Linux 内核版本高于 5.6”,并不对。wg 国内阻断严重。
    Jays
        19
    Jays  
       50 天前 via Android
    @Autonomous 我是说 trojan 或 ss 。wg 我知道是可以
    Autonomous
        20
    Autonomous  
    OP
       49 天前 via iPhone
    @Jays 我今天调通了,可以访问内网其他设备,需要设置路由规则,对 192.168.1.0/24 走 direct
    dcncy
        21
    dcncy  
       49 天前 via iPhone
    @Ja22 老哥,我在内网用 x-ui 搭建了 vmess 节点,我在 ios 上使用 QX 并配置了该节点,通过节点可以访问互联网服务,说明节点通了。

    我配置了如下规则:
    IP-CIDR,192.168.1.0/24, 家庭节点

    但是我在手机浏览器上无法访问内网服务 http://192.168.1.101:36580 ,为啥不能通呢?还需要配置什么?还是我的理解有问题啊?
    Autonomous
        22
    Autonomous  
    OP
       48 天前 via iPhone
    @dcncy 嗯,如果用 X-UI ,搭好之后只能访问到服务器本身,无法访问家里局域网其他设备。你要在服务端的 X-UI 配一条出站的路由规则 192.168.1.0/24 ,direct
    Autonomous
        23
    Autonomous  
    OP
       48 天前 via iPhone
    @Autonomous 我用 3X-UI ,有一个配置选项是“禁止访问私网 IP”,这个也得关掉
    dcncy
        24
    dcncy  
       48 天前 via iPhone
    @Autonomous 牛,真的可以啦。
    dcncy
        25
    dcncy  
       48 天前 via iPhone
    @Autonomous 谢谢🙏
    Misyo
        26
    Misyo  
       48 天前   ❤️ 1
    Loon 的 WG 回家看视频有断流 BUG ,很久了都没有修复。
    dcncy
        27
    dcncy  
       48 天前 via iPhone
    @Autonomous 老哥,我还需要您的帮助。
    我在局域网内家庭服务器( 192.168.1.101 )上启了一个 nginx ,反向代理了一些服务。
    我在公网 ios 或者 mac 上使用 qx 无法通过域名访问这些服务,需要做哪些配置吗?
    我已经在 qx 设置:host-suffix,example.com,家庭节点
    我需要在 xui 的 xray 设置啥内容能让域名解析到 192.168.1.101 服务上呢?
    dcncy
        28
    dcncy  
       48 天前
    @dcncy #27 请忽略该问题,已经解决了。原来是家庭服务上的 surge 捣鬼导致的。
    GivingX
        29
    GivingX  
       48 天前
    @dcncy #28 大佬能不能截图下,出战规则的配置
    Autonomous
        30
    Autonomous  
    OP
       48 天前 via iPhone
    @dcncy 我不太会用服务端的解析,所以用笨方法,在客户端配置本地 DNS ,iPhone 就用 Loon 来做,Linux 电脑就改 hosts 文件
    dcncy
        31
    dcncy  
       48 天前 via iPhone
    @GivingX 你说的是 x-ui 面板的 xray 设置不?

    {
    "api": {
    "services": [
    "HandlerService",
    "LoggerService",
    "StatsService"
    ],
    "tag": "api"
    },
    "log": {
    "access": "/log/access.log",
    "error": "/log/error.log",
    "loglevel": "info",
    "dnsLog": true,
    "maskAddress": ""
    },
    "inbounds": [
    {
    "listen": "127.0.0.1",
    "port": 62789,
    "protocol": "dokodemo-door",
    "settings": {
    "address": "127.0.0.1"
    },
    "tag": "api"
    }
    ],
    "outbounds": [
    {
    "protocol": "freedom",
    "tag": "direct",
    "settings": {}
    },
    {
    "protocol": "blackhole",
    "settings": {},
    "tag": "blocked"
    }
    ],
    "policy": {
    "system": {
    "statsInboundDownlink": true,
    "statsInboundUplink": true
    }
    },
    "routing": {
    "rules": [
    {
    "ip": [
    "192.168.1.0/24"
    ],
    "outboundTag": "direct",
    "type": "field"
    },
    {
    "inboundTag": [
    "api"
    ],
    "outboundTag": "api",
    "type": "field"
    },
    {
    "ip": [
    "geoip:private"
    ],
    "outboundTag": "blocked",
    "type": "field"
    },
    {
    "outboundTag": "blocked",
    "protocol": [
    "bittorrent"
    ],
    "type": "field"
    }
    ]
    },
    "stats": {}
    }
    dcncy
        32
    dcncy  
       48 天前 via iPhone
    @GivingX log 模块可以不要,我为了查问题配置的。

    "log": {
    "access": "/log/access.log",
    "error": "/log/error.log",
    "loglevel": "info",
    "dnsLog": true,
    "maskAddress": ""
    },

    其实就是默认的配置加了一个 rule:

    {
    "ip": [
    "192.168.1.0/24"
    ],
    "outboundTag": "direct",
    "type": "field"
    },
    GivingX
        33
    GivingX  
       47 天前 via Android
    谢谢老哥
    GivingX
        34
    GivingX  
       47 天前 via Android
    Free3
        35
    Free3  
       5 天前
    所以前提 还是得必须要有一个公网 IP 是吧?
    Autonomous
        36
    Autonomous  
    OP
       5 天前 via iPhone   ❤️ 1
    @Free3 对的,ipv6 就可以,ddns 绑定到域名
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3400 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 11:15 · PVG 19:15 · LAX 03:15 · JFK 06:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.