使用 dhcp 发送 IPv6 的网络掩码和网关/路由

使用 dhcp 发送 IPv6 的网络掩码和网关/路由

我已经设置了 DHCP 服务器来为我的客户端分配 ipv6。但是,“路由器”和“子网”选项都被忽略了。

我读到过,ipv6 不是从 DHCP 获取这些,而是​​从路由器广播获取。

但是,我觉得这很奇怪。为什么它从 DHCP 获取静态 IP,而从路由器获取网络掩码?奇怪的架构。

无论如何,我想知道是否有办法轻松地将这些“缺失”的功能添加到 DHCPv6 或任何其他解决方法中。最终结果应该是,我可以根据客户端的 MAC 地址从一个中心位置设置“ip6”、“网络掩码”和“网关”,就像我对 ipv4 所做的那样。

我不想弄乱 ipv6 自动配置和无状态的东西。

我可以通过在网络配置中的“up”事件上设置内容来以“糟糕”的方式解决网关问题,但我找不到在启动接口后更改其网络掩码的方法。

答案1

通常,IPv6 应该使用“邻居发现协议”通过“路由器通告”从路由器本身获取 IP、网络掩码和路由/网关信息。

这与 IPv4 的工作方式完全不同。有一种称为 DHCPv6 的东西,据说可以作为 IPv6 的 DHCP,但缺少很多功能。很可能是因为 IPv6 的工作方式。

然而,我们中的许多人都希望能够像分配 IPv4 和 DHCP 一样为我们的客户端分配 IPv6。这是可能的,但需要一点调整。

您要做的第一件事是向您的 DHCP 服务器添加 3 个自定义 OPTION 参数。

如果您在 Linux 中使用 ISC DHCP 服务器,您的配置文件应该如下所示:

authoritative;
default-lease-time 86400;
max-lease-time 86400;
log-facility local7;
use-host-decl-names on;

option ipv6-address code 214 = ip6-address;
option ipv6-netmask code 215 = unsigned integer 8;
option ipv6-gateway code 216 = ip6-address;

subnet 88.xxx.xxx.128 netmask 255.255.255.224 {
  option domain-name "example.com";
  option domain-name-servers 8.8.8.8, 8.8.4.4;
  option routers 88.xxx.xxx.128;
  option subnet-mask 255.255.255.255;
  option ipv6-netmask 112;
}

host ip-88-xxx-xxx-129.example.com {
  hardware ethernet 16:xx:xx:xx:b3:8d;
  fixed-address 88.xxx.xxx.129;
  option host-name "ip-88-xxx-xxx-129.example.com";
  option ipv6-address 2a01:xxx:xxx:2464::1:1;
  option ipv6-gateway 2a01:xxx:xxx:2464::1:0;
}

host ip-88-xxx-xxx-130.example.com {
  hardware ethernet 16:xx:xx:xx:af:aa;
  fixed-address 88.xxx.xxx.130;
  option host-name "ip-88-xxx-xxx-130.example.com";
  option ipv6-address 2a01:xxx:xxx:2464::2:1;
  option ipv6-gateway 2a01:xxx:xx:2464::2:0;
}

host ip-88-xxx-xxx-131.example.com {
  hardware ethernet 16:xx:xx:xx:7a:73;
  fixed-address 88.xxx.xxx.131;
  option host-name "ip-88-xxx-xxx-131.example.com";
  option ipv6-address 2a01:xxx:xxx:2464::3:1;
  option ipv6-gateway 2a01:xxx:xxx:2464::3:0;
}

如您所见,我添加了 3 个新选项,分别称为“ipv6-address”、“ipv6-netmask”和“ipv6-gateway”。您可以像通常使用 IPv4 一样设置它们。

进行更改后,请不要忘记重新启动 DHCP 服务器。

现在,需要告知客户端在发出 DHCP 请求时包含这 3 个自定义选项。

这取决于您使用的 DHCP 客户端。Debian/Ubuntu 使用“dhclient”,其配置需要如下所示:

option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;

option ipv6-address code 214 = ip6-address;
option ipv6-netmask code 215 = unsigned integer 8;
option ipv6-gateway code 216 = ip6-address;

request subnet-mask, broadcast-address, time-offset, routers,
        domain-name, domain-name-servers, domain-search, host-name,
        netbios-name-servers, netbios-scope, interface-mtu,
        rfc3442-classless-static-routes, ntp-servers,
        dhcp6.domain-search, dhcp6.fqdn,
        dhcp6.name-servers, dhcp6.sntp-servers,
        ipv6-address, ipv6-netmask, ipv6-gateway;

如您所见,我在顶部添加了 3 个自定义 OPTION 定义,然后告诉 DHCP 将它们包含在请求中。

现在尝试重新启动您的客户端,看看它是否仍然像以前一样正确获取 IPv4(应该如此)。

重启后,您可以查看 DHCP 创建的租约文件。它包含从 DHCP 服务器收集的信息。在 Debian/Ubuntu 系统上,可以在“/var/lib/dh​​cp/dhclient.eth0.leases”中找到它。如果您查看该文件,您应该会看到类似以下内容:

lease {
  interface "eth0";
  fixed-address 88.xxx.xxx.136;
  option subnet-mask 255.255.255.255;
  option routers 88.xxx.xxx.128;
  option dhcp-lease-time 86400;
  option dhcp-message-type 5;
  option domain-name-servers 8.8.8.8,8.8.4.4;
  option dhcp-server-identifier 88.xxx.xxx.128;
  option ipv6-address 2a01:xxx:xxx:2464::8:1;
  option ipv6-netmask 112;
  option host-name "ip-88-xxx-xxx-136.example.com";
  option ipv6-gateway 2a01:xxx:xxx:2464::8:0;
  option domain-name "example.com";
  renew 6 2013/08/03 23:32:53;
  rebind 0 2013/08/04 09:04:30;
  expire 0 2013/08/04 12:04:30;
}

如您所见,3 个自定义 OPTION 已经正确到达客户端。

现在,您需要做的最后一件事是添加一个使用这些值来设置您的 ipv6 接口的脚本。

dhclient 使用一个特殊的钩子系统,它会在某些阶段运行脚本。我们需要让它在收到 DHCP 服务器的响应时运行。

在“/etc/dhcp/dhclient-exit-hooks.d/ipv6”创建一个文件,内容如下:

#**************************************
# This script sets ipv6 based on custom options
#**************************************

# To enable this script set the following variable to "yes"
RUN="yes"

if [ "$RUN" != "yes" ]; then
    exit 0
fi

if [ "$reason" != "BOUND" ]; then
    exit 0
fi

if [ ! -n "$new_ipv6_address" ] || [ ! -n "$new_ipv6_netmask" ] || [ ! -n "$new_ipv6_gateway" ]; then
    exit 0
fi

ip addr add $new_ipv6_address/$new_ipv6_netmask dev $interface

ip -6 route add default via $new_ipv6_gateway dev $interface

现在重新启动您的客户端并观察奇迹发生!

更新 1:将 ipv6 从“ifup.d”移至 DHCP 绑定运行,以使其更清晰。

相关内容