一波三折的校园网IPv6 x 华硕 AC86U 您所在的位置:网站首页 梅林路由器设置ap 一波三折的校园网IPv6 x 华硕 AC86U

一波三折的校园网IPv6 x 华硕 AC86U

2023-08-07 06:08| 来源: 网络整理| 查看: 265

一波三折的校园网IPv6 x 华硕 AC86U 2018-11-20 17:54:38 32点赞 141收藏 65评论 购买理由

开学搬到了新宿舍,一看网口是千兆的一波三折的校园网IPv6 x 华硕 AC86U ,再加上自己之前也买了小米台灯,开关等,还有远程访问实验室NAS和游戏需求,开始寻思买一台高性能路由器。被张大妈各种毒文案例,就像四千预算进卡吧一样,路由器预算一度从200块的TP-Link路由器加钱到了AC86U。终于在双十一之前忍不住剁手。

一波三折的校园网IPv6 x 华硕 AC86U华硕(ASUS)RT-AC86U 游戏路由 2900M双频全千兆低辐射/智能无线游戏路由器/MU-MIMO吃鸡路由/支持AiMesh1099元京东去购买

买回来火速设置一波,第一次用这么高级的路由器有点小激动一波三折的校园网IPv6 x 华硕 AC86U 。首当其冲就是刷入梅林,设置IPv6,结果踏入了一个深坑。这里先插一句,关于梅林固件,作者的网站是。从这个网站下载的是原版梅林固件。固件代码都是开源的,可以从Github上看到。接下来步入正题。

坑爹的校园网

AC86U支持的设置IPv6方式有下图几种,理论上覆盖了绝大多数网络情况,有很多学校的同学直接选择Passthrough就可以使用。

IPv6 支持姿势IPv6 支持姿势

如果你所在学校可以通过上述任意一种方法正常使用IPv6,那很好,这篇文章就不用再看啦。(当然你也可以来感受一下这个姿势,说不定也想试试呢一波三折的校园网IPv6 x 华硕 AC86U )。但是,凡事就怕但是,如果上面的姿势都不管用,那么或许这篇文章就能帮到你啦。

我所在学校宿舍的校园网用了一种叫做DHCPv6的姿势来给大家分配校园网,而且还只给每一个客户端分配一个IP,天啊,IPv6那么多地址,为什么只给一个!于是就悲剧了,路由器自带的IPv6选项在我的网络情况下都不可用。那么第一步就是确定你的网络环境是什么。最简单的方法就是打开你的网络设置,如果你发现你的IPv6前缀是128位,又或者如果你发现路由器自带的IPv6选项在你的网络环境中都用不了,那么就很有可能是跟我一样的网络环境了。

IPv6 信息IPv6 信息

在这种网络环境下,除了NAT这样比较不符合IPv6精神的做法之外,唯一可用的就是桥接模式。也就是让路由器在IPv6网络上像一台交换机一样工作,这样就能无缝接入校园网IPv6啦。网上有很多配置桥接模式的方法,AC86U也十分简单,通过ssh(关于如何ssh站内已经有很多文章介绍了,我就不重复说明啦)登陆到路由器上,在/jffs/scripts/wan-start脚本中添加下面两行命令就可以轻松搞定~

ebtables -t broute -A BROUTING -i eth0 -p ! ipv6 -j DROP

brctl addif br0 eth0

重启路由之后就可以开心的使用IPv6啦!但是!这个时候路由器就没办法获取IPv6了,你的NAS只有IPv6地址,又想在路由器上用,就很尴尬了,所以需要有一个特殊姿势让路由器在桥接模式下也获取到IPv6。由于之前在学校只学过理论知识,只知道理论可行,但是对实现不了解。恰好因为华硕路由器使用了openwrt,由于开源协议的限制,华硕自己的固件也要开源(所以才有了梅林),这样一来就可以通过围观固件源码的方法搞定这件事情了!下面就以AC86U为对象,介绍怎么在开启IPv6桥接模式的情况下为路由器获取IPv6地址。

首先要做一些准备工作:

将路由器的 IPv6 设置为 passthrough。然后通过 ssh 登陆路由器,运行下面这行命令

ps | grep odhcp6c

你应该会看到有类似这样一行输出

odhcp6c -df -R -s /tmp/dhcp6c -N try -c 000300010123d231c3a3 -r23 -r24 -r82 -r83 br0

其中有一串字符 000300010123d231c3a3,这串字符是你的设备ID,记下来这串字符,稍后要用到。

然后关闭路由器的IPv6功能。复制下面这一大长串脚本到你的/jffs/scripts/wan-start脚本中,一定要记得把最后一行的设备ID替换成你在准备工作里面获取到的ID,保存!重启!你会发现路由器自己也获取到IPv6地址了,LAN里的设备也正常获取到了IPv6地址!

#!/bin/sh

# IPv6 bridge ebtables -t broute -A BROUTING -i eth0 -p ! ipv6 -j DROP brctl addif br0 eth0

# enable IPv6 on eth0 echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6 echo 2 > /proc/sys/net/ipv6/conf/eth0/accept_dad echo 2 > /proc/sys/net/ipv6/conf/eth0/dad_transmits echo 1 > /proc/sys/net/ipv6/conf/eth0/accept_ra echo 0 > /proc/sys/net/ipv6/conf/eth0/forwarding # see lan.c config_ipv6 echo 0 > /proc/sys/net/ipv6/conf/br0/disable_ipv6 echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6 echo 0 > /proc/sys/net/ipv6/conf/default/disable_ipv6 echo 2 > /proc/sys/net/ipv6/conf/br0/accept_dad echo 2 > /proc/sys/net/ipv6/conf/br0/dad_transmits # set_default_accept_ra echo 1 > /proc/sys/net/ipv6/conf/all/accept_ra echo 1 > /proc/sys/net/ipv6/conf/default/accept_ra echo 0 > /proc/sys/net/ipv6/conf/all/forwarding # Allow router get IPv6 Address # When user disable IPv6, system will set ip6tables ALL policy to DROP # wait after that, then set our firewall sleep 10 # set up firewall ip6tables -P INPUT ACCEPT ip6tables -P OUTPUT ACCEPT

ip6tables -A OUTPUT -p tcp -j ACCEPT ip6tables -A OUTPUT -p udp -j ACCEPT # input rules ip6tables -A INPUT -p ipv6-crypt -j ACCEPT ip6tables -A INPUT -p ipv6-auth -j ACCEPT ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT ip6tables -A INPUT -m state --state NEW -j ACCEPT ip6tables -A INPUT -m state --state INVALID -j DROP # allow DHCPv6 ip6tables -A INPUT -p udp --sport 547 --dport 546 -j ACCEPT ip6tables -A INPUT -p udp --sport 500 --dport 500 -j ACCEPT ip6tables -A INPUT -p udp --sport 4500 --dport 4500 -j ACCEPT # allow ipv6-icmp related packet ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type packet-too-big -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type time-exceeded -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type parameter-problem -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-request -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type echo-reply -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 130 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 131 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 132 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-solicitation -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type router-advertisement -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbour-solicitation -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type neighbour-advertisement -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 141 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 142 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 143 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 148 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 149 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 151 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 152 -j ACCEPT ip6tables -A INPUT -p ipv6-icmp --icmpv6-type 153 -j ACCEPT ip6tables -A INPUT -j DROP

# Start DHCPv6 for LAN on br0 # In my enviroment, IPv6 address spwan from a DHCPv6 server odhcp6c -df -R -s /tmp/dhcp6c -N try -c 你的设备ID -r23 -r24 -r82 -r83 br0

张大妈没有贴代码的选项,大家凑合看吧一波三折的校园网IPv6 x 华硕 AC86U

原理解释

这一段较为硬核,需要一定的专业知识,可以跳过不影响你使用。方便好奇的同学了解背后的原理,并根据自己的设备因地制宜的修改设置。

接下来我会解释上面这个脚本在让路由获取IPv6地址的部分过程中都做什么,为什么这样做。在我的网络环境里,只有把路由器设置为 IPv6 passthrough 的时候路由器能正确获取 IPv6 地址。所以需要弄清楚这个模式做了什么操作。好在华硕固件是开源的,可以直接从官网下载。下文的讨论基于写这篇文章时能拿到的最新固件 3.0.0.4.384.32797 的源码。可以到官网支持页面选择操作系统为“其他”就可以看到源码下载链接。由于梅林是基于华硕固件源码的小改版本,也可以直接看梅林仓库的代码。

拿到了源码,直接搜索 PASSTHROUGH 关键字,发现启动 IPv6 Passthrough 的代码在 asuswrt/release/src/router/rc/wan.c下面,快速过一遍 IPv6 相关的代码,发现 IPv6 的设置主要有以下几个方面。

首先是开启IPv6,设置了accept_ra, forwarding一些字段。这些字段的意义都可以 Google 到。比如下面代码中设置的字段是互斥的,一个为1另一个就得为0。这两个字段决定了系统是工作在路由状态还是工作在主机状态。ra 是 router advertisement 的缩写,是 IPv6 网络用来自动配置路由的协议。我们想让路由器在LAN的状态像主机一样获取到 IP,就需要将路由器设置为主机状态,请求路由配置。

case IPV6_PASSTHROUGH: #endif ipv6_sysconf(wan_ifname, "accept_ra", 1); ipv6_sysconf(wan_ifname, "forwarding", 0);

代码中还有很多设置IPv6 相关配置的地方, 分散在各处,就不一一列出来了。总结下来就是分别在 WAN 口 和 LAN 口设置下面的相关参数。相关的代码可以在lan.c 和 wan.c 中找到。下面这段脚本就是用来设置对应参数的。

# enable IPv6 on eth0 echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6 echo 2 > /proc/sys/net/ipv6/conf/eth0/accept_dad echo 2 > /proc/sys/net/ipv6/conf/eth0/dad_transmits echo 1 > /proc/sys/net/ipv6/conf/eth0/accept_ra echo 0 > /proc/sys/net/ipv6/conf/eth0/forwarding # see lan.c config_ipv6 echo 0 > /proc/sys/net/ipv6/conf/br0/disable_ipv6 echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6 echo 0 > /proc/sys/net/ipv6/conf/default/disable_ipv6 echo 2 > /proc/sys/net/ipv6/conf/br0/accept_dad echo 2 > /proc/sys/net/ipv6/conf/br0/dad_transmits # set_default_accept_ra echo 1 > /proc/sys/net/ipv6/conf/all/accept_ra echo 1 > /proc/sys/net/ipv6/conf/default/accept_ra echo 0 > /proc/sys/net/ipv6/conf/all/forwarding

其次是开启relay功能,顺着 wan.c 再往下看,到了配置 IPv6 passthrough 的代码

case IPV6_PASSTHROUGH: start_6relayd(); /* fall through */ #endif case IPV6_NATIVE_DHCP: start_dhcp6c();

这段代码做了两步操作,第一步是启动了 6relayd ,可以确认华硕是用 6relayd 做的中继,据论坛用户表示该项目不是很稳定,并且在我的网络环境无法实现中继;第二步是启动了 DHCPv6 客户端,为特定的端口分配IP。具体代码实现太长,这里贴出一小部分

int start_dhcp6c(void) { char *wan_ifname = (char *) get_wan6face(); char *dhcp6c_argv[] = { "odhcp6c", "-df", "-R", "-s", "/tmp/dhcp6c", "-N", "try", NULL, NULL, /* -c duid */ NULL, NULL, /* -FP len:iaidhex */ NULL, NULL, /* -rdns -rdomain */ NULL, NULL, /* -rsolmaxrt -r infmaxrt */ NULL, /* -v */ NULL, /* interface */ NULL }; int index = 7; struct duid duid; char duid_arg[sizeof(duid)*2+1]; char prefix_arg[sizeof("128:xxxxxxxx")]; int service; ...

可以看到路由器使用 odhcp6c 为自己在 WAN 口上获取IP。这个时候可以脑补这段代码获取参数值,这样比较麻烦且容易出错,所以才出现了配置部分一开头的使用ps | grep odhcp6c 查看参数的trick。经过多次验证参数是不变的,所以可以通过这个方法获取启动 odhcp6c 客户端的参数表。有一点主要注意的是默认情况下我们是为 WAN 口绑定 IP,而本文中的网络情况是 WAN 口 与 LAN 口已经被桥接在一起了,在 IPv6 的层面已经没有了内外网的区分。所以应为网桥,也就是 br0 绑定IP。

最后还需要调整防火墙设置,因为当路由器关闭了 IPv6 功能后,会默认过滤丢弃掉所有的 IPv6 数据包,所以还需要设置对应的防火墙规则。设置防火墙规则的代码散落在各处,找起来十分麻烦,且很难找全,所以祭出查看 odhcp6c 参数的方法,通过运行ip6tables -L 查看 filter 表中所有的规则,然后手写一份一样的出来就可以啦,于是就有了上面那一大长串 IPv6 的过滤规则。

最终,通过看源码可以梳理出来路由器在设置 IPv6 passthrough 后的行为如下

修改系统设置,启用所有端口的 IPv6 功能

添加防火墙规则,允许 IPv6 数据包通过路由器

开启 DHCPv6 客户端,为路由器申请IP地址

所以按照这些步骤,就可以自己手动设置桥接后的路由器通过HDCPv6服务申请IPv6 地址,还顺便复习了一波计算机网络的知识2333。

未经授权,不得转载


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有