diff --git a/README.md b/README.md index abe3055..0c7945a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,8 @@ | **qBittorrent** | `192.168.1.200` (macvlan) | PT 下载,独立 IP | | **Windows** | `192.168.1.177` | 内网办公,SSH | | **Spark** | `192.168.1.166` | Ubuntu 主机,本地 TUN 代理 | +| **iPhone** | WG `10.0.0.3` | WireGuard 客户端,远程访问内网 | +| **Mac** | WG `10.0.0.4` | WireGuard 客户端,远程访问内网 | --- @@ -544,6 +546,156 @@ nc -zv salmonstill.cn 51413 | `xray-北京vps-config.json` | 北京VPS `/usr/local/etc/xray/config.json` | Xray 入站+路由(含 proxy_from_lan + external_qbit) | | `xray-旁路由-config.json` | 旁路由 `/etc/xray/config.json` | Xray bridge + to_qbit(51413) + socks-lan(1080) → to_beijing_direct | +## WireGuard 内网穿透(iPhone / Mac 远程访问内网) + +复用已有的 WireGuard 隧道,让外部 iPhone / Mac 通过北京 VPS 中继,访问家里整个 `192.168.1.0/24` 内网的**任意端口**(无需逐个配置端口规则)。 + +### 架构 + +``` +iPhone (WireGuard App, 10.0.0.3) +Mac (WireGuard, 10.0.0.4) + ↓ WG 隧道 (UDP 51820) +北京VPS 49.232.242.90 (wg0, 10.0.0.1/24) + ↓ 转发 (iptables FORWARD ACCEPT) +旁路由 192.168.1.199 (10.0.0.2, penetration zone) + ↓ 转发 + SNAT (→ 192.168.1.199) +整个 192.168.1.0/24 任意端口可达 (如 Spark 192.168.1.166:8081 Expo dev server) +``` + +### 虚拟网段 IP 分配 + +| 设备 | WG IP | 说明 | +|---|---|---| +| 北京 VPS | `10.0.0.1/24` | WG 服务端,监听 `:51820` | +| 旁路由 | `10.0.0.2/24` | 子网代理节点,进 LAN | +| iPhone | `10.0.0.3/32` | WireGuard App | +| Mac | `10.0.0.4/32` | WireGuard | + +### 北京 VPS 配置 (`/etc/wireguard/wg0.conf`) + +```ini +[Interface] +Address = 10.0.0.1/24 +ListenPort = 51820 +PrivateKey = <北京VPS私钥> +MTU = 1420 + +PostUp = iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE +PostUp = iptables -A FORWARD -i wg0 -j ACCEPT +PostUp = iptables -A FORWARD -o wg0 -j ACCEPT +PostDown = iptables -t nat -D POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE +PostDown = iptables -D FORWARD -i wg0 -j ACCEPT +PostDown = iptables -D FORWARD -o wg0 -j ACCEPT + +[Peer] +# 旁路由(子网代理,带 192.168.1.0/24) +PublicKey = <旁路由公钥> +AllowedIPs = 10.0.0.2/32, 192.168.1.0/24 +PersistentKeepalive = 25 + +[Peer] +# iPhone +PublicKey = +AllowedIPs = 10.0.0.3/32 +PersistentKeepalive = 25 + +[Peer] +# Mac +PublicKey = +AllowedIPs = 10.0.0.4/32 +PersistentKeepalive = 25 +``` + +> ⚠️ **关键坑:iptables FORWARD policy DROP**。VPS 装过 Docker 后,`iptables` 的 FORWARD 链默认策略会变成 `DROP`,导致客户端流量穿透 VPS 转发时被丢弃(症状:`ping 10.0.0.1` 通、`ping 10.0.0.2` 不通)。必须在 PostUp 加 `-i wg0` / `-o wg0` 两条 ACCEPT。 +> 查看规则用 `iptables -L FORWARD -n -v`(**必须带 `-v`**,否则不显示 In/Out 接口列,`grep wg0` 会以为规则不存在)。 + +### 旁路由配置(ImmortalWrt LuCI) + +#### 1. 新建 `penetration` zone + +网络 → 防火墙 → General Settings → 添加: + +| 字段 | 值 | +|---|---| +| Name | `penetration` | +| Input | `accept` | +| Output | `accept` | +| Forward | `accept` | +| Covered networks | `WireGuard` | +| Allow forward to destination zones | `lan` | + +同时把 WG 接口从 `wan` zone 的 **Covered networks 取消勾选**(一个接口只能属于一个 zone)。 + +#### 2. 新增通用 SNAT 规则(关键) + +网络 → 防火墙 → NAT 规则 → 添加: + +| 字段 | 值 | +|---|---| +| Name | `penetration-snat` | +| 地址族限制 | 仅 IPv4 | +| 协议 | Any | +| 出站区域 | `lan` | +| 源地址 | `10.0.0.0/24` | +| 目标地址 | any | +| 操作 | `SNAT` → 重写 IP `192.168.1.199` | + +生成规则:`ip saddr 10.0.0.0/24 ... snat ip to 192.168.1.199` + +> ⚠️ **关键坑:penetration zone 勾 masq 无效**。ImmortalWrt (fw4) 的 masquerade 按"出接口"触发,隧道流量转发进 LAN 时出接口是 `br-lan`(属于 lan zone),不会进 `srcnat_penetration`。必须显式加 SNAT 规则,否则 166 等设备的回包发给主路由(192.168.1.1)而丢失(症状:`ping 10.0.0.2` 通、`ping 192.168.1.166` 不通)。 + +#### 3. Minecraft 端口转发联动 + +因为 WG 接口从 `wan` 移到了 `penetration`,Minecraft 那条 `Minecraft-udp` 端口转发的 **Source zone 要从 `wan` 改成 `penetration`**(玩家流量实际也走 WG 隧道进来),否则 Minecraft 会断。 + +### 客户端配置 + +#### iPhone(海外区 App Store 官方 WireGuard) + +``` +[Interface] +PrivateKey = +Address = 10.0.0.3/32 +DNS = 223.5.5.5 + +[Peer] +PublicKey = <北京VPS服务端公钥> +Endpoint = 49.232.242.90:51820 +AllowedIPs = 10.0.0.0/24, 192.168.1.0/24 +PersistentKeepalive = 25 +``` + +#### Mac + +同上,`Address = 10.0.0.4/32`,PrivateKey 换成 Mac 的。 + +> AllowedIPs 只含虚拟网段和内网网段 → split tunnel,仅内网流量走隧道,不影响正常上网。 + +### 验证命令 + +```bash +# 北京 VPS 上:确认 3 个 peer 都有握手 +wg show + +# 客户端设备上:三层诊断(定位故障层级) +ping -c 3 10.0.0.1 # ① 隧道到 VPS —— 通说明客户端配置对 +ping -c 3 10.0.0.2 # ② 隧道到旁路由 —— 通说明 VPS 转发对 +ping -c 3 192.168.1.166 # ③ 进内网 —— 通说明旁路由转发+SNAT 对 + +# 旁路由上确认 SNAT 规则 +nft list ruleset | grep -iE "penetration-snat|10.0.0.0/24" +``` + +### 排障对照表 + +| 现象 | 原因 | 修复 | +|---|---|---| +| `ping 10.0.0.1` 通、`ping 10.0.0.2` 不通 | VPS iptables FORWARD policy DROP | wg0.conf PostUp 加 `-i wg0` / `-o wg0` ACCEPT | +| `ping 10.0.0.2` 通、`ping 192.168.1.166` 不通 | 旁路由缺通用 SNAT | 新增 `penetration-snat`(SNAT → 192.168.1.199) | +| 旁路由自己 ping 166 通,但客户端不通 | 同上 | 同上 | +| `iptables -L FORWARD -n \| grep wg0` 为空 | 没带 `-v`,接口列不显示 | 用 `iptables -L FORWARD -n -v` | + ## Minecraft UDP 转发 ### 架构 diff --git a/xray-北京vps-config.json b/xray-北京vps-config.json index a51acc6..2ede7ad 100644 --- a/xray-北京vps-config.json +++ b/xray-北京vps-config.json @@ -268,6 +268,17 @@ "port": 38665, "network": "tcp" } + }, + { + "tag": "external_expo", + "listen": "0.0.0.0", + "port": 38666, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 38666, + "network": "tcp" + } } ], "outbounds": [ @@ -391,6 +402,13 @@ ], "outboundTag": "portal" }, + { + "type": "field", + "inboundTag": [ + "external_expo" + ], + "outboundTag": "portal" + }, { "type": "field", "inboundTag": [ diff --git a/xray-旁路由-config.json b/xray-旁路由-config.json index 481cab8..4f9acaa 100644 --- a/xray-旁路由-config.json +++ b/xray-旁路由-config.json @@ -84,6 +84,13 @@ "redirect": "192.168.1.177:8501" } }, + { + "tag": "to_expo", + "protocol": "freedom", + "settings": { + "redirect": "192.168.1.166:38666" + } + }, { "tag": "to_3000", "protocol": "freedom", @@ -463,6 +470,14 @@ "port": "38653", "outboundTag": "to_nas" }, + { + "type": "field", + "inboundTag": [ + "bridge" + ], + "port": "38666", + "outboundTag": "to_expo" + }, { "type": "field", "inboundTag": [