使用树莓派3构建校园网关路由器

RaspberryPi 2016-10-26

为什么我要采用树莓派3作为路由器

我原来的用的无线路由是WR841N, 刷了Openwrt, 用于锐捷认证和提供ipv4网络.
前些日子折腾在路由器后提供ipv6网络, 可是学校网络不支持relay mode, 因此只能在路由上配置NAT6.
然而NAT6是非常消耗资源的一项操作. 当北邮人PT下载跑满百兆带宽的时候, 路由器的负载就会上到5以上.
担心长时间路由器会HOLD不住, 所以萌生了购买了一个新的路由器的想法.
本来已经看好了MT7610a的小米路由mini, 但是转念一想为什么不用树莓派搭建一个网关呢.
成本并没有增加多少, 而且5V的供电也可以在没电之后继续使用移动电源使用.
更何况树莓派3的四核A53比起MT7610a的性能不知道好了多少倍.
以及我并不需要千兆无线, 而且MT7610a只有百兆有线.

除了树莓派3的其他选择

在同等价位来考虑, 其实香蕉派M2+其实是一个更好的选择.
香蕉派M2+的劣势下在于四核A7@1.2g比起树莓派3要差.
但是, 优势同样非常明显.
树莓派3的最大缺点就在于IO带宽, 其物理拓扑结构是主芯片引出一个USB2.0接口到网卡同时作为HUB引出四个USB口.
也就是说, 板载的网卡LAN9514和四个USB接口同时共用一个USB2.0的480Mbps带宽.
当需要进行大IO操作时, 劣势就明显的体现出来了.
香蕉派M2+的网卡以及两个USB口都是直连芯片的, 只受到AMBA带宽的限制.
根据我看到的实测数据大概可以达到60+MByte/s, 相比之下, 树莓派的实测数据只能到10+MByte/s.
如果需要更大的IO带宽, 那么最好还是右转上J1900这样的凌动x86, 大概也只要500左右.
除了IO带宽以外, 香蕉派M2+还板载8G emmc. 相比TF卡, 稳定性大大提升, 同时也省下买TF卡的钱.
不过我倒是有一大把闲置的TF卡, 其实倒不是什么问题.
以及, 在香蕉派上有官方提供的Android系统, 以后也可以改造成电视盒子使用.

至于, 为什么最后还是选择了树莓派...原因还是更好友好的社区支持嗯.
换而言之就是用的人多, 踩坑的概率小= =

硬件准备

树莓派3一只. USB有线网卡一只, TF卡8G一只, 5V2A电源一只(5V1A也可以)

开工

在系统的选择上, 我采用的是Openwrt的衍生系统LEDE.
根据官方Wiki的叙述, 大概就是Openwrt的一帮开发者看Openwrt的低效不爽, 自己另外开个新坑的感觉.
不过, 确实LEDE的内核版本会比Openwrt要新, 所以就用它了.

LEDE的下载地址: https://downloads.lede-project.org/snapshots/targets/brcm2708/bcm2710/
下载那个: lede-brcm2708-bcm2710-rpi-3-ext4-sdcard.img.gz 就好了√

安装请参考Openwrt Wiki: https://wiki.openwrt.org/toh/raspberry_pi_foundation/raspberry_pi
简述的话就是在Linux内:

dd if=lede-brcm2708-bcm2710-rpi-3-ext4-sdcard.img of=/dev/sd* bs=2M conv=fsync

值得注意的是, 这会更改TF卡的分区表, 如果有什么数据的话, 请做好备份.
默认的话, 会分出一个20M的/boot分区和一个256M的/分区. 显然没有很好的利用好TF卡的空间.
所以, 我们还需要重新对TF卡分个区. 这可以使用GParted做到:

sudo apt-get install gparted
sudo umount /media/username/* #使用GParted前先取消挂载
sudo gparted

只要File-Device选择TF卡, 然后右键分区, 选择Resize就可以调整分区大小了√

Wiki中还提供了一些有用的信息:
比如说可以通过GPIO连接串口:
115200 8N1

Pin 6Pin 8Pin 10
GroundTXRX

以及可以通过修改/boot/config.txt文件修改一些配置.

修改软件源

很遗憾, 官方默认的软件源在国内的普通网络情况下似乎是连不上的.
而且, 官方的软件是滚动更新的. 一旦换了内核版本简直就是噩梦...
特别是opkg还没有提供upgrade的功能_(:3」∠)_
所以, 我特意把我安装时的软件源镜像了一份存在了服务器上. 大概一共才500M不到吧√
地址是: http://raspberrypi.slkun.me/mirror/LEDE/20161119/
速度什么的另说...至少以后官方滚内核的时候, 可以保证还有旧的软件可以用.
服务会在我还在用这一版的前提下会一直提供的嗯.

新版的17.01和18.06已出, 该镜像不再维护

软件源的配置文件在: /etc/opkg/distfeeds.conf

src/gz reboot_core http://raspberrypi.slkun.me/mirror/LEDE/20161119/core/
src/gz reboot_base http://raspberrypi.slkun.me/mirror/LEDE/20161119/base
src/gz reboot_telephony http://raspberrypi.slkun.me/mirror/LEDE/20161119/telephony
src/gz reboot_packages http://raspberrypi.slkun.me/mirror/LEDE/20161119/packages
src/gz reboot_routing http://raspberrypi.slkun.me/mirror/LEDE/20161119/routing
src/gz reboot_luci http://raspberrypi.slkun.me/mirror/LEDE/20161119/luci
#src/gz reboot_usr http://raspberrypi.slkun.me/mirror/LEDE/20161119/usr

usr目录是打算放我自己编译的一些软件, 现阶段就是mentohust咯.
请手动下载安装, 目前还没有配置Packages信息.

网络配置

默认配置的树莓派的网口为lan口, 是一个静态的192.168.1.1的ip, 没有dhcp服务器也没有dhcp客户端.
而且默认配置的LEDE也没有安装luci, 只能通过SSH登录.
因此, 需要修改/etc/config/network文件将其修改成为dhcp客户端模式以能够连上网.

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

config globals 'globals'
        option ula_prefix 'fd8f:4e62:2b25::/48'

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

这样只要把树莓派的lan口连上可以上网的路由器就可以了.

LEDE内部配置

系统镜像准备好之后, 把TF卡插进树莓派, 然后上电.
通过查看路由器的DHCP表来获得树莓派的ip, 当然也可以在网络配置时采用静态ip.
但是需要注意配置正确的网关, 不然内网可以访问到树莓派, 但是树莓派不能通过路由上网.

硬件驱动

我用的USB网卡是ASIX AX88772B, 虽然很廉价, 但是基本上也能够跑满100M的带宽.
确认路由器可以连上网以后, 安装驱动:

opkg update
opkg install kmod-usb-net kmod-usb-asix

这样使用ifconfig就可以看到eth1的第二张网卡了.

安装Luci

opkg install luci luci-i18n-base-zh-cn luci-i18n-firewall-zh-cn luci-theme-material

安装一些实用工具

opkg install ipset vim-full git git-http zsh curl libustream-openssl
opkg install wpad

安装Mentohust

ipk包可以从镜像下的usr分类下下载.

opkg install mentohust luci-luci-app-mentohust

注意不要直接使用mentohust的交互式命令行输入用户名和密码.
该编译版本与shell不太兼容, 我也懒得去找为什么.
直接使用/etc/mentohust文件配置, 或者通过luci就好.

安装ipv6 NAT支持

opkg install kmod-ipt-nat6

添加启动时脚本到/etc/rc.local

#!/bin/sh /etc/rc.common

# For enable mentohust for sure at startup
MAX_TRIES=60
COUNT=1
PING_TEST=$(ping -w 3 www.baidu.com | grep "3 packets transmitted, 3 packets received")

# detecting internet is ok
while [ ! -n "$PING_TEST" ]
        do
        if [ $COUNT -gt $MAX_TRIES ]
        then
                logger -t MENTOHUST "Cannot access the Internet (reached retry limit $MAX_TRIES times)" && exit 1
        fi
        mentohust -k
        sleep 10
        mentohust -d
        sleep 60
        logger -t MENTOHUST "Try to connect the Internet... ($COUNT time)"
        COUNT=$((COUNT+1))
        PING_TEST=$(ping -w 3 www.baidu.com | grep "3 packets transmitted, 3 packets received")
done
logger -t MENTOHUST "Internet is accessible!"

# NAT6 init script for OpenWrt 
# Depends on package: kmod-ipt-nat6 ip6tables
# Ref:  https://wiki.openwrt.org/doc/howto/ipv6.nat6

MAX_TRIES=60
WAN6_NAME="wan6" 
WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.ifname") 
LAN_ULA_PREFIX=$(uci get network.globals.ula_prefix)
PROBE=0
COUNT=1

# detecting ipv6
while [ $PROBE -eq 0 ]
        do
        if [ $COUNT -gt $MAX_TRIES ]
        then
                logger -t NAT6 "No IPv6 route found (reached retry limit $MAX_TRIES times)" && exit 1
        fi
        sleep 30
        logger -t NAT6 "detect IPv6 route... ($COUNT time)"
        COUNT=$((COUNT+1))
        PROBE=$(route -A inet6 | grep -c '::/0')
done

ip6tables -t nat -I POSTROUTING -s "$LAN_ULA_PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
logger -t NAT6 "configure the IPv6 NAT table: $LAN_ULA_PREFIX at $WAN6_INTERFACE"

WAN6_GATEWAY=$(ifconfig "$WAN6_INTERFACE" | grep 'Global' | awk '{print $3}'| awk -F':' '{print $1":"$2":"$3":"$4"::1"}')
logger -t NAT6 "get the gateway of IPv6: $WAN6_GATEWAY"

route -A inet6 add default gw "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
logger -t NAT6 "set the gateway of IPv6: $WAN6_GATEWAY at $WAN6_INTERFACE"

logger -t NAT6 "IPV6 Configure done!"

exit 0

前一部分是刚开机时(早上来电时)如果发现认证不成功没有网, 就反复尝试认证直到成功为止.
第二部分是判断网络是否存在ipv6, 如果存在则建立ipv6 NAT转发.

配置网络

最后需要把网口做出合理的分配. /etc/config/network

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

config globals 'globals'
    option ula_prefix '1111:2222:3333:4444::/64'

config interface 'lan'
    option ifname 'eth1'
    option force_link '1'
    option type 'bridge'
    option proto 'static'
    option ipaddr '192.168.1.1'
    option netmask '255.255.255.0'
    option ip6assign '64'

config interface 'wan'
    option ifname 'eth0'
    option proto 'dhcp'
    option hostname 'Raspberry_Pi'
    option peerdns '0'
    option dns '223.5.5.5 208.67.222.220 202.114.0.242'

config interface 'wan6'
    option ifname 'eth0'
    option proto 'dhcpv6'

结束

完成配置之后重启, 将wan口接在树莓派本身的网口上, 下级交换机/路由器接在USB无线网卡上就可以正常工作. 其他关于Openwrt的配置就自己发挥想象咯.
在树莓派上, 性能和存储容量基本上不是问题, 唯一的限制点就是IO带宽了.
如果要挂移动硬盘之类的, 请注意供电和速度, 或者直接上香蕉派/凌动工控主板就好了.


本文由 SLKun 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

2 条评论

  1. hkrept
    hkrept

    您好,我有些问题想向您请教,用邮箱联系您了。

    1. SLKun
      SLKun

      我没有收到你的邮件.

添加新评论