分类目录归档:享受过程

iOS Surge 加载 wireguard 配置打通 tailscale

Wireguard 是新一代的轻量级、易于配置、简洁优雅的 VPN 协议。 tailscale 是底层利用了 wireguard 协议和 UDP 打洞等方式,把天南地北的主机去中心化地连为虚拟局域网的商业产品。 tailscale 有很大的免费使用额度(3 用户 100 终端,2024.2),在各大操作系统平台上都有配置简单的客户端。但在 iOS 上启动会占用独占性的 VPN 接口,和 Surge 产生了互斥。最贴身的 iPhone 设备不能接入自己的 tailscale 网络是很可惜的,于是 2024 年的春节档就着手准备解决这个问题。

这个问题有很多解决途径,iPhone 开启 tailscale app 之后借助 tailscale 的 exit node 功能把所有流量交给别的设备分流处理算一种(落选原因:5G 速度大于家宽上传),Surge 等 app 除了 wireguard 外还支持的 socks 、 ssh 等协议也算一种(落选原因:不想暴露任何 TCP 端口)。家里有一台常开的 N100 低功耗处理器小主机,装好了 Linux 操作系统,当然要充分利用这个资源,顺便还能把该主机上挂载的移动硬盘以 smb 协议共享为 “网盘” 来使用。

由于 Surge 支持 “分离配置” 特性,就算是遇到不能修改的订阅的配置也可以通过 “自定义主配置文件”加载 “订阅配置的某些段落”来实现自由定制某些规则。正是在这种情况下,只要再写一个 wireguard 专用的配置文件,变成 “自定义主配置文件”+“订阅配置”+“wireguard 专用配置” 即可,关键段落如下:

[Proxy]
#!include subscription.conf, wireguard.conf
[WireGuard name]
#!include wireguard.conf
[Rule]
IP-CIDR,10.0.0.1/32,wireguard,no-resolve #内网主机 wireguard 的对端地址
IP-CIDR,192.168.1.0/24,wireguard,no-resolve #内网主机所在的家庭内网 LAN 段,可访问家庭局域网
IP-CIDR,100.64.0.0/10,wireguard,no-resolve #tailscale 段,如果嫌大可以精确到主机/32

Surge 中 wireguard 配置和官方配置没什么差别,section-name 所指定的名字要和主配置、 wireguard 配置中 [WireGuard name]里的 name 相对应;peerallow-ips 的值如需填多个地址段要用双引号包裹,如 allow-ips = "0.0.0.0/0, ::0/0"

由于该内网小主机一开始经考虑被设置为内网设备而非软路由,所以在(有公网 IPv4 地址的)主路由上通过转发规则把公网来的 wireguard 的 UDP 包转发到内网小主机。主机上通过 wg 自带的命令生成公私密钥对,填入 Surge 的 wireguard 配置中,wg-quick up wg0 启动服务后 iPhone 即可访问主机上的服务,连接成功。

2024.3.8 更新方案:通过主路由器端口转发的方式把公网来的 UDP 转发到小主机,更新为直连小主机的 ipv6 地址(在主路由中用 ip6tables 放行对应端口)。使用 ddns 工具同时更新主机的 ipv6 、 ipv4 地址,ipv4 则是主路由器的公网 ipv4 地址并 fallback 到上述端口转发方案。

到这里只实现了 wireguard 的两个对端互连,要让 iPhone 访问内网主机所在的家庭局域网 192.168.1.0/24,除了上文中提到的在 Surge 主配置文件 [Rule]中将指定网段流量导向 wireguard,还要在内网主机上通过 iptables 让内网主机把 wireguard 流量转发到家庭局域网。在网上的很多 wireguard 教程里,内网主机端的 PostUp(也就 wireguard 服务启动后执行的命令)是这样写的:

iptables -A FORWARD -i wg0 -o eth0 -j ACCEPT;
iptables -A FORWARD -i eth0 -o wg0 -j ACCEPT;
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE;

这三句话可能以不同的形式(网卡名称,地址段等)出现,但实质相同,实现了内网主机 wireguard 网卡 wg0 、物理网卡 eth0 互联互通和 NAT 的规则。如无特殊,PostDown 则是写入相对应的 iptables 删除命令(把-A 换成-D)。重要的是开启 Linux 内核包转发,编辑 /etc/sysctl.conf, 将 net.ipv4.ip_forward 的值从 0  改为 1 。然后 sysctl -p  生效。

在解决了访问内网主机物理局域网段的访问问题后,我想进一步访问内网主机所在的 tailscale 虚拟局域网,实现方法也很简单并可以按照以上步骤如法炮制:把上述 iptables 命令中的物理网卡 eth0 改为 tailscale 的虚拟网卡名 tailscale0 ,再写三句命令追加在 PostUp 的后面,PostDown 也同样追加,重启 wg0 即可生效。最后 systemctl enable wg-quick@wg0wg0 加入开机自启动服务。

最后,幸亏路由器支持 NAT Loopback(又称 NAT hair pinning),也就是 IPv4 的网关会自动识别并修正 “目标写着路由器公网 IP,实际上得往内网去” 的请求,使得以上所有基于 “iPhone 在公网” 的设定到了内网也能正常运作。(如不支持 Loopback 可能需要内网自定义 DNS,使得目标服务器在公网解析出公网 IP,在内网解析出内网 IP)最终结构如下:

联通 iptv 贝尔电视盒折腾记

春节假期在家无事,想把联通 iptv 送的盒子折腾一下,装一装第三方 app,可以在电视上看看斗鱼直播什么的。之前的电视盒是创维某型号,插 U 盘可直接安装 apk,iptv 首页也能直接进入应用列表。但某次更换套餐后,换了个 “贝尔 S-010W-AV2B” 电视盒,配置是更好了,但上述 feature 全部堵死。于是在智能电视论坛等地方一番搜索和实操,最终实现了 “可安装安装第三方 app” 、 “更换默认 launcher” 这两大步。

一、可安装安装第三方 app

和路由器刷机一样,有人直接拆机上 TTL 线开搞,但这有点费周章了。先看看能不能打开 adb 调试吧。这个机器插上 USB 键盘后按 F2 可以打开应用列表,找到设置 app,开发者选项里打开 USB 调试即可在局域网内进行 adb 连接。同时,该机器两个 USB 口中靠近开关的那个可用公对公 USB 线连接电脑进行 USB 调试。这里用 Google 官方的 adb 提示 “adb server version (99) doesn’t match this client (41); killing…”,似乎是版本不匹配,还是在论坛里找到了可用的 adb 程序。 push 了某应用市场和第三方桌面,安装、启动都没问题。但是从第三方应用市场下载安装 app 却提示了禁止安装,还请我谅解?

谅解当然是不可能的,只有破解才是正道。原来这个机型的 Android 系统安装 apk 是依靠 com.android.packageinstaller,这个组件想必是经过了魔改,那么找一个 Android 4.4.4 原版的 packageinstaller.apk 代替即可,热心人早有提供,adb 进去卸载 com.android.packageinstaller,安装原版,问题解决。

二、更换默认 launcher

iptv 电视盒开机后,经过认证,会直接进入运营商定制的首页,没机会选择第三方桌面,并且定制首页的应用列表的入口也是点击无效。越是后期出厂的盒子,越是严格响应广电政策号召,不停地采取诸如限制 apk 安装、封堵 adb 之类的措施。同时,按下遥控器的 “首页” 按钮也会进入定制首页,无法再返回第三方桌面。那我总不能每次都用键盘或者 adb 来启动第三方桌面、打开第三方 app 啊,还是要想办法进一步改造一下。

这里有两个思路,一个是更改 Android 系统的 launcher,另一个是修改遥控器的按键映射——使 “首页” 或其他闲置按钮可以起到打开第三方 app 的作用。装了个利用 Android 辅助功能的按键映射 app,将 “双击遥控器首页” 按钮映射为打开第三方桌面,成功!本来是挺完美的了,但这个方案竟然出现了按键胡乱响应的 bug,实在是影响正常使用,进一步搜索想探究下遥控器按钮的映射,也发现 adb shell 里 getevent -l 命令很有趣,可以捕获包括遥控器在内的按键命令,但始终未找到这个机器的遥控器配置文件在哪里。

在论坛里搜到一个型号相近的电视盒修改教程,提示我 /system/build.prop 这个文件存了很多系统配置,其中就有和 launcher 相关的。花了论坛币,把人家的文件下载后逐行仔细揣摩,发现以下两行可能是关键:

ro.iptv.enable=true
ro.build.office=IPTV_cujs

上一行修改为 false,下一行留空,把 /system 分区挂载成 RW 后,adb push 回电视盒,重启后……盒子就挂了!卡在开机界面无响应了……

正丧气时,仔细想了想,问题应该不至于那么严重。发现启动卡住时,USB 调试起不来(原需进入系统设置点击一下才能启动),但网络 adb 竟然是通的,这又燃起了一丝希望,莫不是权限问题吧,赶紧 chmod 777,还是不行,这真是让人又是灰心,又是不解。谁知后来一搜,才发现在 Android 手机刷机界,这个问题简直是必踩之坑, /system/build.prop 这个文件的正确权限应该是 644 。 chmod 后启动正常,开机后也有了 launcher 选择,直接将第三方桌面指定为默认并不再询问。这下唯一美中不足的就是通过第三方桌面进入定制界面后没办法再回来,只能重启,这也已经很能令人满意了。

当然了,还有个另辟蹊径的思路就是直接购买非运营商定制的电视盒,或者树莓派、 HTPC 之类的设备,把运营商推流的地址抓出来导入到第三方播放器。这就有待来日了。