高通410随身WiFi的进阶USB网络共享和IPv6配置
大概是今年年初开始,酷安社区那边掀起了折腾淘宝上那些高通410平台的随身WiFi的热潮,它们价格低廉、解锁简易、拓展性强的特点使得各路大神都投入了极大的热情来开发其周边玩法,OpenStick就是一个能让这个随身WiFi跑debian的项目。这个棒子的相关信息网上已经有非常非常多了,我在这里就不陈词滥调介绍,而是速战速决分享一些新的玩法和优化。
修改 Gadget 让其支持 USB CDC-ECM
首先是我想把这个棒子直接插在 CCR1036 上让他作为带外管理使用,但是显然它没有直接就能用,所以我稍微研究了一下,主要涉及添加 ECM 功能和修改 Vendor ID/Device ID两部分。
什么是 USB Gadget
https://blog.csdn.net/zjujoe/article/details/2645510
Linux-USB Gadget 驱动框架(以下简称 Gadget)实现了USB 协议定义的设备端的软件功能。基于 API, Gadget 驱动实现了一套硬件无关的功能,这基本上可以对应到 USB 协议里 的各种 USB Class。
普通的 Gadget 驱动只实现一个功能(比如, u 盘,usb 网卡)。复合设备可以支持多个功能。像智能手机*, PDA*这样的设备,硬件支持较丰富的端点、DMA Buffer, 给软件提了支持复合功能的基础。
简单的说就是在一个USB接口上实现多个功能的框架。
什么是 USB CDC-ECM
CDC-ECM 是一套和微软 RNDIS 类似的,实现 Ethernet over USB 的协议,但它是由 USB-IF 制定的业界标准,除了 Windows 之外其他系统(Linux、macOS)基本都支持。
HandsomeMod(OpenStick 项目的发行版) 如何管理和使用 Gadget
https://www.kancloud.cn/handsomehacker/openstick/2637561
OpenStick 提供的所有系统都使用基于libusbgx的Gadget Controller (以下简称gc)来管理usb在device模式下的行为。
该发行版使用 gc 来管理 Gadget,而且作者在编写这个程序的时候就支持了许多种设备类型,包括CDC-ECM。我们只需要修改系统开机启动会调用的脚本 /usr/sbin/mobian-usb-gadget
就可以,修改后的脚本如下。
#!/bin/sh
CONFIGFS=/sys/kernel/config/usb_gadget/g1
setup() {
# Remove All Gadgets If Gadget Exist
[ -d $CONFIGFS ] && gc -c
# Setiing Up Rndis
gc -a rndis
sleep 1
# Add CDC-ECM Device
gc -a ecm
# Setting Up Adbd
gc -a ffs
mkdir -p /dev/usb-ffs/adb
# in offical version of gc name will be ffs.x
mount -t functionfs ffs.2 /dev/usb-ffs/adb
# Fire Up Adbd
adbd -D &
# (hack) wait adbd setup
sleep 1
# Enable Gadget
gc -e
}
reset() {
echo "Removing the USB gadget..."
# Remove USB gadget
if [ -d $CONFIGFS ]; then
echo "Removing gadget configuration..."
gc -c
fi
}
case "$1" in
reset) reset ;;
setup) setup ;;
*) ;;
esac
不知道为什么,添加了 ECM 设备之后再加ADB设备会让整个 USB 功能失效,考虑到我暂时用不上 adb 所以干脆就注释掉了。 2022年10月16日更新:我傻逼了,没看注释说 在正式版gc里ffs的设备名字是ffs.x而不是adb,导致mount不上。现在请配合以上更新后的脚本使用。
修改 Vendor ID 和 Product ID
需要重新编译 https://github.com/HandsomeMod/gc 并且替换 /usr/bin/gc
,当然你也可以直接以二进制方式修改可执行文件里的数值。修改为如下即可让RouterOS识别。
#ifndef ID_VENDOR
#define ID_VENDOR "0x05ac"
#endif
#ifndef ID_PRODUCT
#define ID_PRODUCT "0x1402"
#endif
如果你实在太懒,可以直接下载我编译好的版本 https://pan.globalslb.net/s/RbYcP (只修改了ID,没有改名字)
插上路由器之后 RouterOS 里大概是这个效果(如果自己编译的话,可以自定义设备名字)
配置网络
添加完 ECM 之后系统里会出来两个 usb 网口 usb0 和 usb1,需要按照 https://www.kancloud.cn/handsomehacker/openstick/2684880 的教程配置好网桥,然后把 usb1 也添加进这个网桥里,ROS 才能 DHCP 获得 IP
IPv6 配置
蜂窝网络的 IPv6 共享是什么样子的
一言以蔽之就是 ND Proxy,因为核心网没有实现 DHCPv6 Prefix Delegation。所以我们主要依靠 NDPDP 来把网络打通。这和教育网里的 SLAAC IPv6 分配很类似,可以完全参考其经验操作。在这里我主要参考了 https://www.cnblogs.com/flintlovesam/p/5329241.html 来配置NDPPD + RADVD + DHCP6S
所有配置
原理性的东西看上面的教程就知道了,这里直接分享所有配置和脚本。
使用的前提是你已经按照 https://www.kancloud.cn/handsomehacker/openstick/2684880 的教程配置好网桥了,一切都是以该教程的配置为基础的。
你还需要用 apt install ndppd radvd wide-dhcpv6-server
安装依赖软件。
以下文件如果不存在则创建:
/etc/NetworkManager/dispatcher.d/ipv6-conf.sh
主要负责在网络变动的时候重新配置 IPv6
配置完毕之后记得用 chmod +x /etc/NetworkManager/dispatcher.d/ipv6-conf.sh
给予执行权限
#!/usr/bin/env bash
interface=$1
event=$2
if [ "$interface" == "wwan0" ]; then
prefix=$(ip -6 addr show dev wwan0| sed -e's/^.*inet6 \([^ ]*\)\/.*$/\1/;t;d'|head -n 1|cut -f'1-4' -d':')
# just assume prefix length /64 here
echo "get prefix $prefix::/64"|systemd-cat -t ipv6_conf
cp /etc/ndppd.conf.bak /etc/ndppd.conf
sed -i "s/REPLACE_PREFIX_HERE/$prefix:2333::\/80/g" /etc/ndppd.conf
cp /etc/radvd.conf.bak /etc/radvd.conf
sed -i "s/REPLACE_PREFIX_HERE/$prefix:2333::\/64/g" /etc/radvd.conf
cp /etc/wide-dhcpv6/dhcp6s.conf.bak /etc/wide-dhcpv6/dhcp6s.conf
sed -i "s/PREFIX_MIN/$prefix:2333::2000/g" /etc/wide-dhcpv6/dhcp6s.conf
sed -i "s/PREFIX_MAX/$prefix:2333::3000/g" /etc/wide-dhcpv6/dhcp6s.conf
systemctl restart radvd
systemctl restart ndppd
systemctl stop wide-dhcpv6-server
systemctl start wide-dhcpv6-server
echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
sleep 30
echo "setting route" |systemd-cat -t ipv6_conf
ip -6 addr add $prefix:2333::1/80 dev br0
ip -6 route add $prefix::/65 dev br0
ip -6 route add $prefix:8000::/65 dev br0
ip -6 route |systemd-cat -t ipv6_conf
fi
/etc/ndppd.conf.bak
NDPPD的配置模板
proxy wwan0 {
router yes
timeout 500
ttl 30000
rule REPLACE_PREFIX_HERE {
auto
}
}
/etc/radvd.conf.bak
RADVD的配置模板
interface br0 {
AdvSendAdvert on;
AdvOtherConfigFlag on;
AdvManagedFlag on;
MinRtrAdvInterval 3;
MaxRtrAdvInterval 10;
prefix REPLACE_PREFIX_HERE {
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
};
};
/etc/wide-dhcpv6/dhcp6s.conf.bak
DHCPv6服务器的配置模板
interface br0 {
address-pool pool1 3600;
};
pool pool1 {
range PREFIX_MIN to PREFIX_MAX ;
};
如果不出意外的话,配置完这些之后你重启一下 ModemManager 或者重新插入一下棒子就能看到下面的效果。
在ROS上也可以获取地址
如果出了意外的话,请运用你的聪明才智进行解决~
换不同运营商卡之后 modem not found
好像是因为换运营商之后会把esim重新启用,所以导致找不到你的卡。参考这个解决:
https://techie-s.work/posts/2022/07/openstick-msm8916/
注意 /sys/class/leds/ 下面的路径名字可能不一样(比如我的叫sim:sel,自己看着改就好。
总结
感谢送给我棒子的寒烟w,这个棒子的可玩性确实非常好:弄坏了能随时9008刷回去、4G还蛮稳定的、跑debian发热不严重。目前我在上面跑了 IPv6 DDNS 和 Frp 做路由器的带外管理,为我的炸网行为增添多一重保障。