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

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

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

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

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

    写在前面

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

    之前弄的 WireGuard 也不是完全没有用,至少让我了解分流规则、策略组
    l4ever
        13
    l4ever  
       59 天前
    wg 是 udp ,国内运营商都限速的,特别是跨省 udp 流量。不建议你折腾。
    ljsh093
        14
    ljsh093  
       59 天前 via iPhone
    Wg 不会被限速阻断吗,我的 hk 小鸡半天被断
    Autonomous
        15
    Autonomous  
    OP
       59 天前 via iPhone
    @l4ever
    @ljsh093 确实有阻断,我已经换到 trojan 了
    Jays
        16
    Jays  
       59 天前 via Android
    @Autonomous 如何实现的访问 内网其他主机或设备呢?
    Autonomous
        17
    Autonomous  
    OP
       59 天前 via iPhone
    @Jays wireguard 部署好后可以访问服务器本身的资源,但是内网其他设备不可达,猜测是容器 bridge 模式的限制,不过我不需要访问其他设备,就没有再管这些。你可以考虑换成 host 模式运行,理论上更好
    nt0p
        18
    nt0p  
       58 天前 via iPhone
    “WireGuard 要求 Linux 内核版本高于 5.6”,并不对。wg 国内阻断严重。
    Jays
        19
    Jays  
       57 天前 via Android
    @Autonomous 我是说 trojan 或 ss 。wg 我知道是可以
    Autonomous
        20
    Autonomous  
    OP
       57 天前 via iPhone
    @Jays 我今天调通了,可以访问内网其他设备,需要设置路由规则,对 192.168.1.0/24 走 direct
    dcncy
        21
    dcncy  
       56 天前 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
       56 天前 via iPhone
    @dcncy 嗯,如果用 X-UI ,搭好之后只能访问到服务器本身,无法访问家里局域网其他设备。你要在服务端的 X-UI 配一条出站的路由规则 192.168.1.0/24 ,direct
    Autonomous
        23
    Autonomous  
    OP
       56 天前 via iPhone
    @Autonomous 我用 3X-UI ,有一个配置选项是“禁止访问私网 IP”,这个也得关掉
    dcncy
        24
    dcncy  
       56 天前 via iPhone
    @Autonomous 牛,真的可以啦。
    dcncy
        25
    dcncy  
       56 天前 via iPhone
    @Autonomous 谢谢🙏
    Misyo
        26
    Misyo  
       56 天前   ❤️ 1
    Loon 的 WG 回家看视频有断流 BUG ,很久了都没有修复。
    dcncy
        27
    dcncy  
       56 天前 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  
       55 天前
    @dcncy #27 请忽略该问题,已经解决了。原来是家庭服务上的 surge 捣鬼导致的。
    GivingX
        29
    GivingX  
       55 天前
    @dcncy #28 大佬能不能截图下,出战规则的配置
    Autonomous
        30
    Autonomous  
    OP
       55 天前 via iPhone
    @dcncy 我不太会用服务端的解析,所以用笨方法,在客户端配置本地 DNS ,iPhone 就用 Loon 来做,Linux 电脑就改 hosts 文件
    dcncy
        31
    dcncy  
       55 天前 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  
       55 天前 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  
       55 天前 via Android
    谢谢老哥
    GivingX
        34
    GivingX  
       55 天前 via Android
    Free3
        35
    Free3  
       13 天前
    所以前提 还是得必须要有一个公网 IP 是吧?
    Autonomous
        36
    Autonomous  
    OP
       13 天前 via iPhone   ❤️ 1
    @Free3 对的,ipv6 就可以,ddns 绑定到域名
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4450 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:04 · PVG 12:04 · LAX 20:04 · JFK 23:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.