在 PPPoE 下 DHCPv6 Stateless/Stateful 获取 ipv6 地址

前言

前段时间学校信息化处突然把全校的网络架构改了,现在的校园网速度终于能追上国内平均网速了(大雾)。

和别的学校不同,有些学校插上网线就会分配到 ipv6 地址,如果需要外网 ipv4 访问权限的话那么可能就需要用户登录,比如 Drcom 或者锐捷这些客户端(校方不嫌烦么)。我校插上网线默认什么都没有,只有 PPPoE 拨号之后才会分配 ipv4 和 ipv6 地址。

原本在校园网改造之前,我的 Thin PC 插在宿舍的网口上,在 /etc/ppp/peers/provider 里加上 +ipv6,小小配置下,拨号后就会分配有一个 ipv6 地址分配到 ppp0 interface。然后该干嘛干嘛。

然而网络架构突然变了之后,这么做行不通了——如此拨号之后不知道为什么只会分配一个 ipv4 地址,虽然网络架构升级后 ipv4 速度上完全不需要 ipv6 网络来加持了,但是堵塞公共出口总是不好的嘛,为什么不利用好没什么人用的 CERNET 2 呢对吧。

于是开始查资料。

Disclaimer: 至写下本文的时候奶冰还是对 ipv6 一头雾水(SLAAC, DHCPv6 Stateless/Stateful, Prefix Delegation, NDP 这些都啥啊大佬快救我),所以难免会有胡说八道之嫌,还请各位看官半信,如果遇到了和奶冰一样的情况并用本文的内容解决了问题我不胜荣幸,如果没能解决欢迎反馈,当然更欢迎对本文指正批评(超乖巧)

一点点背景

我校的 ipv6 地址自古至今都只分配一个地址(/128)(或者换句话说没有 Prefix Delegation?),所以如果是路由器 PPPoE 拨号的话,为了给下级设备 ipv6 访问权限还要折腾 NAT6。(差评)
因此在本文后半部分解决问题的时候都默认没有 PD,对于分配子网的环境下还请自行调整。

另外本文默认已经搭建好 PPP 环境,关于如何安装 PPP 已经如何使用 pppoeconf 请自行解决。

折腾过程

在校园网架构变更后我一度以为 ipv6 没了,因为 Debian 上拨号死活拿不到 ipv6 地址,一度想要指定静态 ipv6 地址但是似乎因为 PPPoE 拨号覆盖 IP 的原因总之呢就不了了之。

但是后面发现 Windows 上直接连接网线拨号是可以拿到 IPv6 地址的,于是开了 Wireshark 抓了一下包,这才发现原来是 Windows 先 PPPoE 拨号,后通过 DHCPv6 索要 ipv6 地址。

那那,为什么之前在 Debian 上什么都不用配置就能直接拿到 ipv6 地址呢?
胡乱猜测原因是原来的网络架构分配 ipv6 的方式是 SLAAC,因而能够自动配置

所以,按照这个思路,大概是要折腾一个 DHCPv6 客户端的节奏吗?

后面查了下,Linux 下有的 DHCPv6 客户端有 wide-dhcpv6-client, dhcpy6d, dibbler-client,文档什么的看得我一头雾水,因为 Google 上大多数的文档还讲了如何把 PD 用 radvd 分配给下级,感觉和我这边的网络环境不太相关

后面就先试了下 dibbler-client, 文档也挺少的,跟着官方 conf 走了一遍,在配置文件(/etc/dibbler/client.conf)里就短短几行

log-level 7
iface ppp0 {
    ia # 获取常规地址(非临时地址)
    option dns-server # 拿到地址后再顺便给我丢一个 DNS 服务器吧
}

然后,先拨号,然后 systemctl start dibbler-client,看了下 ip addr,然后就有 ipv6 地址了
……嗯 的确就这么简单

不过如果在 config 里的部分 interface 在 dibbler-client 启动的时候是处于 down 的状态,似乎 dibbler-client 会启动失败,这不太好(不太方便用来自动启动)
另外看了下 ifconfig 的结果,获取到的 ipv6 地址是有租期的,也就是这样的方式是 DHCPv6 Stateful 获取的,当时没有看到 dibbler-client 文档里写了其实开一个选项就能 Stateless 了,只想着换着折腾 Stateless,所以后面用了 wide-dhcpv6-client

安装好 wide-dhcpv6-client 之后,打开/etc/wide-dhcpv6/dhcp6c.conf,输入下面的内容

interface ppp0 {
    request domain-name-servers;
    request domain-name;
    send rapid-commit;
    send ia-na 0; # 给我一个 ipv6 地址
    script "/etc/wide-dhcpv6/dhcp6c-script";
};

id-assoc na 0 { # 这行虽然没有任何用但就是要加上
};

在已经 PPPoE 拨号连接上的情况下,systemctl start wide-dhcpv6-client后,也能拿到 ipv6 地址,而且这次是没有租期的,应该就是传说中的 Stateless

获取到 ipv6 地址的问题解决了,但这两款软件都不会实时检测 interface 是否 up 或者 down 来实现自动在 PPPoE 拨号完获取 ipv6 地址,所以我们还需要做点别的手脚

创建一个 /etc/ppp/ip-up.d/0dhcpv6文件,并写入以下内容

#!/bin/sh
/etc/init.d/wide-dhcpv6-client start

也就是在拨号完之后自动启动 DHCPv6 客户端来获取 IPv6 地址即可

P.S.: 上文是对于只获取一个地址的情况,如果想要拿子网(PD)的话,把 ia 改成 pd 就行了
比如 dibbler-client 似乎是这样改的

log-level 7
iface ppp0 {
    pd
    option dns-server
}

wide-dhcpv6-client 的话似乎要这么改

interface enp1s0 {
    send rapid-commit;
    send ia-na 0;
    send ia-pd 0; # 伸手要一个子网
};

id-assoc pd 0 {
    prefix ::/64 infinity;
    prefix-interface eth0{ # 给 eth0 分配一个子网里的 IPv6
        sla-len 0;
        sla-id 0;
        ifid 1;
    };
};

因为没玩过 所以是否有效有待商榷
另外如果要下发到下级设备的话那还需要 radvd,不过那个我真的没玩过了(也没条件玩QAQ)

后续

后面又看了下 dibbler-client 文档,他的配置文件里还有这么两行

# Uncomment following line to make dibbler accept downed/not associated interfaces
inactive-mode

似乎意味着即便 interface 是 down 的状态也可以启动 dibbler-client(原本是不允许的),那么是否意味着可以不要 ip-up 脚本来把 dibbler-client 带起来,而是让 dibbler-client 在后台持续运行,自行检测 interface 在 up 的时候自动获取 ipv6 地址呢?这个就没测试过了(

另外每次写博文都要找配图快被烦死了哟

点赞
  1. Villivateur Von说道:

    校园网ipv6会经常莫名其妙地路由断掉,即有ipv6,但是没有路由。这两款软件有没有自动检测并重新获取ipv6的方案?

    1. Milkice说道:

      好像没有诶...没遇到过这种情况

发表评论