清华本科生适用路由器配置指南

发布于2012年11月17日 -

如果你只是需要一个能在熄灯之后使用的路由器,请在网上买一个带电池的路由器,只要大约100元即可。

本解决方案主要包括:

  • 通过ISATAP隧道使用IPv6
  • 直接翻BEEP墙
  • 离线下载
  • 一个比较靠谱的DNS

如果读者对路由器有所了解,很可能会听说过OpenWrt这个东西。

OpenWrt是什么?

OpenWrt是适合于嵌入式设备的一个Linux发行版。

相对原厂固件而言,OpenWrt不是一个单一、静态的固件,而是提供了一个可添加软件包的可写的文件系统。这使使用者可以自由的选择应用程序和配置,而不必受设备提供商的限制,并且可以使用一些适合某方面应用的软件包来定制你的设备。对于开发者来说,OpenWrt是一个框架,開發者不必麻烦的构建整个固件就能得到想要的应用程序;对于使用者来说,这意味着完全定制的能力,與以往不同的方式使用设备。

以上摘自Wikipedia。

根据这段描述,我们知道,OpenWrt是一个Linux发行版,因此理论上几乎任何事情都可以通过OpenWrt来完成。但实际上,受到设备的限制(包括组件和性能等方面),人们通常会从更实际的角度考虑,它能做什么。

除了本文开始列出的一些功能外,在网上也能找到一些有趣的小玩意,包括遥控小车、视频监控等。当然,考虑到我们的实际需求,本文将不对这些新奇的想法展开描述。

路由器的选择

可以安装OpenWrt的路由器有很多,完整的列表可以在这里找到:

http://wiki.openwrt.org/toh/start

在挑选路由器前,我们需要再次明确我们的需求:

  • 不怕断电
  • 能装OpenVPN等程序

市面上有电池的路由器还是有一些的,例如TP-Link的MR11U、它的马甲——Mercury M301等。

而能装一些程序则是一个比较高的要求,因为通常路由器的Flash都很小,主流容量是4M,个别路由器甚至只有2M。这给我们在上面安装一个操作系统,再装一些程序带来了比较大的困难。因此,在一些论坛,经常可以看到有人动手改装路由器,换大一些的Flash,并增加内存。

这一次,我选择的是淘宝上,有人改装过的Mercury M301,改装后的Flash有16M,内存有64M,足够满足我们的全部需求。

预编译OpenWrt

在网上可以下载到很多人编译好的OpenWrt,但它们并不满足我们的需求。所以必须自行编译OpenWrt。

如果读者有过编译嵌入式Linux内核或其他嵌入式程序的经验,那么编译OpenWrt的体验则会相当好。我们不需要去找老旧的交叉编译器和旧版Linux内核,只需要使用简单的Make命令,即可编译出一个OpenWrt出来。

编译的教程在http://wiki.openwrt.org/doc/howto/buildroot.exigence,简单的流程如下:

1. 为了避免不必要的麻烦,装一个32位版本的Ubuntu,分区容量建议至少15GB。

2. 安装subversion和build tools,因为OpenWrt是存放在SVN上的。

$ sudo apt-get update
$ sudo apt-get install subversion build-essential

3. 使用SVN下载源码。

$ mkdir ~/openwrt
$ cd ~/openwrt
$ svn co svn://svn.openwrt.org/openwrt/trunk/
$ cd trunk

4. 下载安装feeds,feeds是OpenWrt的包。

$ ./scripts/feeds update -a
$ ./scripts/feeds install -a

5. 依次执行以下命令以完成配置:

$ make defconfig
$ make prereq
$ make menuconfig

此处可能会遇到一些包的缺失信息,只需要按照提示使用apt-get安装好即可。 6. 执行make来编译。

对于这个流程,有一些问题需要加以说明:

  • 从SVN上下载源码和feeds的文件大概有500MB,在make的时候还会下载大量包(根据menuconfig的选项而不同),因此请尽量使用一个快速的网络。
  • make的时候,很可能会因为网络的原因无法下载到需要的包而导致错误,这个时候,请使用make V=99编译,可以看到是哪个包下载失败,然后自行去网上找到这个包,放置在./dl目录下。
  • 可以使用make -j n(把n替换成CPU线程数+1)来多线程编译,但这样可能会难以找到错误的地方。
  • 流程第5步中的make menuconfig中需要选择包,我们在此时只要选择好路由器的型号,并选中IPv6下的radvd,其他的可以先不选择。这是因为,只有在第一次make的时候,编译脚本才会去网上下载Linux内核源码和相关的包,而我们接下来需要修改一些源码。
  • 修改openvpn的编译选项,以便openvpn能从文件中读取用户名和密码: 打开./package/feeds/packages/openvpn-devel/Makefile文件,在define Build/Configure段的若干选项中(例如在“--enable-small ”之后)增加一行“--enable-password-save ”。

要解决的问题

在我们的需求中,有一个需求是很特殊的——IPv6。在清华,IPv6是一个很奇葩的东西。在不少地方,我们可以使用到原生的IPv6,而且这个IPv6地址还是动态的。但遗憾的是,很多时候,IPv6还需要通过一个Portal来认证,而这个Portal总是不能正常工作。因此,很多人会选择适用ISATAP服务来访问IPv6。

如果使用Native IPv6,一切都很简单,我们只需要让IPv6桥接,让IPv4 NAT就可以了。

如果使用ISATAP,则问题变得很复杂:

  • 一方面,ISATAP得到的IPv6地址的前缀是64位,这意味着我们不能再划分子网。
  • 在RFC的文档中,IPv6是不支持NAT的。

于是,我们找到了北邮同学的一个解决方案:napt66。这个方案通过Netfilter,实现了一个私有的NAT服务。该方案的部署比较复杂,但幸运的是,作者给出了一个在OpenWrt上部署的文档。这里简单的总结如下(路径可能略有不同):

1. 修改Linux内核中IPv6转发的代码。该文件位于./build_dir/linux-arch/linux-version/net/ipv6/ip6_output.c,将以下两行注释掉:

if (net->ipv6.devconf_all->forwarding == 0)
    goto error;

更新:Linux 3.7开始,内核提供了对NAT6的原生支持。

2. 修改radvd的探测IPv6转发参数的代码。该文件位于./build_dir/target-mips_uClibc-version/radvd/radvd.c,注释掉以下部分(代码可能略有不同):

int check_ip6_forwarding(void) {
......
//    if (value != 1)
//        flog(LOG_DEBUG, "IPv6 forwarding setting is: %u, should be 1", value);
//        return -1;
//    }
......
}

3. 新建./package/base-files/files/etc/radvd.conf文件,内容如下:

interface br-lan { 
        AdvSendAdvert on;
        MinRtrAdvInterval 5; 
        MaxRtrAdvInterval 10;
        AdvManagedFlag off;
        AdvOtherConfigFlag off;
        AdvDefaultPreference high;
        prefix fc00:0101:0101::/64 { 
                AdvOnLink on; 
                AdvAutonomous on; 
                AdvRouterAddr on; 
        };
};

4. 下载napt66.zip,解压缩到./package/目录下,删除files目录,同时删除Makefile文件里的KernelPackage/napt66/install这一部分,因为我们需要自行配置。

至此,我们的准备工作全部就绪。

正式编译OpenWrt

再次运行make menuconfig,新选择以下包:

  • Base system
  • block-mount(自动挂载)
  • IPv6
  • firewall
    • ip6tables
  • LuCI
  • Collections
    • luci
  • Applications
    • luci-app-ntpc(NTP客户端,openvpn对时间有要求)
    • luci-app-transmission
  • Kernel modules
  • Filesystems
    • kmod-fs-ext4(移动硬盘推荐用此格式)
  • Native Language Support
    • kmod-nls-utf8
  • Netfilter Extensions
    • kmod-ip6tables
    • kmod-napt66
  • Network Support
    • kmod-ipip
    • kmod-iptunnel4
    • kmod-iptunnel6
    • kmod-ipv6
    • kmod-sit
    • kmod-tun
  • USB Support
    • kmod-usb-storage-extras
  • Network
  • BitTorrent
    • transmission-web
  • File Transfer
    • vsftpd(有FTP会方便很多)
  • Firewall
    • iptables
  • Routing and Redirection
    • ip
  • VPN
    • openvpn-devel-openssl

完成这些步骤之后就可以执行makemake -j n来编译。经过几分钟到几十分钟(视网络环境而定)的编译,即可在./bin/目录下,找到编译好的固件。

需要注意的是,这样编译出来的文件可能太大,而无法生成bin文件。所以根据路由器的型号,还可能需要修改生成固件镜像的代码,以我们选择的此款路由器为例:

1. 修改固件打包工具:打开./tools/firmware-utils/src/mktplinkfw.c,找到‘8Mlzma’,然后在这段下面添加一段16M的定义:

.id         = "16Mlzma",
.fw_max_len = 0xfc0000,
.kernel_la  = 0x80060000,
.kernel_ep  = 0x80060000,
.rootfs_ofs = 0x100000,

2. 修改Makefile: 打开./target/linux/ar71xx/image/Makefile,找到含有‘MR11U’的这一行,将行末的‘4Mlzma’改为‘16Mlzma’。

路由器配置

注:以下配置均以本文选定的路由器及清华实际的网络环境为例进行说明。

初始配置

将电脑的IP设置为192.168.1.2,然后访问http://192.168.1.1,直接登录,按照提示修改一个新密码。

然后在System->Software下卸载firewall,因为我们需要手动配置NAT。

建议使用ssh直接操作。

网络配置

网络配置主要包括/etc/config目录下的networkwirelessdhcp文件。

network文件如下:

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.1.1' option ip6addr fc00:0101:0101::1/64 option netmask 255.255.255.0

config interface 'wan' option ifname 'eth0' option proto 'static' option ipaddr 'your-ip' option netmask '255.255.255.0' option gateway 'your-gateway' option dns '8.8.8.8 8.8.4.4'

wireless文件如下:

config wifi-device 'radio0'
    option type 'mac80211'
    option channel '11'
    option hwmode '11ng'
    option path 'platform/ar933x_wmac'
    option htmode 'HT20'
    list ht_capab 'SHORT-GI-20'
    list ht_capab 'SHORT-GI-40'
    list ht_capab 'RX-STBC1'
    list ht_capab 'DSSS_CCK-40'
    option txpower '27'
    option country 'CN'

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

务必注意这里的第一段配置,请保持原有的参数。

dhcp文件的dhcp部分如下:

config dhcp 'wan'
    option interface 'wan'
    option ignore '1'

config dhcp 'lan' option start '100' option leasetime '12h' option limit '150' option interface 'lan'

至此,路由器已经能连通外网,也能给无线设备分配IP地址,但我们发现无线设备并不能访问外网,因为我们还没有配置NAT。

打开/etc/rc.local文件,在exit 0前加入:

iptables -t nat -F
iptables -t filter -F

iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -s 192.168.1.0/24 -j ACCEPT
iptables -A FORWARD -j REJECT

iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -j MASQUERADE

然后重启路由器即可。

IPv6配置

1. 配置ISATAP

在`/etc/rc.local`中加入:
ip tunnel add sit1 mode sit remote 59.66.4.50 local your-ip
ifconfig sit1 up
ifconfig sit1 add 2001:da8:200:900e:0:5efe:your-ip/64
ip route add ::/0 via 2001:da8:200:900e::1 metric 1

2. 启动IPv6转发和radvd

同样继续修改/etc/rc.local

sysctl -w net.ipv6.conf.br-lan.forwarding=1
radvd
insmod /lib/modules/3.3.8/napt66.ko wan_if=sit1

重启路由器之后IPv6应该就生效了。

其他配置

为了使用CDN,我们可以将一些国内网站交给学校的DNS去解析,只需要修改/etc/dnsmasq.conf文件为:

server=/cn/166.111.8.28
server=/100tjs.com/166.111.8.28
server=/115.com/166.111.8.28
server=/126.com/166.111.8.28
server=/126.net/166.111.8.28
server=/163.com/166.111.8.28
server=/17kuxun.com/166.111.8.28
server=/19lou.com/166.111.8.28
server=/2345.com/166.111.8.28
server=/360buy.com/166.111.8.28
server=/360buyimg.com/166.111.8.28
server=/39.net/166.111.8.28
server=/4399.com/166.111.8.28
server=/51.com/166.111.8.28
server=/51.la/166.111.8.28
server=/51buy.com/166.111.8.28
server=/51job.com/166.111.8.28
server=/56.com/166.111.8.28
server=/58.com/166.111.8.28
server=/admin5.com/166.111.8.28
server=/ads8.com/166.111.8.28
server=/aizhan.com/166.111.8.28
server=/alibaba.com/166.111.8.28
server=/alimama.com/166.111.8.28
server=/alipay.com/166.111.8.28
server=/apple.com/166.111.8.28
server=/arpg2.com/166.111.8.28
server=/baidu.com/166.111.8.28
server=/baixing.com/166.111.8.28
server=/bing.com/166.111.8.28
server=/bitauto.com/166.111.8.28
server=/cache.netease.com/166.111.8.28
server=/cctv.com/166.111.8.28
server=/china.com/166.111.8.28
server=/chinanews.com/166.111.8.28
server=/chinaz.com/166.111.8.28
server=/cmbchina.com/166.111.8.28
server=/cn/166.111.8.28
server=/cnbeta.com/166.111.8.28
server=/cnblogs.com/166.111.8.28
server=/cnzz.com/166.111.8.28
server=/csdn.net/166.111.8.28
server=/ct10000.com/166.111.8.28
server=/ctrip.com/166.111.8.28
server=/dangdang.com/166.111.8.28
server=/dianping.com/166.111.8.28
server=/discuz.net/166.111.8.28
server=/docin.com/166.111.8.28
server=/duowan.com/166.111.8.28
server=/eastmoney.com/166.111.8.28
server=/etao.com/166.111.8.28
server=/fastcdn.com/166.111.8.28
server=/ganji.com/166.111.8.28
server=/gtimg.com/166.111.8.28
server=/hao123.com/166.111.8.28
server=/hc360.com/166.111.8.28
server=/hiapk.com/166.111.8.28
server=/hoopchina.com/166.111.8.28
server=/huanqiu.com/166.111.8.28
server=/hudong.com/166.111.8.28
server=/icson.com/166.111.8.28
server=/ifeng.com/166.111.8.28
server=/iloveyouxi.com/166.111.8.28
server=/img.cctvpic.com/166.111.8.28
server=/iteye.com/166.111.8.28
server=/jysq.net/166.111.8.28
server=/kaixin001.com/166.111.8.28
server=/ku6.com/166.111.8.28
server=/lashou.com/166.111.8.28
server=/letv.com/166.111.8.28
server=/live.com/166.111.8.28
server=/love21cn.com/166.111.8.28
server=/lxdns.com/166.111.8.28
server=/meituan.com/166.111.8.28
server=/microsoft.com/166.111.8.28
server=/mop.com/166.111.8.28
server=/mosso.com/166.111.8.28
server=/msn.com/166.111.8.28
server=/nipic.com/166.111.8.28
server=/oeeee.com/166.111.8.28
server=/onlinedown.net/166.111.8.28
server=/paipai.com/166.111.8.28
server=/pchome.net/166.111.8.28
server=/pcpop.com/166.111.8.28
server=/pengyou.com/166.111.8.28
server=/pptv.com/166.111.8.28
server=/qidian.com/166.111.8.28
server=/qiyi.com/166.111.8.28
server=/qq.com/166.111.8.28
server=/qunar.com/166.111.8.28
server=/renren.com/166.111.8.28
server=/sina.com/166.111.8.28
server=/sogou.com/166.111.8.28
server=/sohu.com/166.111.8.28
server=/soku.com/166.111.8.28
server=/soso.com/166.111.8.28
server=/soufun.com/166.111.8.28
server=/taobao.com/166.111.8.28
server=/taobaocdn.com/166.111.8.28
server=/tenpay.com/166.111.8.28
server=/tmall.com/166.111.8.28
server=/tom.com/166.111.8.28
server=/tudou.com/166.111.8.28
server=/v.iask.com/166.111.8.28
server=/vancl.com/166.111.8.28
server=/verycd.com/166.111.8.28
server=/weibo.com/166.111.8.28
server=/wikipedia.org/166.111.8.28
server=/xinhuanet.com/166.111.8.28
server=/xunlei.com/166.111.8.28
server=/yahoo.com/166.111.8.28
server=/yesky.com/166.111.8.28
server=/ynet.com/166.111.8.28
server=/yocc.net/166.111.8.28
server=/youboy.com/166.111.8.28
server=/youdao.com/166.111.8.28
server=/youku.com/166.111.8.28
server=/zhaopin.com/166.111.8.28
server=/zhubajie.com/166.111.8.28
server=/sanguosha.com/166.111.8.28
server=/.phobos.apple.com/178.79.131.110