春节回老家,偶尔翻看一些资料的时候因网络原因众多网站打不开,此事颇为恼人。不由怀念起在家小机柜那点小设备,无奈现在手上空空,闲置的软路由也没带回来,巧妇难为无米之炊。当前这套网络是TPLink AC+AP方案,便对这个AC有了点想法。也就它有点算力,有个系统了吧?:)
网络背景 这是几年前给家里多层楼选择的一套TPLink方案(其实是我先在深圳用淘汰的方案给回了老家使用,吼吼)。有一个AC叫TL-R479GP,为了方便部署,同时支持8口POE供电,连接两个主AP(TL-AP1758GC)和各楼层的一些补充AP(86面板AP)。这不由的回想起,当时在京东下单这一套,也着实不便宜,然后发现1688上居然有几百块线差价,果断退掉去1688买,太香了。当然,很久没去了解了,不清楚如何状况,但从此内心觉得国内有些产品各渠道加价真高啊!
打入R479GP的内部 获得R479GP的ssh权限 不需要复杂的破解,网上已经有几种获得ssh的教程了。主要分两类:
通过修改配置(ssh的用户名/密码)并且重新打包导入配置,获得ssh的登录。 通过默认密码的方式进入。难点在计算默认密码,好在有前人经验,只有一行命令。 我的R479GP最近找客服要了最新固件(1.1.5 Build 20201110 Rel.72597)。感谢京东,客服甚至没问订单没管我是否在他们那购买的就果断发了固件过来,品牌还是不错的嘛:)刷完后我看人家教程一下心惊,听说后续版本有修复一些ssh漏洞,可别搬起石头砸了自己脚啊!所幸后续一切顺利。只要这样:
在设置中[系统工具]->[诊断工具]->[故障诊断]->[开启诊断模式] 即可打开ssh通道,默认端口为33400
root密码为LAN口mac地址md5后的前8位(有些版本是前16位)。LAN的MAC地址在基本设置
->LAN设置
里可以看到。这里假设我的是CC-08-07-06-05-04
,然后可以如下一行命令获得密码: 1
2
❯ echo "CC-08-07-06-05-04" | tr -d '-' | tr -d '\n' | md5 | cut -c 1-8
42df9037
你以为这就结束了吗,太理想了,有用户名和密码后,你登录会神奇的报错,这个我之前没见过啊:
1
Unable to negotiate with 192.168.0.1 port 33400: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1,diffie-hellman-group14-sha1,kexguess2@matt.ucc.asn.au
原因或许是因为R479GP系统的ssh服务端(dropbear)用的比较旧的版本了。要想能正常登录,需要添加一系列参数才可以。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
❯ ssh -o HostKeyAlgorithms = +ssh-rsa -o PubkeyAcceptedAlgorithms = +ssh-rsa \
-o KexAlgorithms = diffie-hellman-group1-sha1 root@192.168.0.1 -p 33400
root@192.168.0.1's password:
BusyBox v1.22.1 (2020-11-10 20:05:06 CST) built-in shell (ash)
Enter ' help' for a list of built-in commands.
_______ ________ __
| | .-----.-----.-----.| | | | .----.| | _
| - || _ | -__| || | | || _|| _|
| _______|| __| _____| __| __|| ________|| __| | ____|
| __| W I R E L E S S F R E E D O M
-----------------------------------------------------
BARRIER BREAKER ( Barrier Breaker, r96964)
-----------------------------------------------------
* 1/2 oz Galliano Pour all ingredients into
* 4 oz cold Coffee an irish coffee mug filled
* 1 1/2 oz Dark Rum with crushed ice. Stir.
* 2 tsp. Creme de Cacao
-----------------------------------------------------
root@TP-LINK:~#
随便看看 既然进来了,我们当然要看看这台设备的信息。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
root@TP-LINK:~# uname -a
Linux TP-LINK 3.3.8 #1 Tue Nov 10 20:09:13 CST 2020 mips GNU/Linux
root@TP-LINK:~# cat /etc/openwrt_release
DISTRIB_ID = "OpenWrt"
DISTRIB_RELEASE = "Barrier Breaker"
DISTRIB_REVISION = "r96964"
DISTRIB_CODENAME = "barrier_breaker"
DISTRIB_TARGET = "ar71xx/generic"
DISTRIB_DESCRIPTION = "OpenWrt Barrier Breaker 14.07"
DISTRIB_TAINTS = "no-all no-ipv6 busybox"
root@TP-LINK:~# cat /etc/openwrt_version
14.07
原来是openwrt的系统啊,MIPS架构。再瞧瞧CPU:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
root@TP-LINK:~# cat /proc/cpuinfo
system type : Qualcomm Atheros QCA956X rev 0
machine : TP-LINK TL-R4299G 2.0
processor : 0
cpu model : MIPS 74Kc V5.0
BogoMIPS : 373.55
wait instruction : yes
microsecond timers : yes
tlb_entries : 32
extra interrupt vector : yes
hardware watchpoint : yes, count: 4, address/irw mask: [ 0x0000, 0x0ff8, 0x0ff8, 0x0ff8]
ASEs implemented : mips16 dsp
shadow register sets : 1
kscratch registers : 0
core : 0
VCED exceptions : not available
VCEI exceptions : not available
我去啊,高通芯片,怎么解读它的强弱,我们看看GPT(其实这次让Gemini客串了)怎么说:
Info
这台网络设备的 CPU 性能一般。它使用的是 Qualcomm Atheros QCA956X 芯片,该芯片于 2013 年发布。它是一款单核 MIPS 74Kc V5.0 处理器,主频为 373.55 MHz。
MIPS 74Kc 是 MIPS 公司于 2002 年发布的一款 32 位 RISC 处理器架构。它是一款低功耗、低成本的处理器,适用于嵌入式系统。
QCA956X 芯片主要用于网络设备,例如路由器和交换机。它还可用于其他嵌入式系统,例如家用电器和工业控制设备。
这台网络设备的 CPU 性能足以满足大多数网络应用的需求。但是,对于要求更高的应用,例如视频流或游戏,它可能不够强大。
以下是 QCA956X 芯片的一些性能指标:
主频:373.55 MHz 指令集:MIPS 32 缓存:32 KB L1 指令缓存、32 KB L1 数据缓存 内存:支持 DDR2 和 DDR3 内存 外围设备:支持多种外围设备,例如 USB、Ethernet 和 PCIe 我不由的担心起来它这小身板还能不能被折腾一下。 再看看内存:1
2
3
4
5
6
7
8
9
root@TP-LINK:~# cat /proc/meminfo
MemTotal: 126464 kB
MemFree: 58968 kB
Buffers: 7960 kB
Cached: 32548 kB
SwapCached: 0 kB
Active: 28672 kB
Inactive: 19708 kB
Active( anon) : 10584 kB
128MB的家庭,让我又想起被嫌弃只有几G内存的软路由静静在躺在家里角落许久,是我的不该啊:) 就这点内存,跑个大点的程序,是不是系统就各种OOM了,想想都怕! 最后看一眼存储空间:
1
2
3
4
5
6
7
8
9
root@TP-LINK:~# df -h
Filesystem Size Used Available Use% Mounted on
rootfs 61.8M 732.0K 61.0M 1% /
/dev/root 9.3M 9.3M 0 100% /rom
tmpfs 61.8M 4.0M 57.7M 7% /tmp
root 61.8M 732.0K 61.0M 1% /tmp/root
overlayfs:/tmp/root 61.8M 732.0K 61.0M 1% /
/dev/mtdblock7 2.0M 712.0K 1.3M 35% /tmp/userconfig
tmpfs 512.0K 0 512.0K 0% /dev
什么!只有61M,并且还不是都可持久化。网上查了一下,可持久化保存的只有/tmp/userconfig这里,其它重启后会被重置。不要怀疑你的眼睛,真的是只有1.3MB呢? 怎么办,我程序放哪啊,还怎么折腾啊?
让v2ray住进小房子 编译自己的v2ray 想要更好的网络条件,我们要借助v2ray等,幸好它是golang开发的,交叉编译出MIPS版本也非难事。可能你也像我一样对交叉编译经验不多,特别是上面GOOS是啥,是linux吗?不会是openwrt吧?哈哈,你可以这样:
go tool dist list
看到go所支持的系统和架构。
最后我们的编译命令是:
1
GOMIPS = softfloat CGO_ENABLED = 0 GOOS = linux GOARCH = mips go build -o $HOME /v2ray -trimpath -ldflags "-s -w -buildid=" ./main
编译后赶紧看一下生成的二进制有多大。31M,完蛋了,放在/tmp/userconfig下是不可能了。所幸你也发现了/tmp目录下还有57M剩余空间,希望点燃了。 这时你想把这编译的二进制SCP过去就好了吧,对不起,dropbear不支持scp。我发现这个系统里有wget命令(curl没有),这是一个积极信号。
我们顺手先在编译机起一个http服务器(在对应二进制目录下),编译机当然有python啦:
然后在R479GP下:
1
2
3
4
5
6
7
8
9
# 只有/tmp下有点空间放东西了
cd /tmp
# 下载我们编译好的v2ray,注意换成你自己的ip/port
wget http://192.168.0.153:8000/v2ray
# 顺便看一下是否能执行
root@TP-LINK:/tmp# ./v2ray version
V2Ray 5.13.0 ( V2Fly, a community-driven edition of V2Ray.) Custom ( go1.20 linux/mips)
A unified platform for anti-censorship.
搞定了编译和二进制问题啦。
构建自己的v2ray配置 我基本没怎么使用过v2ray,它的配置和其它一些类似软件不太一样,服务器也不通用。我随便找了一个简单的模版,对其进行了某些修改:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
{
"log" : {
"loglevel" : "debug"
},
"routing" : {
"domainStrategy" : "AsIs" ,
"rules" : [
{
"type" : "field" ,
"ip" : [
"223.5.5.5/32" ,
"119.29.29.29/32" ,
"180.76.76.76/32" ,
"114.114.114.114/32"
],
"outboundTag" : "direct"
}
]
},
"inbounds" : [
{
"listen" : "0.0.0.0" ,
"port" : "1080" ,
"protocol" : "socks" ,
"settings" : {
"auth" : "noauth" ,
"udp" : true ,
"ip" : "0.0.0.0"
}
},
{
"listen" : "0.0.0.0" ,
"port" : "1081" ,
"protocol" : "http"
}
],
"outbounds" : [
{
"tag" : "proxy" ,
"settings" : {
"vnext" : [
{
"address" : "<vws-url....>" ,
"users" : [
{
"alterId" : 0 ,
"id" : "<id>" ,
"level" : 0 ,
"security" : "auto"
}
],
"port" : "<port>"
}
]
},
"streamSettings" : {
"security" : "none" ,
"wsSettings" : {
"headers" : {
"host" : ""
},
"path" : "<...>"
},
"network" : "ws"
},
"mux" : {
"enabled" : false ,
"concurrency" : 8
},
"protocol" : "vmess"
},
{
"protocol" : "freedom" ,
"settings" : {
"userLevel" : 0 ,
"domainStrategy" : "UseIP"
},
"tag" : "direct"
},
{
"settings" : {
"response" : {
"type" : "none"
}
},
"protocol" : "blackhole" ,
"tag" : "block"
}
]
}
其中有几处主要修改:
inbounds里修改了listen的地址为0.0.0.0,方便内网其它使用。 outbounds里的配置我不太清楚怎么写。我开始也不知道,做了两种尝试,它们都是有效的。 从订阅中获取 我们手上可能有支持v2ray的订阅,但具体到v2y配置应该怎么写,我是不懂也懒得研究。但我发现有个工具v2sub 可以拉取v2ray的订阅并且生成配置,它居然也是golang的,这可太喜欢了(意味着使用方便)。
在两轮交互式输入下,它会产生/etc/v2ray.json
和/etc/v2sub.json
文件。其中/etc/v2ray.json里的那一段outbounds
就是我们要抄过来的。题外话一下,个人感觉工具非必要不需要交互式,还是带参数更加好用一些。又没有复杂度又没有太多上下文,你交互式有啥意义呢? 当然,作为经历过喝水不忘挖井教育的我们,还是感谢一下作者。
从V2rayU中获取 我们都知道很多工具支持订阅,我试着在MacOS下安装了V2rayU,在正常操作能使用后(这步确认了代理服务器没问题),我们可以在菜单中点开查看到它的config.json
。同样我们可以复制出我们想要的outbounds那一段。
验证 到此处,程序和配置都有了,你可以把生成的配置放在前面http-server的目录下,然后同样的在R479GP中用wget收入囊中。这里我默认你会了,并且这个配置叫config.json
,然后我们只需要这样:
1
./v2ray run -c config.json &
便启动了一个v2ray客户端,它监听在1080(socks)和1081(http)。之后,就可以在本地浏览器上通过设置你的SwitchyOmega插件
,添加一个sock5或http协议的proxy,让某些网站走它即可。这期间从日志上看v2ray有一些报错,但不影响使用。发现看网站如google等,CPU/Mem也没多大负载。或许v2ray确实更轻量和高效一点吧:)
如果到这里就结束,那和我们在电脑上直接开一个软件也没多大区别,必须得有后手。
断电就无怎么可以接受? 上面已经描述过,在这台小身板的R479GP中,只有1.3M的空间是永久存储东西的。我们可以进去看看,发现有个文件/tmp/userconfig/etc/rc.local
文件。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@TP-LINK:/tmp/userconfig/etc# cat rc.local
# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
irq_balance()
{
local irqnum = ` cat /proc/interrupts | awk -F: '/eth/ {print $1}' | sed 's/[^0-9]//g' `
[ "1" == ` cat /proc/irq/${ irqnum } /smp_affinity` ] && {
local core_num = ` cat /proc/cpuinfo | grep -w processor | awk 'END{print NR}' `
local mask = ` awk "BEGIN{f=lshift(1, $core_num )-1; print f}" `
echo ` printf %x $mask ` > /proc/irq/${ irqnum } /smp_affinity
}
}
irq_balance
exit 0
写得挺友好,Put your custom commands here that should be executed once
。那么我们可以放点什么进来呢?有些文章说在这里sleep一下,然后放上之前我们的一系列下载配置和启动程序的命令,虽然可行,但不优雅。我想要守护进程,你不给我这机制,那么我就定时执行,于是乎借助crontab来搞:
1
2
# add crontab for start v2ray
echo "*/1 * * * * echo \"check v2ray process at \`date\`\" >> /tmp/result.crontab 2>&1 && sh /tmp/userconfig/start-v2ray.sh" | crontab -
为了防止日程月累打爆日志,我们得小心不去不断追加日志和打印不必要的输出,当然因为/tmp/目录也是易失的,定时重启也会缓存这种情况。之后将以上内容写到上述rc.local
文件的exit 0之前。接下来编写我们的脚本:
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/bin/sh
# 定义工作目录和服务器URL
WORK_DIR = "/tmp"
HTTP_SERVER_URL = "http://192.168.0.153:8000"
V2RAY_BIN = "v2ray"
CONFIG_FILE = "config.json"
# 预期的v2ray文件的MD5值
EXPECTED_MD5 = "2c2adf543c9008f3d8976c71c14b483e"
# 下载v2ray和配置文件
download_files() {
echo "Downloading v2ray and config file..."
wget -O " ${ V2RAY_BIN } " " ${ HTTP_SERVER_URL } / ${ V2RAY_BIN } "
wget -O " ${ CONFIG_FILE } " " ${ HTTP_SERVER_URL } / ${ CONFIG_FILE } "
# 检查MD5校验值
if echo " ${ EXPECTED_MD5 } ${ V2RAY_BIN } " | md5sum -c -s; then
echo "MD5 check succeeded."
else
echo "MD5 check failed, exiting script."
exit 1
fi
# 赋予v2ray执行权限
chmod +x " ${ V2RAY_BIN } "
}
# 检查v2ray进程是否在运行
check_v2ray() {
return ` ps | grep "[v]2ray" | grep -v grep`
}
# 启动v2ray进程
start_v2ray() {
echo "Starting v2ray process..."
./" ${ V2RAY_BIN } " run -c " ${ CONFIG_FILE } " &
}
# 主流程开始
cd " ${ WORK_DIR } "
# 检查v2ray文件是否存在且MD5值是否匹配
if [ ! -f ${ V2RAY_BIN } ] || ! echo " ${ EXPECTED_MD5 } ${ V2RAY_BIN } " | md5sum -c -s; then
download_files
else
echo "v2ray file exists and MD5 check passed."
fi
# 检查v2ray进程是否已经在运行
if check_v2ray; then
echo "No v2ray process detected. start v2ray"
start_v2ray
else
echo "The v2ray process is either already running."
fi
echo "----------- end -----------"
echo
在写脚本时要注意需要在目标机器上能运行,所以有些命令要稍作调整,比如md5sum的参数略有不同等。目标上也无bash,不要想当然:)
至此,无论啥时,包括重启我们的机器也会自动下载v2ray及配置并且启动,它的代码和程序都是在云上的,那么有点云控的味道了。
折腾没止境了? 事情到这里其实还没有结束,但折腾的时间有限。眼看春节放假(包括休了几天)就要过完了,我木有时间再玩这个了,但也有几点想法待后续有空再折腾。
其一:上面会发现我们的程序二进制过大了,在这小小的存储空间中,你都放不下2个这种程序,为了瘦身,我们可以借助upx
等工具将其压缩到较小体积。如以下,32M变8M了,这也太棒了吧!
1
2
3
4
5
6
7
8
9
10
➜ ~ upx --best v2ray
Ultimate Packer for eXecutables
Copyright ( C) 1996 - 2024
UPX 4.2.2 Markus Oberhumer, Laszlo Molnar & John Reiser Jan 3rd 2024
File size Ratio Format Name
-------------------- ------ ----------- -----------
33095680 -> 8659500 26.17% linux/mips v2ray
Packed 1 file.
其二:我们在保障主网络稳定下,又想给某些人(如我)有点新特权。我想可以通过iptables DNAT规则在主路由器上做一些配置,让某些设备可以天然默认进入代理模式而不必配置任何东西,即透明代理。初步想了一下,我们可分几步:
在DHCP中预留一些IP资源段,不自动分配出去。 将预留的IP段借助iptables规则,使其在访问时转发给v2ray。这块因时间关系没空玩了,网上似乎也有一点资料,大概也能找到灵感。资料见附录。 其三:上面云控的味道来了!既然我们可以自动下载软件和配置,何不自动下载脚本呢,这样我只有一个壳脚本,通过它来从云端下载资源,未来的想象空间也会更大!你能想到有多少玩法吗?而我,等有时间再来折腾了。
参考资料 -EOF