小米路由器3(R3)全方位调教

以后再买小米路由器,我就吃屎。

惊闻运营商们已经开了ipv6,想试一下,然而家里的小米路由器太菜了完全不支持,上一个官方版本还在19年,于是开始漫漫折腾垃圾路由器的道路。

调教光纤猫

这里因人而异,我这里参考了这个

调教路由器root && ssh

由于小米官方不给开ipv6,于是只能先刷开发版固件,然后去官网下一个专门的开ssh的bin文件放到u盘刷进去。官方有教程,不用说了。

调教openwrt

连ssh进去之后你会发现小米固件是基于openwrt二次改的,而这个openwrt连opkg啥都没有,是个半残。

首先remount一下根目录

1
mount -o remount, rw /

然后改下环境变量

修改/etc/profile文件,找到export PATH=一行修改为:

1
export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/data/usr/sbin:/data/usr/bin

再这一行下面新添加一行:

1
export LD_LIBRARY_PATH=/data/usr/lib

保存退出,source /etc/profile 使其生效

为啥要改环境变量呢?路由器一般有两个flash芯片储存数据,一个是比较小的spi flash(似乎是这个名字),用来存放linux kernel,rootfs这种比较重要的东西,挂载在/。还有一个比较大的nand flash,挂载到/data。因为前者比较小所以基本上啥都装不下,所以以后一般要把比较大的文件放在后者。这里设置下环境变量方便后续进行。

如果想看具体占用,可以df -h一下。

调教ipv6

可以看这个贴子,但不要用他的6relayd,因为他的是armhf架构的,放在mips的小米3上跑不了。可以去61楼下我编译好的6relayd,尽可能放在/data/sbin里。

调教(交叉编译)6relayd

6relayd这个东西类似于一个ipv6 dhcp?不是很懂。但是因为手头没有mips版的,所以还要下对应的openwrt sdk交叉编译。

点这里下载op sdk,解压。

去这里clone一个6relayd。

6relayd用cmake管理,于是修改cmakelists.txt让sdk里的gcc去编译:

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
cmake_minimum_required(VERSION 2.8)
cmake_policy(SET CMP0015 NEW)

# Project Definition
project(6relayd C)

set(STAGING_DIR "/home/yxaa/OpenWrt-SDK-ramips-for-linux-x86_64-gcc-4.8-linaro_uClibc-0.9.33.2/staging_dir")
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
set(CMAKE_C_COMPILER "${STAGING_DIR}/toolchain-mipsel_24kec+dsp_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mipsel-openwrt-linux-uclibc-gcc")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -std=c99 -I${STAGING_DIR}/target-mips_34kc_uClibc-0.9.33.2/usr/include/ -L${STAGING_DIR}/target-mips_34kc_uClibc-0.9.33.2/usr/lib/")
add_definitions(-D_GNU_SOURCE -Wall -Wextra -Wno-extended-offsetof -pedantic)

add_executable(6relayd src/6relayd.c src/router.c src/dhcpv6.c src/ndp.c src/md5.c src/dhcpv6-ia.c)
target_link_libraries(6relayd resolv)

# Installation
install(TARGETS 6relayd DESTINATION sbin/)

# Packaging information
set(CPACK_PACKAGE_VERSION "1")
set(CPACK_PACKAGE_CONTACT "Steven Barth <[email protected]>")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "6relayd")
set(CPACK_GENERATOR "DEB;RPM;STGZ")
set(CPACK_STRIP_FILES true)

SET(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION})
set(CPACK_PACKAGE_FILE_NAME "${PROJECT_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}")

include(CPack)

/home/yxaa换成相应的路径。然后

1
2
3
cd /home/yxaa/6relayd/
cmake .
make

然后就能在这个文件夹里找到6relayd,传到路由器上,应该可以运行。之后再参考那个教程就行啦。

调教opkg

因为没有opkg,所以现在连一个软件包也没法安装,非常难受。所以要想办法先把这个搞定。

先看这个把opkg binary传上去,确保能正常运行。然而官方的openwrt源在我这里完全连不上,没速度。而且默认的wget不支持https就很蛋疼。其他的国内镜像源也没有这么老的版本,非常尴尬。于是我决定自己搭一个镜像源。

首先,需要一台能连官方源的主机,然后从网上随便找个爬虫把所有软件包都爬下来。下面这个python2爬虫我修改了一下:

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
#!/usr/bin/env python
#coding=utf-8
#
# Openwrt Package Grabber
#
# Copyright (C) 2016 sohobloo.me
#

import urllib2
import re
import os
import time

# the url of package list page, end with "/"
baseurl = 'https://archive.openwrt.org/barrier_breaker/14.07/ramips/mt7620a/packages/'

# which directory to save all the packages, end with "/"
time = time.strftime("%Y%m%d%H%M%S", time.localtime())
savedir = './' + '20200713233348' + '/'
pattern = r'<a href="([^\?].*?)">'
cnt = 0
def fetch(url, path = ''):
global cnt
if not os.path.exists(savedir + path):
os.makedirs(savedir + path)
print 'fetching package list from ' + url + path
content = urllib2.urlopen(url + path, timeout=15).read()
#print content
items = re.findall(pattern, content)
print items
for item in items:
if item.startswith('/'):
continue
elif item.endswith('/'):
fetch(url, path + item)
else:
cnt += 1
print 'downloading item %d: '%(cnt) + path + item
if os.path.isfile(savedir + path + item):
print 'file exists, ignored.'
else:
rfile = urllib2.urlopen(baseurl + path + item)
with open(savedir + path + item, "wb") as code:
code.write(rfile.read())

fetch(baseurl)

搭建http服务器就不说了。然而之后我发现我这里的设置似乎强制用https,但是默认的wget并不支持。想要支持,又要装新的包。没办法于是手动一个个下载https的包上传到路由器,然后用opkg手动安装。下面是支持https需要装的包。

1
2
3
4
5
6
7
8
9
10
11
ca-certificates_20141019_ramips_24kec.ipk
libc_0.9.33.2-1_ramips_24kec.ipk
libopenssl_1.0.2f-1_ramips_24kec.ipk
libpcre_8.35-2_ramips_24kec.ipk
libpthread_0.9.33.2-1_ramips_24kec.ipk
librt_0.9.33.2-1_ramips_24kec.ipk
libubox_2014-08-04-dffbc09baf71b294185a36048166d00066d433b5_ramips_24kec.ipk
libustream-openssl_2014-03-25-fc0b5ec804ee43c532978dd04ab0509c34baefb0_ramips_24kec.ipk
openssl-util_1.0.2f-1_ramips_24kec.ipk
wget_1.16-1_ramips_24kec.ipk
zlib_1.2.8-1_ramips_24kec.ipk

然后我在安装wget的时候提示空间不足。于是把/usr/sbin的几个大文件move到/data/sbin里并作软链接。之后wget的链接也不对,需要用链接到正确位置的wget-ssl

最后把对应的官方源url换成我的,就ok了。

end

最后,理论上你想干啥就干啥了。r3有一个usb口,可以搞搞离线下载之类的……你甚至可以用sdk编译一个tinycc之类的c语言编译器然后传上去,然后达成“在路由器上写C语言作业”的成就。但是性能这么菜的路由器,你真的要在上面跑这些东西吗?……

当然为什么不直接刷相应的openwrt?因为懒得折腾刷机,万一刷坏了,还要被家人狂k。所以并没有胆量。