从零开始,把Raspberry Pi打造成双栈11n无线路由器,支持教育网原生IPv6

准备工作

  1. Raspberry Pi一块
    • 要求已经刷写好了Raspbian系统,关于系统的刷写/无显示器配置这种事情,请参照这里,这里不想多说。
  2. USB无线网卡一枚,一个合格的USB无线网卡最好是不用USB HUB就能稳定运作的,插上之后,在终端机中输入ifconfig输出内容中应该有出现wlan0字样。
    • 无论你有没有现成的USB无线网卡,都请查看USB无线网卡对RPi兼容性列表来确定自己的USB无线网卡是不是支持RPi,如果是杂牌的话,要想办法看到自己的USB无线网卡的芯片型号,然后对照这个表里面有同样型号的无线网卡的兼容性说明。如果你现在无线网卡的芯片在这个表里面不是针对Raspbian out of box的,买买买,不要停~
    • AP功能是一定要有的,如果有11n的话更好(后面会讲如何设置),目前来说直到RPi 2 Model B都没有实装USB 3.0所以没有必要买ac的无线网卡。
    • 我用的是Tenda W311U+,这款有个天线,不过貌似也没啥太大的效果,用起来蛮稳定,速度一般(即使打开了11n机能)
  3. 外网,这篇教程针对的是没有认证的,原生支持IPv6的教育网,有固定IP。
    • 如果你的网络需要认证客户端的话,可以找个借口(用mac什么的)把认证取消,取消不了的话。。。别折腾了~(当然如果你真想折腾,openwrt社区里面会有dalao提供linux的模拟验证客户端,但是这个不在本文讨论之列)
    • 如果你是ADSL用户,本文没有拨号设定,IPv6也需要tunnel,这种情况,建议移步这里
    • 如果你不想折腾IPv6有关机能,忽略本文的IPv6部分即可,同样的,不想开11n的话,也可以忽略本文的11n设定部分。
  4. 确定你的有线无线网卡代号,在终端机中输入ifconfig就可以看到当前连接的所有网络接口,有线网络一般是eth开头,RPi的自带网卡一般是eth0,你连接的无线网卡一般是wlan开头,只插一个的话就是wlan0,这个是给内网用的。下文中的eth0和wlan0就是这么来的,如果不一样的话请自行翻译~

开工!先来配置IPv4无线路由

配置网络接口

在终端机中输入sudo emacs /etc/network/interfaces打开网络接口配置文件,狂按Ctrl+k清除全部内容,然后写入一下内容,完成后按Control+x,Control+c,y保存退出(放弃更改的话Ctrl+x,Ctrl+c,n,yes<换行键>)。

配置好之后,随便ping个网站看看能不能通外网,可以的话继续~

配置外网DNS

终端机中输入sudo emacs /etc/resolv.conf,在里面按下面的样子加上你需要的DNS地址

安装必要的软件包

这里假定你已经可以流畅的链接你的apt软件源了,如果官方源慢的要死就需要换源了,换源教程在这里
按你的需要在终端机中(有选择性地)输入如下命令:

编译工具

即便装了一堆也有可能发生有软件包装不了的情况,不过本文提到的需要编译的软件基本都能过。

编辑器

这俩选一个,或者都不选用系统自带地nano,我用emacs,我不想挑起战争~

AP与IPv4机能

 

IPv6机能

软件包

本文使用NPD Proxy和DHCPV6实现IPv6机能。

编译安装npd6

配置hostapd以使用无线网卡软AP

在终端机中输入sudo emacs /etc/default/hostapd,打开之后找DAEMON_CONF="",把这行首的#去掉,然后把这句话改成DAEMON_CONF="/etc/hostapd/hostapd.conf",保存退出。
在终端机输入sudo mkdir /etc/hostapd,然后sudo emacs /etc/hostapd/hostapd.conf,把文件内容(有的话清除,没有的话就从头写)改成(请仔细看注释有选择性地写~):

打开系统的IPv4转发功能

在终端机中输入sudo emacs /etc/sysctl.conf,直接在文件头写入以下内容:

然后退出回到终端机输入sudo sysctl -q让修改立即生效。

配置DHCP服务器实现内网IPv4地址自动分配

终端机中输入sudo emacs /etc/udhcpd.conf,你需要去掉下面这些行首的#来解除注释,然后按照自己的配置方法修改,注意要和interfaces文件里面wlan0的地址设定一致:

写一个bash脚本来一键打开无线路由机能,开机自动启动

在终端机输入emacs ~/router.sh,接下来写入:

保存,然后修改一下权限让他可以执行,输入sudo chmod 755 ~/router.sh就可以了。
接下来输入sudo emacs /etc/rc.local,在文件的末尾的exit 0这行上面,添加sudo /home/pi/router.sh保存退出。

重启测试

输入sudo reboot,不出意外的话重启之后你的设备可以正常连接你创建的无线网络上网了,802.11g,仅支持IPv4网络。
接下来会将IPv6和802.11n机能的开启,如果你有需要的话可以继续阅读。

配置IPv6实现无线双栈网络

查询外网IPv6地址和网关

Mac下可以插有线网络的话直接在设置里查看就可以了,Windows的话,命令行中输入ipconfig -all,如果你直接在RPi上看,终端机输入ifconfig就够了。纪录2001开头的IPv6地址和网关地址(我这里是fe80开头,有的情况下是2001开头,这个没关系,网关显示什么就记下来什么),Windows下IPv6地址后面可能会显示/64这个是prefix长度,这个也要记下来。

E560B6BE-A1F7-4730-B090-A06977F53DE8

修改sysctl.conf打开IPv6转发

终端机中输入sudo emacs /etc/sysctl.conf,然后添加:

改写router.sh,加入IPv6配置信息

在终端机输入emacs ~/router.sh,接下来写入:

注意,上面这些东西加在service这行前面,上面这5行中,2001:250:3000:3cc6:ba27:ebff:fee6:ce6c是我查到的公网IPv6地址,这个要原样打进去,/64和/126也不能变(除非你的网络非常特殊,64可能要改成你查到的perfix长度,126是不能动的,防止错乱),接下来2001:250:3000:3cc6:1::/80这个是你内网用的IPv6地址,前面四段要和你查到的公网地址保持一致,后面的那一段是你的内网网段,填1就可以了(当然你换什么填什么),接下来那个fe80开头的地址换成你查到的网关地址,这样就搞定了。

配置radvd

radvd的作用是使内网客户端能自动获取IPv6地址。终端机中输入sudo emacs /etc/radvd.conf然后写入:

注意上面的2001开头地址要换成你刚才设定好的内网地址。

配置npd6

npd6是邻居发现代理,是让内网客户端可以自动获取IPv6地址的。终端机中输入sudo emacs /etc/npd6.conf然后写入:

原文件中可能会用好多注释,不过没关系你只要对照上面把有效部分修改好就行了,注意2001开头那个地址要填你自己的

配置DHCPv6

DHCP是啥不用我多说了吧。终端机中输入sudo emacs /etc/wide-dhcpv6/dhcp6s.conf然后写入:

重启测试

sudo reboot,IPv6配置至此结束,没有异常的话在这里应该可以看到下图了吧。

D6A7F186-4E98-448E-A1E3-9E66BE9B4630

配置802.11n机能

检查无线网卡支持哪些802.11n机能

在终端机中输入iw list | less之后你应该会看到一堆,我们只关注开头Capabilities的这部分,一般长得像这样:

你要把这一段记下来,之后按q键结束。

修改hostapd配置文件增加802.11n机能支持

sudo emacs /etc/hostapd/hostapd.conf然后修改两行:

你去要重点关照的就是ht_capab这一行,这一行输入的越全面,你得到的速度就越快。
我在下面引用了官方文档的配置802.11n的部分,你可以对照这个和记好的iw list数据决定填什么,填好之后保存。sudo service hostapd reboot如果提示成功,说明配置没有问题,这个时候应该可以享受到高速度了,如果FAIL了,请仔细检查ht_capab是不是填写错了,如果实在不行,就删掉不确定的项,牺牲一些速度吧。
hostapd详细的配置方法可以参照官方文档,其实hostapd可以支持802.11ac的,但是问题在于USB2.0的传输速率使得在RPi上用ac没有意义。

收工

至此本文的目的已经达到,have fun!

本文系hahaschool原创,转载必须注明出处。

 

13 Comments

  1. kinian
    April 27, 2015

    你好,我按照你所提到的方法配置了,但是有点问题,麻烦你看一下。
    我的情况是这样的,我们学校提供的wifi支持ipv6 ,但是覆盖区域有限,所以我就打算在宿舍用 raspberry pi通过有线网络搭建一个支持ipv6 的接入点。
    我的手机是支持 ipv6 的,连接普通路由器能够看到fe80::开头的本地地址,连接:学校的wifi能够分配2001:开头的全球地址,ipv6 访问也没有问题。
    但是用 raspberry pi配置则有问题,分配不到全球地址,只有本地地址,不过奇怪的是我用笔记本连接 raspberry pi,一切都ok,能得到地址,访问也没问题,很奇怪。
    我之前听说 android不支持dhcp,只能用 neighbor discovery ,不知道是不是因为这个原因,还是其他什么原因,请帮我分析一下。

    Reply
    1. hahaschool
      April 28, 2015

      你好,
      十分抱歉我在文章中遗漏了一个细节,当你在sysctl中打开ipv6转发的时候,就会同时关闭rpi上面获取公网ipv6地址的机能,所以后文是手动用ip这个程序添加公网ipv6地址的,如果你没有手动添加公网地址显然客户端没有办法连接公网。
      实现ipv6路由的方法有很多种,本文这个也只是其中一种。npd6在正常地工作的话,客户端就可以正常地利用邻居发现了,同时要保证radvd这个路由广播服务正常否则ip地址也是送不过去的。你可以尝试重新启动或者前台监视radvd和npd6看一下有什么异常,我这边有时就会发生连接上网络之后,只有fe80,登录到rpi上重启radvd服务就恢复正常了,所以不排除radvd意外退出的可能。
      希望能对你有一定帮助,欢迎跟进。

      Reply
      1. Kinian
        April 28, 2015

        我想问一下我是按照你提到的/64和/126还有一个/80的后缀进行设置的,但是这几个数字是怎么确定的,和我这里的具体网络环境是不是有关系,还有/126这个感觉不是特别有意义的数字

        Reply
        1. hahaschool
          April 28, 2015

          你好,
          那个是前缀码长度,对于国内一般的校园网环境前缀码长度是64,分配给客户端的地址是直接在这个地址之下开一个网段,所以前缀码长度加了一段变成80,前缀码的部分不会改变,不受自动配置影响的。
          欢迎跟进。

          Reply
          1. kinian
            April 28, 2015

            那126有什么含义吗?

        2. hahaschool
          April 28, 2015

          你好,
          那个126就是防止ipv6地址错乱用的,意思就是固定这个公网地址不要变,我在参考别人配置时看见这一条就给加了上去。
          看来我在写ipv6配置方法那里还是有一些解释的不好的地方。。。我是折腾了好几天,看了各种版本的配置方法,最后试验出来一种有效的方法,如果你折腾这种方法无果,不妨尝试一下其他的比如brouter,nat6之类的。
          欢迎跟进。

          Reply
          1. kinian
            April 28, 2015

            不知道你的方法在 android下有没有测试过,我担心是不是 android和其他系统的原理不一样

          2. Kinian
            May 03, 2015

            你好,我现在这样处理的,把~/router.sh和/etc/radvd.conf中的/80都改成了/64

            还有/etc/npd6.conf中的prefix=2001:250:3000:3cc6:1:改成prefix=2001:250:3000:3cc6:

            这时我不清楚DHCPv6怎么设置,就暂时给关了。

            结果是使用PC和Android手机都能分配到ipv6地址,但是似乎不能访问外部的ipv6地址,请教一下我这样做有什么问题?

            我之前听说 android不支持dhcp,只能用 neighbor discovery,看来不能用dhcpv6给android分配地址

        3. hahaschool
          May 04, 2015

          你好,
          不能访问外部的原因是路由表设置的不正确,请检查router.sh中的route条目是否正确填写,同时请确保sysctl中已经打开了ipv6转发。

          Reply
  2. wanicca
    November 21, 2015

    您好,我在配置好后发现搜不到热点,用sudo hostapd /etc/hostapd/hostapd.conf 提示
    nl80211: Driver does not support authentication/association or connect commands
    nl80211 driver initialization failed.
    hostapd_free_hapd_data: Interface wlan0 wasn’t started

    求解决。:D

    Reply
  3. wanicca
    November 21, 2015

    您好,折腾一下午后,现在我可以连上树莓派了,然而ipv6功能迟迟不能正常使用。

    按照教程中的流程结束后,用电脑连接树莓派,检查连接属性如下
    连接特定的 DNS 后缀: local
    描述: Realtek RTL8723AE Wireless LAN 802.11n PCI-E NIC
    物理地址: ‎44-6D-57-9E-B8-8A
    已启用 DHCP: 是
    IPv4 地址: 192.168.156.127
    IPv4 子网掩码: 255.255.255.0
    获得租约的时间: 2015年11月21日 13:43:27
    租约过期的时间: 2015年12月1日 16:14:22
    IPv4 默认网关: 192.168.156.1
    IPv4 DHCP 服务器: 192.168.156.1
    IPv4 DNS 服务器: 10.0.0.10, 10.0.0.9
    IPv4 WINS 服务器: 192.168.156.10
    已启用 NetBIOS over Tcpip: 是
    连接-本地 IPv6 地址: fe80::f89a:3dea:68b3:5f0c%7
    IPv6 默认网关: fe80::a62:e569:8445:be23%7
    IPv6 DNS 服务器:

    在树莓派上ifconfig得到如下:
    eth0 Link encap:Ethernet HWaddr b8:27:eb:a6:a6:38
    inet addr:10.143.41.170 Bcast:10.143.41.255 Mask:255.255.255.0
    inet6 addr: 2001:da8:204:3334:b4f6:2af9:b08b:5b24/126 Scope:Global
    inet6 addr: fe80::ba27:ebff:fea6:a638/64 Scope:Link
    UP BROADCAST RUNNING ALLMULTI MULTICAST MTU:1500 Metric:1
    RX packets:28838 errors:0 dropped:1074 overruns:0 frame:0
    TX packets:20815 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:9119435 (8.6 MiB) TX bytes:4499897 (4.2 MiB)

    lo Link encap:Local Loopback
    inet addr:127.0.0.1 Mask:255.0.0.0
    inet6 addr: ::1/128 Scope:Host
    UP LOOPBACK RUNNING MTU:65536 Metric:1
    RX packets:136 errors:0 dropped:0 overruns:0 frame:0
    TX packets:136 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:0
    RX bytes:11472 (11.2 KiB) TX bytes:11472 (11.2 KiB)

    wlan0 Link encap:Ethernet HWaddr e8:4e:06:2b:a6:fd
    inet addr:192.168.156.1 Bcast:192.168.156.255 Mask:255.255.255.0
    inet6 addr: fe80::a62:e569:8445:be23/64 Scope:Link
    inet6 addr: 2001:da8:204:3334:1::/80 Scope:Global
    UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
    RX packets:34994 errors:0 dropped:15 overruns:0 frame:0
    TX packets:34991 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:1000
    RX bytes:6074205 (5.7 MiB) TX bytes:26770443 (25.5 MiB)

    并且树莓派上网正常,可以连接ipv6地址。
    设置完全按照教程所示,只是把ipv6的link和global地址换成我自己的了……
    求教,感激不尽。

    Reply
    1. hahaschool
      November 21, 2015

      可能有这么几种原因(也有可能都不是):
      ipv6 DNS没有被正确配置->需要手动设置dns地址
      ip6tables未放行->尝试停掉ip6tables服务,如果恢复正常,说明这里有问题,要补充相应ACCEPT

      第二种可能性偏大

      Reply
      1. wanicca
        November 22, 2015

        感谢回答~现在心情十分激动
        *_*小白表示并不了解ip6tables,有空去研究下……
        不过其实在您回复这段时间内,我又折腾出几种新情况……如果把所有涉及到前缀80长度的地址改回64长度,PC把网关设成wlan0的链路地址,这时PC便可以获得global ipv6地址,但是是前64位+MAC地址生成的后64位,即后64位与本地ipv6地址后4位相同。这种情况下依然不可以上网。(正常情况下是否应该分配到dhcp6s指定的地址池范围内的地址呢?)
        新的情况:在前缀长度80的情况下,手动给PC设置一个前5段与指定给wlan0的地址(2001开头)相同,后3段随机的ipv6地址,网关设指定给wlan0的地址(2001开头),奇迹发生了,PC的ipv6 Internet通了。(小白猜测这是否说明npd6正常工作,问题还是出在dhcp6s和radvd上?)

        Reply

Leave a Reply to wanicca Cancel reply

Scroll to top