小米路由器mini实现翻墙

Published On October 14, 2017

category tool | tags router shadowsocks


目前我的翻墙路由器已经正常工作半年了,室友很满意,是时候把我以前的笔记整理一下并分享出来,希望能帮到更多的人。

小米路由器mini刷pandorabox、装shadowsocks的教程有很多,但大部分都只讲怎么做,很少讲为什么要这样做,本文除了介绍安装步骤,还试图讲清楚路由器翻墙背后的原理。 自制翻墙路由器分两步,第一步是路由器刷开源的系统(比如openwrt),类似于手机刷机;第二步是在openwrt里使用shadowsocks代理软件进行翻墙。

miwifi mini 刷 openwrt pandorabox

路由器其实也是一台小型计算机,它也有操作系统,一般叫做固件(firmware)。常见的固件有如下:

  • openwrt是最流行的开源家用路由器固件
  • pandorabox是openwrt针对国产路由器的优化版
  • LEDE是openwrt官方独立出来的开发分支,目的是解决openwrt维护困难的问题。

一般的家用路由器面向普通人群,都有自带的固件,这些固件比较注重用户界面,但不提供命令行接口或者系统功能不全,因此大家都对刷固件乐此不彼。小米路由器mini应该是支持刷机的最便宜的路由器。

安装openwrt的大致流程是先安装开发版固件,使用ssh进入命令行,执行刷机命令安装openwrt系统。

以下步骤参考:Xiaomi Mi WiFi Mini

获取root密码

要使用ssh登陆,当然得有密码才行,因此需要获取root账号的密码。 进入miwifi路由器的后台http://192.168.31.1,和小米账号绑定。 打开 http://www.miwifi.com,点击<开放>,下拉点击<开启SSH工具>,就可以看到root账号的密码。

安装开发版固件

开发版固件允许通过ssh进入命令行,刷openwrt是通过命令行进行的。 固件下载地址:http://www1.miwifi.com/miwifi_download.html,找到小米路由器mini ROM的开发版。 通过路由器的后台管理系统可以选择固件文件直接安装,另一个方式如下:

  1. 将要安装的固件拷贝到一个u盘中并命名为miwifi.bin,插到路由器上
  2. 开机(拔插电源)的时候常按reset键(iphone的卡针终于派上用场了)直到LED灯开始闪烁然后松开,路由器会安装u盘中的固件,大概等1分钟后系统重启后就完成了

使用这种方法就可以刷成我们想要的任何固件,比如升级或降级官方固件。当然不是所有固件都能正常运行的,不同路由器厂商的固件稍有不同。

刷openwrt

下载小米的openwrt固件,通过scp传到路由器,通过ssh进入路由器命令行执行:

mtd -r write <firmware-image you downloaded> OS1

虽然严格按照openwrt官方wiki的步骤安装openwrt,试了无数次都以失败告终,指示灯变红,没有wifi信号。当然看到红灯不要以为变砖了,使用安装开发版固件中的方法就可以刷回小米的固件。

最后换成pandorabox安装成功了。

pandorabox的下载地址是:http://downloads.openwrt.org.cn/PandoraBox/Xiaomi-Mini-R1CM/stable/,现在貌似打不开了。 我当时用的固件是:PandoraBox-ralink-mt7620-xiaomi-mini-squashfs-sysupgrade-r1024-20150608.bin,百度网盘下载地址是: http://pan.baidu.com/s/1qYhuJVY

灯变蓝后能搜到PandoraBox_开头的wifi,没有密码。路由器的ip通常是192.168.1.1,root账号的密码默认是admin。

Shadowsocks + GfwList 实现路由器自动翻墙

参考:Shadowsocks + GfwList 实现 OpenWRT / LEDE 路由器自动翻墙

优点:只有被墙的站点才走代理

GFW的工作原理:GFW将被墙的域名对应的ip加入黑名单,在大陆网络出口的路由器上,直接丢弃发往黑名单中的ip地址的报文

路由器翻墙原理:

  1. 对于被墙的域名,dnsmasq使用ss-tunel进行解析,ss-tunel通过ss-server转发udp报文到国外的dns服务器,比如8.8.8.8,dnsmasq把解析出来的ip加入到一个集合中,比如gfwlist
  2. iptabel将目的ip位于gfwlist集合中的tcp报文转发到ss-redir
  3. ss-redir将tcp流通过ss-server转发到目的服务器(被墙的服务器)

另一种翻墙的方式是将除国内域名以外的所有域名都通过iptables转发到shadowsocks,参见:

安装

安装依赖的包

opkg update
opkg install iptables-mod-nat-extra ipset
opkg remove dnsmasq && opkg install dnsmasq-full

shadowsocks

发布地址,可以手动下载ramips架构的ipk文件并安装。

目前(2017年4月)可以使用下面的方式一键安装:

opkg install shadowsocks-libev

几点说明:

  • 我使用的是原版shadowsocks-libev,很多教程安装的是shadowsocks-libev-spec,shadowsocks-libev-spec是针对openwrt的优化版
  • 也有教程安装了luci-app-shadowsocks-spec,它相当于shadowsocks-libev的ui,可以在pandorabox的管理后台进行shadowsocks的启动和关闭,对于程序员而言当然不需要这个

查看包含的文件

[root@PandoraBox:/root]#opkg files shadowsocks-libev
Package shadowsocks-libev (d53cd0c3fd-d53cd0c3fded50dbd3774c90b64ffd91a9b3c19a) is installed on root and has the following files:
/usr/bin/ss-local
/usr/bin/ss-redir
/usr/bin/ss-tunnel

各个组件的功能如下:

  • ss-local:建立本地 SOCKS 代理
  • ss-redir:建立透明代理
  • ss-tunnel:提供 UDP 转发

配置

1.dnsmasq

dnsmasq-full的功能是:

  1. 作为一个dns的代理,可以根据不同的域名动态选择dns服务器进行解析
  2. 将解析域名得到的IP加到一个ipset中

配置步骤:

  1. 修改/etc/dnsmasq.conf,在最后加入 conf-dir=/etc/dnsmasq.d
  2. 新建目录并进入/etc/dnsmasq.d
  3. 下载 dnsmasq_gfwlist_ipset.conf 后放入该目录,这是一个根据gfwlist生成的给dnsmasq使用的配置文件 该文件的格式如下
#使用指定的dns服务器解析该域名
server=/google.com/127.0.0.1#5353
#将解析出来的IP保存到名为gfwlist的ipset表中
ipset=/google.com/gfwlist

2.shadowsocks配置文件

/etc/shadowsocks.json

{
    "server": "23.105.207.175",
    "server_port": "1080",
    "password": "<your pwd>",
    "method": "aes-256-cfb"
}

3.启动脚本

init script 是一个特殊的shell脚本,不仅可以用来启动和停止守护进程,还可以加入开机启动项,方便重启后自动启动。路由器重启在所难免,除了停电,跳闸或者电费用完了都会导致断电,因此设置开启启动项非常有必要。

通过上面介绍的翻墙原理可以知道,需要依赖以下服务:

  • dnsmasq:作为本地dns服务器,转发黑名单的域名解析请求到ss-tunel
  • ipset:增加一个set
  • iptable:增加转发规则,有关它的配置请参考
  • ss-redir:转发tcp报文
  • ss-tunel:转发udp报文,给dns解析用

dnsmasq、ipset和iptable默认是开机启动的,启动脚本应该包括ss-redir和ss-tunel的启动命令,除此之外,因为ipset和iptable的设置都是临时生效,重启后失效,因此把它们也加入启动脚本中:

START=95

ss_redir_PID_FILE="/var/run/ss-redir2.pid"
ss_tunnel_PID_FILE="/var/run/ss-tunnel2.pid"
CONFIG=/etc/shadowsocks.json
DNS=8.8.8.8:53
PROXY_PORT=1080
TUNNEL_PORT=5353

start() {
    # Proxy Mode
    service_start /usr/bin/ss-redir -c $CONFIG -b 0.0.0.0 -l $PROXY_PORT -f "$ss_redir_PID_FILE"
    # Tunnel
    service_start /usr/bin/ss-tunnel -c $CONFIG -b 0.0.0.0 -u -l $TUNNEL_PORT -L $DNS -f "$ss_tunnel_PID_FILE"

    ipset -N gfwlist iphash -exist
    iptables -t nat -A PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080
}

stop() {
    # Proxy Mode
    service_stop /usr/bin/ss-redir
    # Tunnel
    service_stop /usr/bin/ss-tunnel
    iptables -t nat -D PREROUTING -p tcp -m set --match-set gfwlist dst -j REDIRECT --to-port 1080

}

启动

/etc/init.d/shadowsocks start
// 增加可执行权限
chmod +x /etc/init.d/shadowsocks
// 开启开机自动启动
/etc/init.d/shadowsocks enable

路由器设置

wan口配置:使用自定义的DNS服务器127.0.0.1,即dnsmasq

DHCP/DNS设置中填上国内的公共DNS服务器:114.114.114.114

运维

查看ipset

列出gfwset中的ip

ipset list gfwlist

查看iptables

列出nat表的所有链和规则

iptables -t nat -L

删除nat表PREROUTING链的第一条规则

rulenum 是该条规则的编号。从1开始。

iptables -t nat -D PREROUTING 1

ipset和iptables的设置都是实时生效、重启后失效的

路由器重启无法启动shadowsocks

路由器因为停电后重启,发现init脚本start函数没有启动ss-redir

logread没有init脚本的日志 修改ss_redir的启动命令,将日志输出到文件

# Proxy Mode
echo "starting redir" > /tmp/out.txt
#service_start /usr/bin/ss-redir -c $CONFIG -b 0.0.0.0 -l $PROXY_PORT -f "$ss_redir_PID_FILE"
service_start /usr/bin/ss-redir -c $CONFIG -b 0.0.0.0 -l $PROXY_PORT > /tmp/out.log 2>&1 &
echo $? >> /tmp/out.txt

/tmp/out.txt

starting redir
0

/tmp/out.log

^[[01;32m 2017-09-24 10:33:42 INFO: ^[[0minitialize ciphers... aes-256-cfb
^[[01;32m 2017-09-24 10:33:42 INFO: ^[[0mlistening at 0.0.0.0:1080
^Terminated

说明ss-redir本身是正常启动的,之后被系统终止了,经调查可能是因为资源不够,比如内存不够,被OOM(Out-Of-Memory) killer杀掉的,但是从dmesg的输出找不到证据。

最后将luci-app-shadowsocks包移除就OK了

2019.9.6更新日志

断电后路由器会自动恢复出厂设置,据说需要升级固件。

  1. 升级固件至PandoraBox-ralink-mt7620-xiaomi-mini-2018-12-14-git-1b9b0f382-squashfs-sysupgrade.bin

  2. 安装shadowsocksr-libev 因为有些ss服务商都只提供shadowsocksr

  3. DNS不经过代理服务器,而是直接通过8.8.8.8#53解析

    vim /etc/dnsmasq.d/dnsmasq_gfwlist_ipset.conf
    %s/127.0.0.1#5353/8.8.8.8#53/g
    
    再次说明gfw是直接封ip,而非干预域名解析。 所以就不需要/usr/bin/ssr-tunnel了

  4. 使用新的ssr服务

    {
        "server": "hk2.dawangidc.org",
        "server_port": "16230",
        "password": "xxx",
        "method": "chacha20",
        "protocol": "auth_chain_a",
        "obfs": "tls1.2_ticket_auth"
    }
    


qq email facebook github
© 2019 - Xurui Yan. All rights reserved
Built using pelican