秉亮的个人日志


做个树莓派翻墙路由器

网上有很多教程,但这个应该是最新的>_>

2016-05-28

前言

照例的絮絮叨叨。起因是给 chromebook 装 crouton 的时候各种网络问题(不过后来熟练掌握的 crouton 的 proxy 用法后这些问题已经不复存在),所以想要装一个 openwrt 的翻墙路由器。起初淘宝买了一个洋垃圾 Netgear WNDR3800,后来没用上就退掉了。看着毕设时候买的 Raspberry Pi 2,一直闲置着,翻了一下 openwrt 支持列表,算是对 Pi2 支持很不错(我当初也想在手头的 WRTNode 上面刷一个 Shadowsocks 但是也是各种出错,有需求的时候再试试看)。于是开始自己倒腾起了。网上的资料很多但是相对凌乱,而且它们的设备较老,所以本日志是对它们的一个更新补充。

我用到的设备

网络拓扑图

Alt text

编译 openwrt 及 shadowsocks 相关 ipk

至本日志发布为止,Raspberry Pi 2 B 支持的最新版本为 15.05.1 Chaos Calmer。所以编译目标为该版本。

编译前确保电脑内存和硬盘足够,当初我在 Digital Ocean 上的最低配置的 VPS 或者在我的 Chromebook 上编译会有问题,最后我使用了 PC + Virtualbox + Ubuntu 的方式,给虚拟机分配了 2 核 + 8G 内存 + 40G 动态大小硬盘。编译时需要链接网络,所以需要保证联网,有些源会被墙,会自动寻找可用源,也有可能失败,失败了重新编译就行,不会清除已经编译好的文件,编译时使用 proxychains-ng 会出错,原因未名。

参考:OpenWrt build system – Installation

安装必须的程序

sudo apt-get update
sudo apt-get install git-core build-essential libssl-dev libncurses5-dev unzip gawk

安装可能需要的程序

sudo apt-get install subversion mercurial

下载源码(这里下载的是 15.05 版本的源码,直接下载很慢,可以使用代理)

git clone git://git.openwrt.org/15.05/openwrt.git

下载并安装可用的 “feeds”

cd openwrt
./scripts/feeds update -a
./scripts/feeds install -a

下载Shadowsocks-libev for OpenWrtOpenWrt-dist LuCI源码(下载慢可用代理)

git clone https://github.com/shadowsocks/openwrt-shadowsocks.git package/shadowsocks-libev
git clone https://github.com/aa65535/openwrt-dist-luci.git package/openwrt-dist-luci

编译 po2lmo(OpenWrt-dist LuCI 需要 po2lmo)

pushd package/openwrt-dist-luci/tools/po2lmo
make && sudo make install
popd

编译目录

make menuconfig

编译完成后会弹出编译目录,在这里进行一些选择:

Save & Exit

编译

    make V=s

等待几小时,完成后可以在 openwrt/bin 目录下看到新生成的 brcm2708 文件夹。可以在 brcm2708/packages/base 目录下找到 shadowsocks-libev-spec-polarssl_2.4.6-1_brcm2708.ipk 和 luci-app-shadowsocks-spec_1.4.0-1_all.ipk。虽然同时在 brcm2708 目录下可以找到编译出来的 openwrt-brcm2708-bcm2709-sdcard-vfat-ext4.img,但是这个镜像安装之后 opkg install 会报错,所以编译这一步只使用编译出来的两个 ipk 文件,openwrt 映像还是使用从官网下载的版本。编译 ipk也可以使用 openwrt sdk,但我下载的 sdk 编译报错,所以使用直接编译全部的方式。

烧录 openwrt 镜像

把 TF 卡连上电脑进行烧录。

参考:Raspberry Pi[OpenWrt Wiki]

在OpenWrt的树莓派页面上有对应的下载链接和安装教程。

下载下来后执行:

dd if=/home/username/Downloads/openwrt-brcm2708-bcm2709-sdcard-vfat-ext4.img of=/dev/sdX bs=2M conv=fsync

上面这行 shell 命令中的 sdX 会不一样,可以使用 dmesg,也可以使用 gparted 来找到插入的 tf 卡的设备名称。

windows 上可以使用 Win32DiskImager。

烧录完之后就可以插入 TF 卡,链接上显示器键盘网卡和电源线进行初步的设置了。

对树莓派进行初步设置

插上电源后等待10+秒后,显示器没有更新信息后按回车进入控制台。

修改密码

passwd

按照提示输入,这一步会自动开启 SSH

修改network配置

参考:DIY高性能树莓派OpenWrt无线路由器 - 树叶的blog

    vi /etc/config/network

删除 lan 口下 ifname 那行,修改 lan 下 ipaddr 地址为另一个网段(我的主路由网段是 192.168.1.x,所以此处我修改为192.168.2.1),新增一个 wan 口,设为动态获取。

config interface 'loopback'
        option ifname 'lo'
        option proto 'static'
        option ipaddr '127.0.0.1'
        option netmask '255.0.0.0'

config interface 'lan'
        option type 'bridge'
        option proto 'static'
        option ipaddr '192.168.2.1'
        option netmask '255.255.255.0'
        option ip6assign '60'

config interface 'wan'
        option ifname 'eth0'
        option proto 'dhcp'

config globals 'globals'
        option ula_prefix 'xxxx:xxxx:xxxx::/xx'

用网线连接上 Raspberry Pi 的网口和主路由的LAN口,然后执行 /etc/init.d/network restart 重启网络,然后就可以使用 ping 命令检测网络连接。如果能够ping通的话就可以进行下一步了。

修改firewall设置

vi /etc/config/firewall

参考:如何配置防火墙 [OpenWrt Wiki]

在 firewall 中新建两条规则,分别开启从外网可以访问 22 和 80 端口,这样 Raspberry Pi 连上主路由之后就可以在主路由的局域网里通过 SSH 和 LuCI 访问 Raspberry Pi 了。

config rule
        option src              'wan'
        option dest_port        '22'
        option target           'ACCEPT'
        option proto            'tcp'

config rule
        option src              'wan'
        option dest_port        '80'
        option target           'ACCEPT'
        option proto            'tcp'

保存后重启网络和防火墙

/etc/init.d/network restart
/etc/init.d/firewall restart

通过 SSH 连接到 Raspberry Pi

Raspberry Pi 在主路由上获取到的 IP 是 192.168.1.4,现在可以在连到主路由的设备上通过 SSH 或者 LuCI 来设置。SSH 则是直接 ssh [email protected],LuCI 则是在浏览器中直接访问 http://192.168.1.4 即可。

安装网卡驱动

更新源(这个时间有时候会很长,如果失败的话重新执行该命令)

opkg update

安装USB设备支持

opkg install kmod-usb-core kmod-usb-uhci kmod-usb-ohci kmod-usb2
opkg install usbutils

查看网卡芯片

lsusb

我的是:Realtek Semicondoctor Corp. RTL8188CUS 802.11n WLAN Adapter。这一款可以用 rtl8192cu 来作为驱动。

参考:RTL8188CUS - two wireless interfaces possible? (AP+STA) –General Discussion –OpenWrt

安装rtl8192cu驱动

opkg install kmod-rtl8192cu

安装完成后重启

reboot

重启之后查看是否成功安装了设备驱动

root@OpenWrt:~# lsmod | grep 8192
compat                  1476  4 rtl8192cu
mac80211              388426  3 rtl8192cu
rtl8192c_common        32617  1 rtl8192cu
rtl8192cu              58304  0
rtl_usb                 8087  1 rtl8192cu
rtlwifi                48071  2 rtl8192cu

修改无线设置

默认的无线是关闭的,需要把它打开。

vi /etc/config/wireless

删除 disabled 那一行,确认 channel 的值不是 auto。此时的 Wifi 设置是没有加密的。

但是不知为何 Wifi 信号是搜不到的,打开 LuCI 页面可以看到 Wifi 状态显示的是:”Wireless is disabled or not associated”,在这里我折腾了很久,后来发现下一步可以修正它,让无线正常工作。

增加加密模式和对AP的支持

参考:Configure WiFi encryption [OpenWrt Wiki]

先更新源

opkg update

安装支持(官方建议安装 wpad-mini)。从支持情况来看,可能是默认的模式不支持AP,但是未作研究。

安装了 wpad-mini 之后会增加对 AP 的支持,这样就可以使用网卡作为 AP 了。跟是否加密无关,但是还是建议使用时使用加密通讯。

opkg install wpad-mini

接下去使用 LuCI(或者直接编辑 wireless 文件)来修改模式为 WPA2。然后重启。

reboot

现在正常的话你可以在你的 Wifi 列表之中看到设置的 Raspberry Pi 上的无线 AP 信号了。

我的 wireless 文件:

config wifi-device 'radio0'
    option type 'mac80211'
    option path 'platform/bcm2708_usb/usb1/1-1/1-1.5/1-1.5:1.0'
    option hwmode '11g'
    option channel '1'
    option txpower '20'
    option country '00'

config wifi-iface
    option device 'radio0'
    option network 'lan'
    option mode 'ap'
    option ssid 'Raspi'
    option encryption 'psk2+ccmp'
    option key 'password'

安装 Shadowsocks

先通过 SSH 连接上 Raspberry Pi,然后使用 SCP 命令将先前编译好的文件复制到 Raspberry Pi 上。

复制文件到 Raspberry Pi 上的 /tmp 文件夹中。/tmp 文件夹下的文件会在每次重启后自动清空,所以直到安装前不要重启,安装完成后直接重启就会自动清除。

scp raspi/shadowsocks-libev-spec-polarssl_2.4.6-1_brcm2708.ipk [email protected]:/tmp
scp raspi/luci-app-shadowsocks-spec_1.4.0-1_all.ipk [email protected]:/tmp

ssh [email protected]
cd /tmp
ls

输完 ls 后你可以看到复制过来的两个文件。

下面开始安装:

opkg update
opkg install shadowsocks-libev-spec-polarssl_2.4.6-1_brcm2708.ipk
opkg install luci-app-shadowsocks-spec_1.4.0-1_all.ipk

安装完成后登陆 LuCI,可以在 Service 下发现新增了 shadowsocks 的目录。不过现在登陆 Shadowsocks 账号还缺一个步骤,设定 DNS。

设置DNS

参考:路由器刷OpenWRT安装shadowsocks使用透明代理+去DNS污染 - 落格博客

Raspberry Pi 使用 opkg 没法安装 wget,所以这里还是使用 scp 来中转。

在 Raspberry Pi 上新建一个 dnsmasq.d 的目录,这里边存放 dns 规则。

mkdir /etc/dnsmasq.d

/etc/dnsmasq.conf 中写入 conf-dir=/etc/dnsmasq.d 使 dnsmasq.d 目录内的规则生效

echo "conf-dir=/etc/dnsmasq.d" >> /etc/dnsmasq.conf

下载下面两个文件并使用 scp 拷贝到 Raspberry Pi 上的 /etc/dnsmasq.d 文件夹中

https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/accelerated-domains.china.conf

https://raw.githubusercontent.com/felixonmars/dnsmasq-china-list/master/bogus-nxdomain.china.conf

scp raspi/accelerated-domains.china.conf [email protected]:/etc/dnsmasq.d
scp raspi/bogus-nxdomain.china.conf [email protected]:/etc/dnsmasq.d

使用 SSH 登陆 Raspberry Pi

cd /etc/dnsmasq.d
ls

你可以看到刚才下载的两个文件。

新建一个配置文件,意义为让其他不在列表中(即国外域名)都走代理解析。这里的 5300 是设定的用来 UDP 转发的端口,Shadowsocks 安装完成后默认的就是 5300,也可以自行修改。

echo "server=/#/127.0.0.1#5300" > gfwlist.conf

如果想 DNS 全部使用 UDP 转发的结果,可以删除 accelerated-domains.china.conf 和 bogus-nxdomain.china.conf 文件。

设置Shadowsocks

打开 LuCI 界面,点击 Service –> Shadowsocks,填入对应的数据,Enable UDP Forward。Save & Apply。刷新后在 Global Setting 下的 Global Server 中选择刚才新建的配置。

重启

reboot

打开手机连接该热点,就可以直接连上 Google 了。

备份

辛辛苦苦做完,但是又怕路由器出了问题也没办法像普通路由一样有个 Factory Reset 怎么办?可以使用 dd 指令来制作一个映像,用来保存。但是默认的会保存整个 TF 卡的映像,现在一个 TF 卡少则 8G,多的几十上百,很多空间是冗余的,所以在制作映像的时候需要压缩它。

How to shrink Raspberry Pi SD card images with GParted and dd - Knight of Pi

首先使用 GParted 查看 TF 卡情况,在我的这张盘上,从开始到最远的有数据的区块总大小为 76MB,所以下面这条命令的最后一个 count 参数就设为 76。注意设备名。

sudo dd if=/dev/sdX of=/home/username/raspi_openwrt_shadowsocks_embed.img bs=1M count=76

获得的映像为 76MB,可以直接 gzip raspi_openwrt_shadowsocks_embed.img 压缩一下,压缩完只有 8MB 不到。顺手丢进 Dropbox 或者别的云存储可以保存。

资料自取区

raspi_openwrt_shadowsocks_embed.img.gz

下载链接

镜像中的用户密码:password

shadowsocks-libev-spec-polarssl_2.4.6-1_brcm2708.ipk

下载链接

luci-app-shadowsocks-spec_1.4.0-1_all.ipk

下载链接