HNU 新校园网使用 OpenWRT 配置 IPv6 指南
November 4, 2025
Table of Contents
Table of Contents
配置前须知: 本教程适用于 2025 年 9 月更新后的湖南大学新校园网,未来校园网络依然有更新可能,本教程可能也失效,其他高校的网络也有可能适用 or 不适用。
且在新的校园网情况下,配置 IPv6 并不一定能提高网速,而且也不一定能省钱。
接续 cyp 学长的 HNU 校园网 IPv6 免流教程 2.0,写一下自己配置 HNU 新校园网的 IPv6 教程,对校园网账号和电信宽带账号都适用。 参考了这位知乎大佬的指南: 校园网环境下 Openwrt 配置 ipv6教程——以 nat6为例,这篇指南对 HNU 新校园网同样适用,我只是做了一点小修改。 你也可以结合我的一篇旧文章:使用小米 AX3000T 配置 Openwrt 接入 HNU 新校园网食用~
不过配置前须注意,在我所在的天马园区的宿舍楼,校园网 IPv6 比较不稳定,获取都有点看运气……
且在当今 HNU 的网络环境下,你很难保证教育网 IPv6 的高可用性,也许它在宿舍的效果可能网速比 IPv4 网络还差,且访问一些网站丢包卡顿高延迟 (至少在我的宿舍里是这样……)。 经个人测试,在研究生楼,HNU 的校园网络表现最好,且教育网 IPv6 也发挥了不限速的实力,网速甚至达到过 300Mbps 的速度!(比宿舍100兆限速好太多……) 不过这也是看运气的事情,没准在你的宿舍网络更好呢🤔。 当然,如果你想要更好的内网穿透,有一个 IPv6 地址可以有巨大的提升,不过这也是后话了。
IPV6 接口设置
wan6 接口配置 DHCPv6
当你刷好了路由器的 openwrt 配置好了 wan 和 lan 基本上设置,或者桥接的 wwan 的设置,打开接口→wan6,设置设备为 @wwan,协议选择 DHCPv6 客户端,如图配置请求 IPv6 地址和请求 IPv6 前缀。基本配置如图:

然后我们需要前往高级设置,配置一下IPv6分配长度设定为64。如图配置。

lan 接口分配 IPv6
我们需要前往高级选项,将 IPv6分配长度设定为64,然后前往 DHCP 服务器进行一些配置。

然后选择 DHCP 服务器,勾选动态 DHCP,以及强制。

然后前往 IPv6 配置,如图勾选指定的主接口,然后 RA 服务 和 DHCPv6服务 选择为服务器模式,禁用 NDP 代理,不要选指定的主接口。
然后在 RA 设置里,如图配置:
然后前往接口→全局网络选项,修改一下 IPv6 ULA 前缀,我这里直接跟随教程修改为fd34:fe56:7891:2f3a::/64。可以照抄。
这是内网 IPv6 地址,只要不冲突就无伤大雅。
如果想要更规范,可以用默认的。

这样,下面的设备就可以拿到 ip 为 fd34开头的 inet6地址。
防火墙配置
前往网络→防火墙,如图配置,把各种入站数据出站数据区域内转发都改为接受,然后 wan 那里配置勾选 IP 动态伪装。

内网 NAT6的配置
这是我自己使用 HNU 网络情况修改的脚本版本,增加了一些鲁棒性:
#!/bin/sh /etc/rc.common
# NAT6 init script for OpenWrt // Depends on package: kmod-ipt-nat6
# edited by Sad Pencil at 2020-02-09
# replace route command with ip command to solve issues on new OpenWRT
# edited by Sad Pencil at 2021-11-29
# update line WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.device" || uci get "network.$WAN6_NAME.ifname")
START=55
# Options
# -------
# Use temporary addresses (IPv6 privacy extensions) for outgoing connections? Yes: 1 / No: 0
PRIVACY=1
# Maximum number of attempts before this script will stop in case no IPv6 route is available
# This limits the execution time of the IPv6 route lookup to (MAX_TRIES+1)*(MAX_TRIES/2) seconds. The default (15) equals 120 seconds.
MAX_TRIES=15
# An initial delay (in seconds) helps to avoid looking for the IPv6 network too early. Ideally, the first probe is successful.
# This would be the case if the time passed between the system log messages "Probing IPv6 route" and "Setting up NAT6" is 1 second.
DELAY=5
# Logical interface name of outbound IPv6 connection
# There should be no need to modify this, unless you changed the default network interface names
# Edit by Vincent: I never changed my default network interface names, but still I have to change the WAN6_NAME to "wan" instead of "wan6"
WAN6_NAME="wan6"
# ---------------------------------------------------
# Options end here - no need to change anything below
boot() {
[ $DELAY -gt 0 ] && sleep $DELAY
# --- 第一步:获取 WAN6_INTERFACE ---
WAN6_DEVICE_REF=$(uci get "network.$WAN6_NAME.device" 2>/dev/null)
if [ -n "$WAN6_DEVICE_REF" ]; then
# 存在 device 选项,检查是否为引用
if [[ "$WAN6_DEVICE_REF" == @* ]]; then
REFERENCED_IFACE=${WAN6_DEVICE_REF:1}
# 获取被引用接口的实际 device 名称 (例如:phy0-sta0)
WAN6_INTERFACE=$(uci get "network.$REFERENCED_IFACE.device" 2>/dev/null)
else
# 直接使用 device 名称
WAN6_INTERFACE=$WAN6_DEVICE_REF
fi
else
# 原作者的逻辑:如果 device 找不到,尝试 ifname
WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.ifname" 2>/dev/null)
fi
# 确保 WAN6_INTERFACE 最终被设置 (如果 uci 找不到,OpenWrt 接口名称可能就是 wan6)
if [ -z "$WAN6_INTERFACE" ]; then
WAN6_INTERFACE=$WAN6_NAME
fi
# 注意:上面这段代码替换了您原脚本中获取 WAN6_INTERFACE 的部分
PROBE=0
COUNT=1
while [ $PROBE -eq 0 ]
do
if [ $COUNT -gt $MAX_TRIES ]
then
logger -t NAT6 "Fatal error: No IPv6 route found (reached retry limit)" && exit 1
fi
sleep $COUNT
COUNT=$((COUNT+1))
PROBE=$(ip -6 route | grep -i '^default.*via' | grep -i -F "dev $WAN6_INTERFACE" | grep -i -o 'via.*' | wc -l)
done
logger -t NAT6 "Setting up NAT6"
if [ -z "$WAN6_INTERFACE" ] || [ ! -e "/sys/class/net/$WAN6_INTERFACE/" ] ; then
logger -t NAT6 "Fatal error: Lookup of $WAN6_NAME interface failed. Were the default interface names changed?" && exit 1
fi
# 替换原作者的硬编码:
# WAN6_GATEWAY=$(ip -6 route |grep -o '2001.*1102'|sed s'/1102/1101::1/g')
# 尝试获取接口上的全局 IPv6 地址
MY_IPV6_ADDR=$(ip -6 addr show dev $WAN6_INTERFACE | grep -oP 'scope global\s+\K[^/]+' 2>/dev/null)
if [ -n "$MY_IPV6_ADDR" ]; then
# 提取前缀(前四个字段),例如 2001:250:4402:1119
IPV6_PREFIX=$(echo $MY_IPV6_ADDR | cut -d: -f-4)
# 构造推算的全局网关:前缀 + ::1
WAN6_GATEWAY="${IPV6_PREFIX}::1"
else
# 如果没有找到全局地址,则 WAN6_GATEWAY 保持为空
WAN6_GATEWAY=""
fi
# 检查是否推算成功
if [ -z "$WAN6_GATEWAY" ] ; then
logger -t NAT6 "Fatal error: Cannot derive global IPv6 gateway for $WAN6_INTERFACE. Check if a global IPv6 address is assigned." && exit 1
fi
LAN_ULA_PREFIX=$(uci get network.globals.ula_prefix)
if [ $(echo "$LAN_ULA_PREFIX" | grep -c -E "^([0-9a-fA-F]{4}):([0-9a-fA-F]{0,4}):") -ne 1 ] ; then
logger -t NAT6 "Fatal error: IPv6 ULA prefix $LAN_ULA_PREFIX seems invalid. Please verify that a prefix is set and valid." && exit 1
fi
ip6tables -t nat -I POSTROUTING -s "$LAN_ULA_PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
if [ $? -eq 0 ] ; then
logger -t NAT6 "Added IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)"
else
logger -t NAT6 "Fatal error: Failed to add IPv6 masquerading rule to the firewall (Src: $LAN_ULA_PREFIX - Dst: $WAN6_INTERFACE)" && exit 1
fi
ip -6 route add 2000::/3 via "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Added $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
else
logger -t NAT6 "Error: Failed to add $WAN6_GATEWAY to routing table as gateway on $WAN6_INTERFACE for outgoing connections"
fi
if [ $PRIVACY -eq 1 ] ; then
echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/accept_ra"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Accepting router advertisements on $WAN6_INTERFACE even if forwarding is enabled (required for temporary addresses)"
else
logger -t NAT6 "Error: Failed to change router advertisements accept policy on $WAN6_INTERFACE (required for temporary addresses)"
fi
echo 2 > "/proc/sys/net/ipv6/conf/$WAN6_INTERFACE/use_tempaddr"
if [ $? -eq 0 ] ; then
logger -t NAT6 "Using temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
else
logger -t NAT6 "Error: Failed to enable temporary addresses for outgoing connections on interface $WAN6_INTERFACE"
fi
fi
exit 0
}
复制完毕后去 ssh 上去路由器,然后 vi /etc/init.d/nat6, I 后复制到脚本里再 :wq 退出,然后设定权限:
chmod +x /etc/init.d/nat6
/etc/init.d/nat6 enable
然后用 vim 继续 vi /etc/sysctl.conf
在最后又添加:
net.ipv6.conf.default.forwarding=2
net.ipv6.conf.all.forwarding=2
net.ipv6.conf.default.accept_ra=2
net.ipv6.conf.all.accept_ra=2
保存退出,最后:
ip6tables -t nat -A POSTROUTING -o $(uci get network.wan6.ifname) -j MASQUERADE
去 https://ipv6ready.me/ 看到这个就基本成功了:

如果修改路由器任意配置后 IPv6 消失了,可以 ssh 上去路由器,然后继续 /etc/init.d/nat6 restart 试试,一般有效果。
你也可以去往网络->网络诊断,进行 IPv6 ping 确认路由器的 IPv6 获取情况。

LAN 侧内网分布配置 odhcpd
这里是配置 NAT6 时候,可能出现 IPv6 不稳定的情况,导致路由器有 IPv6 而下拉设备虽有 IPv6 认证但无法正常连通 IPv6 地址的解决方法。
使用的是 odhcpd,配置也很简单:
- 安装 odhcpd
opkg update
opkg install odhcpd-ipv6only # 已装会提示已安装
我的 odhcpd 配置如图,可供参考:
root@OpenWrt:~# cat /etc/config/odhcpd
config odhcpd 'odhcpd'
option maindhcp '0' # 只负责 IPv6
option leasefile '/tmp/hosts/odhcpd'
option leasetrigger '/usr/sbin/odhcpd-update'
option loglevel '4'
root@OpenWrt:~#
然后进行:
/etc/init.d/odhcpd enable
/etc/init.d/odhcpd start
- 确认
service odhcpd status # running
netstat -lnp | grep odhcpd # 应看到 UDP 546/547 监听 br-lan
应该看到:
root@OpenWrt:~# netstat -lnp | grep odhcpd
udp 0 0 :::547 :::* 12552/odhcpd
raw 0 0 ::%168:58 :::* 58 12552/odhcpd
root@OpenWrt:~#
如果设备端拿到 ULA 前缀的 IPv6 地址,但无法 ping 通 IPv6 地址,那么进入路由器端,使用:
# 给 lan 段显式声明默认路由标志
uci set dhcp.lan.ra_default='1'
uci commit dhcp
/etc/init.d/odhcpd restart
即可恢复正常。
dadfailed 问题
当然部署 IPv6也会有很多困难,比如出现 DADFAILED 问题,你可能在系统日志看见这个问题:
Tue Nov 4 20:55:13 2025 kern.info kernel: [768787.360836] IPv6: phy0-sta0: IPv6 duplicate address fe80::92fb:5dff:fef1:2fb8 used by 00:ad:d5:4b:16:ee detected!

同时,你 ip a 可能会看见这个:
inet6 fe80::92fb:5dff:fef1:2fb8/64 scope link dadfailed tentative proto kernel_ll
这个时候就比较麻烦了,涉及到 MAC 地址冲突问题,出现这个问题往往是在校园网内有一个有缘人连接 HNU,网络 MAC 地址和你相同,当然作为 OpenWrt,我们可以直接改掉我们的 MAC 地址(改掉后需要重新进入 web.hnu.edu.cn 进行验证)。
修改方法也很简单,我的做法很暴力,直接关闭 DAD 认证,避免 00:ad:d5:4b:16:ee 这个内网设备的追击。
自己必须在 phy0-sta0 接口上永久禁用 DAD 检查。
vi /etc/sysctl.conf ,然后添加:
net.ipv6.conf.phy0-sta0.dad_transmits = 0
应用更改并重启网络:
sysctl -p
/etc/init.d/network restart
等待一会后,重新认证校园网登录,应该成功。
去服务器 ssh,使用 ip a,应该可以看到:
11: phy0-sta0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether ae:2e:9d:1a:d7:15 brd ff:ff:ff:ff:ff:ff
inet 10.68.157.83/15 brd 10.69.255.255 scope global phy0-sta0
valid_lft forever preferred_lft forever
inet6 2001:250:4402:1119:ac2e:9dff:fe1a:d715/64 scope global dynamic mngtmpaddr proto kernel_ra
valid_lft 258906sec preferred_lft 172506sec
inet6 fe80::ac2e:9dff:fe1a:d715/64 scope link proto kernel_ll
valid_lft forever preferred_lft forever
dadfailed 错误消失~
IPv6 优先
前往 https://ipw.cn/ipv6/ 可以更快速地看到自己的 IPv6地址,同时你也可以看到自己的网络是 IPV4 优先还是 IPV6 优先。
一般使用 IPV6 优先比较好,毕竟不限速+不计费流量(教育网 IPv6的好处)。如果你的 IPv6 配置正常,浏览器会为你默认配置 IPv6 优先。
但是我这里有一个奇怪的配置问题,使用测速网站可能无法测出正常的网速,但正常使用无碍,能正常使用就可以了。
一个校园网登录脚本
听说 HNU 校园网更新后经常断连,需要重新登录连接,虽然我自己还没有遇到这个问题,但是维持稳定的网络环境,我自己用 BurpSuite 抓包分析了一下 HNU 的校园网验证,写了一个用于电信宽带验证的小脚本。
这个 HNU 校园网的登录脚本,挂在自己的 openwrt 路由器上,定时 30min 一次运行,仅供参考。
这个脚本的使用前提是你的 DNS 配置正确,为校园的内网 DNS,可以访问 web.hnu.edu.cn 进入验证页面。
自己抓包看了看,如果你不使用电信宽带而使用校园网,那么你的 USER_ACCOUNT 改为 USER_ACCOUNT=",0,你的学号" 即可,把@telecom去掉。
然后注意修改 phy0-sta0 为你自己的网络接口,比如 wan 啊,phy1-sta0 之类。
#!/bin/sh
# 用户信息配置
USER_ACCOUNT=",0,你的学号@telecom"
USER_PASSWORD="你的个人门户密码"
# -------------------
# 从物理设备名 phy0-sta0 获取IP
WLAN_USER_IP=$(ifconfig phy0-sta0 | grep 'inet addr' | cut -d ':' -f 2 | cut -d ' ' -f 1)
if [ -z "$WLAN_USER_IP" ]; then
logger "HNU Login: [失败] 未能从物理设备(phy0-sta0)获取到IP地址,脚本退出。"
exit 1
fi
# 使用域名,因为我们确认了DNS是好的
AUTH_URL="http://web.hnu.edu.cn:801/eportal/portal/login?callback=dr1003&login_method=1&user_account=${USER_ACCOUNT}&user_password=${USER_PASSWORD}&wlan_user_ip=${WLAN_USER_IP}&wlan_user_ipv6=&wlan_user_mac=000000000000&wlan_ac_ip=&wlan_ac_name=&jsVersion=4.2.1&terminal_type=3&lang=zh-cn&v=2485&lang=zh"
# 【V6 终极修正】增加 -L 处理重定向,并增加 --header "Referer: ..." 来模拟浏览器行为
RESPONSE=$(curl -s -L -m 5 --header "Referer: http://web.hnu.edu.cn/" "$AUTH_URL")
logger "HNU Login: [信息] 已发送伪装Referer的登录请求。"
if echo "$RESPONSE" | grep -q '"result":1'; then
logger "HNU Login: [成功] 服务器返回认证成功!"
else
logger "HNU Login: [警告] 认证可能失败,服务器返回: $RESPONSE"
fi
exit 0
然后去 vi /etc/login_hnu.sh,复制后 wq 保存,然后 crontab -e,在打开的 vim 编辑器中,添加以下一行内容:
*/30 * * * * /etc/login_hnu.sh
之后 :wq 保存
听 cry 学长说,“HNU 校园网完全是一个黑盒系统”。
在一片漆黑的环境下接几根线的确是很费脑力和时间的。我自己配置 IPv6 也经历了很多让人想要放弃的瞬间……但学长学姐们的指南帮助了我很多很多,我也想接续这份薪火。
我更希望我的教程可以帮到更多未来的 HNU 学子们。
Enjoy the IPv6 world!