科学上网

树莓派打造科学上网无线路由器(基于Realtek 8192cu网卡)

前言


一直念叨着要把家里的无线路由改成能自动科学上网,但是平时在各种设备上习惯了用SS,懒癌晚期患者说了N长时间都没有动静。直至前几天,小朋友抱怨因为不能访问Google,查资料时搜索引擎都只能用度娘。关乎到下一代成长总得引起足够重视,但是哥穷得实在舍不得花钱买一个新的路由器,想起家里有个已经吃尘差不多两年的Model B树莓派,翻箱倒柜找出来,开始折腾。

以为无非是手到擒来的小case,把树莓派接上电来开始放狗搜,结果还要赔了差不多一个晚上才把它折腾完。原因主要有两个,一是网上大多数使用的无线网卡都是nl80211的,而俺手里只有型号为磊科Netcore NW337的Realtek 8192cu USB无线网卡,而默认的驱动程序并不支持hostapd;二是现在大家用的都是新版本的Raspbian操作系统,而俺是使用吃灰的旧派来折腾。所以此博文并没有多大的技术含量,无非是记录俺安装过程的备忘录,还有就是各种资料拼凑的整合。在此先感谢本文引用的各位大拿的资料。

硬件与系统


系统是Raspbian Wheezy,更新了源后升级到了最新版本固件(sudo rpi-update)。
我利用树莓派的有线网卡连接电信的光猫,USB无线网卡做为网络信号发射器。USB无线网卡使用的是在某东买的磊科Netcore NW337网卡,成本低廉耐操是王道。再重点说明一下,这个网卡的芯片是Realtek 8192cu。利用以下命令可以确认无线网卡的芯片型号。
$ dmesg | grep 8192cu
[ 7.434462] usbcore: registered new interface driver rtl8192cu

基本设置

1.树莓派基础设置

运行Raspbian系统配置命令,把文件系统扩展到整个SD卡,修改密码等。
$ sudo raspi-config

2.修改系统源
默认的源更新时速度会很慢,备份源文件,修改源至中国科学技术大学 Linux 用户协会的镜像。然后更新源,更新系统固件。
$ sudo mv /etc/apt/sources.list /etc/apt/sources.list.bak
$ sudo echo "deb deb http://mirrors.ustc.edu.cn/raspbian/raspbian/ wheezy main contrib non-free rpi" > /etc/apt/sources.list
$ sudo apt-get update
$ sudo rpi-update

3.把eth0的IP设置为固定IP

原来系统的IP是DHCP,把IP地址改为固定,并把默认网关指定为电信光猫的IP。

$ sudo nano /etc/network/interfaces

把配置信息修改如下:

auto eth0
iface eth0 inet static
address 192.168.1.2
netmask 255.255.255.0
gateway 192.168.1.1

192.168.1.1为电信光猫地址。

4.安装dnsmasq,设置DHCP服务

使用dnsmasq来做DHCP服务器,修改配置文件,设置DHCP的客户端IP网段。

$ sudo apt-get install dnsmasq

$ sudo nano /etc/dnsmasq.conf

对应修改以下几段内容。

#配置监听地址
listen-address=127.0.0.1,192.168.1.2,192.168.0.1
#配置DHCP分配段
dhcp-range=192.168.0.100,192.168.0.150,12h

注意192.168.0网段是无线路由分配给客户端的地址段。

重启dnsmasq服务以使更改生效。

$ sudo service dnsmasq restart

5.开启系统的包转发
Linux系统默认关闭了IP包转发,需要把包转发打开方能使用路由功能。
$ sudo nano /etc/sysctl.conf

去掉net.ipv4.ip_forward=1前的注释,运行以下命令使其生效。同时启用eth0的NAT。

$ sudo sysctl -p
$ sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Realtek 8192cu网卡驱动的安装

正如前文所说,系统默认的Realtek 8192cu网卡驱动并不支持hostapd,所以必须重新编译网卡的驱动。

1.安装内核源

为了编译网卡驱动,你需要系统的内核源,下载Raspbian的内核源至当前用户的honme目录备用。

$ cd ~
$ sudo wget https://raw.githubusercontent.com/notro/rpi-source/master/rpi-source -O /usr/bin/rpi-source && sudo chmod +x /usr/bin/rpi-source && /usr/bin/rpi-source -q --tag-update

下载后运行以下命令。

$ rpi-source

运行时很有可能会提示gcc版本错误,因为内核源所用的gcc版本要比当前树莓派安装的gcc版本要高。用以下命令查看对应的gcc版本并安装新版本。

$ cat /proc/version
$ gcc --version | grep gcc
$ sudo apt-get update
$ sudo apt-get install -y gcc-4.8 g++-4.8

然后设置gcc版本。

$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 20
$ sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20
$ sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50

再一次运行命令安装内核源。

$ rpi-source

创建内核源目录的符号链接,此步非常重要,不做的话下面的命令会报错。

$ ln -s ~/linux/arch/arm ~/linux/arch/armv6l

2.重新编译rt8192c网卡驱动程序

系统默认的rt8192c驱动程序不支持AP模式,但是感谢dz0ny提供的代码,让这成为可能。从git克隆代码到本地。

$ cd ~
$ git clone https://github.com/dz0ny/rt8192cu.git

如果提示没有git请自行安装git。

构建驱动程序并安装。

$ cd ~/rt8192cu
$ sudo make
$ sudo make install

安装成功后程序会自动把旧的驱动程序放到黑名单里,运行以下命令确认。

$ cd ~/rt8192cu
$ cat /etc/modprobe.d/blacklist.conf
blacklist rtl8192cu

3.下载hostapd源并编译

网上的资料讲需要到Realtek官网下载hostapd压缩包并解决对应树莓派所需的hostapd源,估计是太旧的原因,现在Realtek官网已没有该文件下载。开始觉得应该在官方源安装个hostapd也可以,于是apt-get install hostapd,折腾了老半天,发现没法启动hostapd,最后还是卸载了,放狗搜到了RTL8188C_8192C_USB_linux_v4.0.2_9000.20130911.zip,老老实实的做下来才能正常工作。

上传zip文件到用户目录下,解压。

$ unzip RTL8192xC_USB_linux_*.zip

再解决你所需要的hostapd程序。

$ tar zxvf RTL8188C_8192C_USB_linux_*/wpa_supplicant_hostapd/wpa_supplicant_hostapd-0.8_rtw_*.tar.gz

切换到hostapd源,修改Makefile。

$ cd ~/wpa_supplicant_hostapd-0.8_*/hostapd/
$ sudo nano Makefile

找到CFLAGS节内容修改为:

CFLAGS=-MMD -Os

编译hostapd,并把可执行文件复制至正确位置。

$ sudo make
$ sudo cp hostapd hostapd_cli /usr/local/sbin/

4.配置hostapd

创建hostapd配置文件名录,编辑配置文件。

$ sudo mkdir /etc/hostapd
$ sudo nano /etc/hostapd/hostapd.conf

我的hotapd.conf文件长这个样子。

ctrl_interface=/var/run/hostapd
###############################
# Basic Config
###############################
macaddr_acl=0 auth_algs=1
driver=rtl871xdrv
##########################
# Local configuration...
##########################
interface=wlan0
hw_mode=g
ieee80211n=1
wme_enabled=1
channel=13
ssid=Tongfu
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_psk=IL0veT0ngfu
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

运行命令来验证hostapd配置文件,没有错误提示CTRL+C结束,修改/etc/default/hostapd文件,编辑/etc/default/hostapd,改变DAEMON_CONF的配置为DAEMON_CONF=”/etc/hostapd/hostapd.conf”

$ sudo hostpad -d /etc/hostapd/hostapd.conf
$ sudo nano /etc/default/hostapd

创建初始化脚本到/etc/init.d中,以便设置开机启动AP服务。

$ sudo nano /etc/init.d/hostapd

文件代码如下:

#!/bin/bash
# /etc/init.d/hostapd

### BEGIN INIT INFO
# Provides: hostapd
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Managing hostapd
# Description: This service is used to manage hostapd (WiFi Access Point)
### END INIT INFO

case "$1" in
start)
echo
echo "Starting hostapd..."
echo
if [ ! -d /var/run/hostapd ]; then
rm -rf /var/run/hostapd
mkdir /var/run/hostapd
fi

/usr/local/sbin/hostapd -B -P /var/run/hostapd/wlan0.pid /etc/hostapd/hostapd.conf
;;
stop)
echo
echo "Stopping hostapd..."
echo
if [ -e /var/run/hostapd/wlan0.pid ]; then
read pid < /var/run/hostapd/wlan0.pid if [ x$pid != x ]; then kill $pid fi fi ;; restart) echo echo "Restarting hostapd..." echo if [ -e /var/run/hostapd/wlan0.pid ]; then read pid < /var/run/hostapd/wlan0.pid if [ x$pid != x ]; then kill $pid fi fi if [ ! -d /var/run/hostapd ]; then rm -rf /var/run/hostapd mkdir /var/run/hostapd fi /usr/local/sbin/hostapd -B -P /var/run/hostapd/wlan0.pid /etc/hostapd/hostapd.conf ;; *) echo echo "Usage: /etc/init.d/hostapd start|stop|restart" echo exit 1 ;; esac exit 0 [/highlight]

赋予文件可执行,并且开机启动。

$ sudo chmod +x /etc/init.d/hostapd
$ sudo update-rc.d hostapd defaults

现在启动hostapd服务,应该可以用电脑搜到热点并连接了。

$ sudo service hostapd start

至此,利用Realtek 8192cu USB无线网卡在树莓派建立无线路由器的工作已完成,你可以通过无线网络连接路由,正常的上网浏览了。但是要透明的访问Google,还是得进行科学上网的设置。

科学上网配置

1.建立无污染DNS
使用中科大的DNS,修改/etc/dnsmasq.conf。
$ sudo nano /etc/dnsmasq.conf

在文件最后加入以下规则:

no-resolv
server=202.38.93.153
server=202.141.162.123

重启dnsmasq。

$ sudo service dnsmasq restart

2.安装shadowsocks

通过pip安装shadowsocks,建立配置文件

$ sudo pip install shadowsocks
$ sudo nano /etc/shadowsocks.conf

配置文件内容如下:

{
"server":"xxx.xxx.xxx.xxx",
"server_port":9999,
"local_port":1088,
"password":"xxxxx",
"timeout":300,
"method":"aes-256-cfb",
"fast_open": false,
"workers": 1
}

保存文件后启动ss服务。

$ sudo sslocal -c /etc/shadowsocks.conf -d start

如果没有问题把命令加入/etc/rc.local来实现开机自启动。

3.安装redsocks

安装redsocks并编辑配置文件。

$ sudo apt-get install redsocks
$ sudo nano /etc/redsocks.conf

修改配置文件的redsocks部分。


redsocks {
local_ip = 0.0.0.0;
local_port = 12345;
ip = 127.0.0.1;
port = 1088;
}

启动redsocks,确认ss和redsocks都启动

$ sudo service redsocks start
$ netstat -an|grep 1088
$ netstat -an|grep 12345

4.安装ipset并导入chnroute

科学上网的规则:凡是国外的网站都用shadowsocks加速。因此,我们借助于ipset保存国内ip段。

安装ipset,导出国内ip地址段,再导入到ipset

$ sudo apt-get install ipset
$ curl 'http://ftp.apnic.net/apnic/stats/apnic/delegated-apnic-latest' | grep ipv4 | grep CN | awk -F\| '{ printf("%s/%d\n", $4, 32-log($5)/log(2)) }' > chnroute.txt
$ sudo ipset create chnroute hash:net
$ cat chnroute.txt | sudo xargs -I ip ipset add chnroute ip

5.备份ipset并开机载入

导入ipset的过程非常缓慢,不适合每次开机都执行。我们可以将ipset的结果保存,每次开机导入。

$ sudo ipset save chnroute > /etc/chnroute.ipset

然后在/etc/rc.local中加入如下语句,实现开机启动。


ipset restore < /etc/chnroute.ipset [/highlight]

6.导入防火墙规则

sudo iptables -t nat -N SHADOWSOCKS

sudo iptables -t nat -A SHADOWSOCKS -d $server_IP -j RETURN

sudo iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN
sudo iptables -t nat -A SHADOWSOCKS -m set --match-set chnroute dst -j RETURN

sudo iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 12345

sudo iptables -t nat -A OUTPUT -p tcp -j SHADOWSOCKS
sudo iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS

其中$server_IP是你的VPS的地址,保存规则后确认可以正常翻墙。可把规则加载写入到/etc/rc.local中,实现开机重新生效防火墙规则。

在客户端连接此无线路由,开始自由自在的上网吧。

引用与感谢

没有网上前人大量的实验和分享的文章,俺绝对是没办法自己搞定树莓派无线路由的设置的,特别感谢以下博客文章。

1.来自Wannabe Nerd RandomnessWiFi access point using a Realtek 8192cu based USB WiFi dongle with a Raspberry Pi,本文关于Realtek 8192cu网卡的设置引用均来自此文章,thanks Jack Flushell for your great sharing.

2.本文科学上网设置部分引用于Tony Lee的博客文章用树莓派打造无线中继科学上网路由器,感谢Tony的分享,同在魔都,有缘的话自当结识。