前言 我主业是安卓开发,但不务正业的我又在折腾别的了。
之前写过一篇关于 NX54 如何配置 iptables 以开放指定 IP 的 IPv6 防火墙规则。最近又把手上的一块 14 年的废弃 ARM 开发板翻出来,挂了块硬盘,让我在任意设备上都能访问家里的网络。要说这块板子,官方系统只到ubuntu 2014,连python3都没法装,之前折腾过armbian,但kernel有问题,usb不工作。最近看论坛去年有人升级了内核了,赶紧换一下系统。
过年期间家属送了一台 Mac mini(现在百亿补贴入手价 2899,血亏 600),于是我又折腾了一下,把整个网络重新整理了一遍。熬了几个夜晚和午休时间,总算弄好了,这里记录一下过程中遇到的问题和解决方案。
之前我做了什么
桥接路由,这样可以直接获取公网ipv6地址,供自己在外边连接。
关防火墙。大多数路由器都有ipv6防火墙,像我的NX54就是基于ip6tables的配置,需要关掉。我是只关掉了我的linux的ip。我使用了脚本自动更新,脚本流程如下: 1 linux定时任务 -> python脚本 -> 获取ipv6 -> 发现变化 -> 更新nx54防火墙 -> 更新cloudflare dns AAAA(最早做了一版发email的,后来改ddns了)
不得不说,cloudflare真的是互联网之光,域名便宜,免费加速,还提供Pages,Workers。
linux关闭ssh密码访问,把常用的设备公钥加进去。
经过上面的配置,外网只能通过IPV6访问到linux,利用SSH建立隧道,还能连接家里的电脑,方便又安全。
Mac mini准备 能源
✅ 防止进入睡眠
✅ 唤醒以供网络访问
❌ 如有可能,将硬盘置于睡眠状态
✅ 断电自动重启
远程桌面 设置 -> 通用 -> 共享 -> 屏幕共享 & 远程登录 & 文件共享 mac支持屏幕分享,但是是通过vnc://协议访问的,如果要通过ARD,那还需要花几百块买软件。平替方案:走ssh通道
1 ssh -L 5900:192.168.x.x:5900 username@linux_ipv6
command + spcae 屏幕分享 输入localhost就能连了,如此一来就是加密的。本来我是准备用wireguard去连接的,但一直没从10.0.0.0穿透到192.168.x.x,不好直接用ssh隧道更方便。
打开自动登录
这一项非常关键,不然重启后就卡在登录界面,需要手动输入密码。
服务开机启动 适用一些需要开机启动的服务,和linux不一样,使用launchctl管理。注意脚本不要放在Documents,没权限访问,自己在~下新建一个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd" > <plist version ="1.0" > <dict > <key > Label</key > <string > yourshell.startup</string > <key > ProgramArguments</key > <array > <string > /path/to/yourshell.sh</string > </array > <key > RunAtLoad</key > <true /> <key > KeepAlive</key > <true /> <key > StandardOutPath</key > <string > /Dev/null</string > <key > StandardErrorPath</key > <string > /Dev/null</string > </dict > </plist >
1 2 3 4 # 停止 sudo launchctl bootout gui/$(id -u) ~/Library/LaunchAgents/yourshell.startup.plist # 加载 sudo launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/yourshell.startup.plist
打通转发(linux -> Mac mini🪜) 配置 我使用 Linux 网关配合 MosDNS 进行 DNS 分流:直连流量
不处理,访问内部网站
解析虚拟ip,然后通过 iptables 进行路由转发。由于 Mac 不支持 TPROXY,所以我在 Mac 上运行 SOCKS 代理,然后在 Linux 上使用 TPROXY 转发连接到 SOCKS。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 # 修改iptables iptables -t mangle -N MYWAY 2>/dev/null iptables -t mangle -F MYWAY iptables -t mangle -A MYWAY -d 198.18.0.0/16 -p tcp -j TPROXY --on-port <tproxy_port> --tproxy-mark 1 iptables -t mangle -A MYWAY -d 198.18.0.0/16 -p udp -j TPROXY --on-port <tproxy_port> --tproxy-mark 1 iptables -t mangle -D PREROUTING -j MYWAY 2>/dev/null iptables -t mangle -A PREROUTING -j MYWAY # 开启NAT转发 echo "net.ipv4.ip_forward = 1" | sudo tee -a /etc/sysctl.conf echo "net.ipv4.conf.all.route_localnet=1" | sudo tee -a /etc/sysctl.conf sysctl -p # nat转换 注意这里区分你的网络接口 iptables -t nat -A POSTROUTING -o end0 -j MASQUERADE # 路由 注意这两条也要保存到rc.local,不然重启后就失效了。 ip rule add fwmark 1 lookup 100 ip route add local 0 0.0. 0/0 dev lo table 100 # 保存 iptables配置 sudo iptables-save | sudo tee -a /etc/iptables/rules.v4 sudo nano /etc/rc.local # 添加 iptables-restore < /etc/iptables/rules.v4 # 添加 ip rule add fwmark 1 lookup 100 # 添加 ip route add local 0 0.0. 0/0 dev lo table 100 # 保存 # 确保有执行权限 sudo chmod +x /etc/rc.local
最终实现的效果如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 📱 手机(或其他设备) │ ├── 发起请求(例如:访问 https://www.example.com) │ ├── 📡 DNS 请求发送至 ➜ 192.168.x.115(网关设备上的 MosDNS) │ │ └─ MosDNS 分流: │ ├─ 直连域名 → 直连(返回真实 IP) │ └─ 内部域名 → 发给 113 上的 DNS服务 │ │ └─ DNS服务 返回 fake-ip(如 198.18.0.x) │ └── 手机收到 fake-ip(例如 198.18.0.33)后发起连接 ↓ 发出 TCP 请求目标:198.18.0.33:443 ↓ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🛡️ 网关设备(115)iptables 检测 │ ├── mangle 表匹配到 fake-ip 段(198.18.0.0/16) │ ├── TPROXY 重定向流量 → 本地转换服务 │ ├── 路由策略: │ └─ fwmark=1 → local via lo(回送至本地转换服务 │ └── 本地转换服务 接收到TPROXY流量 ↓ 转发至 代理服务(113)的 Socks 服务 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 🧱 代理服务(113)处理流量 │ └── 访问目标网站(如 example.com),建立 TLS 连接 ↓ 返回响应 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⬆️ 回程流量返回手机,访问完成
踩过的坑 有些细节不说了,我还有份详细的笔记,但不方便暴露。这里走了点弯路,踩坑总结:
tproxy to socks 本来尝试用工具redsocks,AI说不支持udp,放弃了。改用另一款,性能稍微差点,但支持的协议多,配置也简单。
一定要配echo "net.ipv4.conf.all.route_localnet=1" | sudo tee -a /etc/sysctl.conf
这一项才允许路由lo,我本身对linux的网络熟练度低,就因为这个配置,搞了好久,AI也一直没讲,后面一点点查到的。
起初直接使用 TUN 实现,毕竟是个虚拟网卡,招呼了所有流量,后来觉得不够优雅,最终改成 DNS分流 + TPROXY + SOCKS,感谢一位哥们跟我交流后确定了方向。
为什么非要建在mac上,因为开发板性能太差,虽然还能撑,但能少安服务就少安吧,况且在新mac上加一个这个服务跑,完全不受影响。我在linux上面还有个Alist(板子原生支持SATA,就接了块电脑硬盘)。
linux上有个systemd-resolved,记得disable,占了53端口。当然也可以不做,需要设备上指定DNS端口。
居然是冰的 Mac mini跑好几天了,摸一摸表面居然是冰的。家里养猫,PDD 26买了个3D打印的底座,不是15块那个,不是一个做工。