我想做什么?
我正在尝试通过 DHCP 在单个物理 ISP 上行电缆上获取 3 个公共 IP 地址。
出了什么问题?
续订有点不对劲。从接口来看,virtual0 在尝试通过与 DHCP 服务器的单播连接进行更新时工作得很好。virtual1 和 virtual2 接口因单播而失败。他们进入后备模式以使用广播并成功使用广播,但垃圾日志中充满了不好的东西。我正在运行 Debian 8 和 isc-dhcp-client v. 4.3.1 。
我在启动时设置了这样的接口:
IF_VIRTUAL_BASE=eth0 IF_PUB0=虚拟0 IF_PUB1=虚拟1 IF_PUB2=虚拟2 IF_LAN=eth2 ifconfig "$IF_VIRTUAL_BASE" 向上 ip link add link "$IF_VIRTUAL_BASE" 地址 00:90:0b:ff:10:5b "$IF_PUB0" type macvlan ip 链接设置“$IF_PUB0” ip link add link "$IF_VIRTUAL_BASE" 地址 00:90:0b:ff:11:5b "$IF_PUB1" type macvlan ip 链接设置“$IF_PUB1” ip link add link "$IF_VIRTUAL_BASE" 地址 00:90:0b:ff:12:5b "$IF_PUB2" type macvlan ip 链接设置“$IF_PUB2” # 启用转发 回声 1 > /proc/sys/net/ipv4/ip_forward
unset new_routers
在为 virtual1 和 virtual2 完成 dhcprequest 时,我也会这样做。
猜猜看,这种怪物的作品:
7 月 11 日 20:45:43 gw dhclient:虚拟 0 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:43 gw dhclient:virtual1 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:43 gw ifup [582]:虚拟 0 到 255.255.255.255 端口 67 上的 DHCPREQUEST 7 月 11 日 20:45:43 gw ifup [592]:虚拟 1 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:43 gw dhclient:virtual2 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:43 gw ifup [634]:虚拟 2 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:46 gw dhclient:virtual1 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:46 gw ifup [592]:虚拟 1 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:46 gw dhclient:来自 88.113.75.2 的 DHCPACK 7 月 11 日 20:45:46 gw ifup [592]:来自 88.113.75.2 的 DHCPACK 7 月 11 日 20:45:46 gw logger: virtual1 (REBOOT): IP: -> 88.113.75.59; GW:-> 88.113.75.1 7 月 11 日 20:45:47 gw dhclient:virtual0 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:47 gw ifup [582]:虚拟 0 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:47 gw dhclient:来自 88.113.75.2 的 DHCPACK 7 月 11 日 20:45:47 gw ifup [582]:来自 88.113.75.2 的 DHCPACK 7 月 11 日 20:45:47 gw logger: virtual0 (REBOOT): IP: -> 88.113.75.65; GW:-> 88.113.75.1 7 月 11 日 20:45:50 gw dhclient:virtual2 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:50 gw ifup [634]:虚拟 2 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 20:45:50 gw dhclient:来自 88.113.75.2 的 DHCPACK 7 月 11 日 20:45:50 gw ifup[634]:来自 88.113.75.2 的 DHCPACK 7 月 11 日 20:45:50 gw logger: virtual2 (REBOOT): IP: -> 88.113.75.61; GW:-> 88.113.75.1
所以他们工作了,对吧?它们是广播请求。好的,快进一个小时左右,我们得到了这样的战利品:
7 月 11 日 21:45:09 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:11 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:22 gw dhclient:虚拟 2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:25 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:32 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:43 gw dhclient:虚拟 2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:46 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:45:56 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:05 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:11 gw dhclient:虚拟 2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:21 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:30 gw dhclient:虚拟 2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:33 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:42 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:46:47 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:47:00 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:47:01 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 21:47:09 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67
virtual1 和 virtual2 接口拼命尝试通过单播连接到以前的 DHCP 服务器 195.74.6.55 来更新它们的 IP。他们失败了单播。但是接下来发生了一些有趣的事情,最后他们切换到广播作为后备并成功了!
7 月 11 日 22:30:41 gw dhclient:virtual1 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 22:30:47 gw dhclient:virtual2 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 22:30:52 gw dhclient:virtual1 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 22:30:52 gw dhclient:来自 88.113.75.2 的 DHCPACK 7 月 11 日 22:30:52 gw logger: virtual1 (RENEW): IP: 88.113.75.59 -> 88.113.75.59; GW: 88.113.75.1 -> 88.113.75.1 7 月 11 日 22:30:58 gw dhclient:虚拟 2 上的 DHCPREQUEST 到 255.255.255.255 端口 67 7 月 11 日 22:30:58 gw dhclient:来自 88.113.75.2 的 DHCPACK 7 月 11 日 22:30:59 gw logger: virtual2 (RENEW): IP: 88.113.75.61 -> 88.113.75.61; GW: 88.113.75.1 -> 88.113.75.1
观察 virtual0 接口:
7 月 11 日 22:38:17 gw dhclient:虚拟 0 上的 DHCPREQUEST 到 195.74.6.55 端口 67 7 月 11 日 22:38:18 gw dhclient:来自 195.74.6.55 的 DHCPACK 7 月 11 日 22:38:18 gw logger: virtual0 (RENEW): IP: 88.113.75.65 -> 88.113.75.65; GW: 88.113.75.1 -> 88.113.75.1
结论是,对于 virtual0 接口,单播 (dhclient) DHCP 请求有效,而对于 virtual1 和 virtual2,仅广播 DHCP 更新有效。所以,一定是路由问题吧?以下是典型启动后 ip route 显示的内容:
root@gw:~# ip 路由 默认通过 88.113.75.1 dev virtual0 88.113.75.0/24 dev virtual0 proto 内核范围链接 src 88.113.75.65 88.113.75.0/24 dev virtual1 proto 内核范围链接 src 88.113.75.59 88.113.75.0/24 dev virtual2 proto 内核范围链接 src 88.113.75.61 172.16.8.0/28 via 172.16.8.2 dev tun0 # 对于 openvpn 172.16.8.0/24 dev eth2 proto kernel scope link src 172.16.8.254 # For LAN 172.16.8.2 dev tun0 proto kernel scope link src 172.16.8.1 #For openvpn
如何使基于 macvlan 的接口 virtual1 和 virtual2 上的 dhclients 正确路由其单播续订请求并正确接收响应?
我已经完成了大量的谷歌搜索,试图触发许多设置,包括防火墙策略、基于策略的路由、eth0 promisc 模式和 sysctl 变量、剥离通用网络设置等。我目前正在 dhclient 上进行 strace。这些设置的一种组合必须有效。如果需要更多信息,我很乐意提供。
EDIT1:dhclient strace 已准备就绪。
这发生在一开始:
绑定(5, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 16) = 0 绑定(6, {sa_family=AF_INET, sin_port=htons(68), sin_addr=inet_addr("0.0.0.0")}, 16) = 0 sendto(5, "......", 342, 0, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 18) = 342
据我了解,“sendto(5”) 是第一个成功的基于广播的 dhclient 发送。
然后,稍后第一个失败的单播发送:
sendto(6, "......", 300, 0, {sa_family=AF_INET, sin_port=htons(67), sin_addr=inet_addr("195.74.6.55")}, 16) = 300
并且下一个成功的广播发送:
sendto(5, "......", 342, 0, {sa_family=AF_PACKET, proto=0x7669, if1635087474, pkttype=PACKET_HOST, addr(0)={12652, }, 18) = 342
我能够修复它!以一种非正统的方式,但仍然如此。
那我做了什么?我只是卸载了 isc-dhcp-client 4.3.1 并安装了 dhcpcd 6.0.5(由 Roy Marples,debian 包名称 dhcpcd5)。而已。
我在大约 23:00 重新启动机器并检查所有接口是否正常,然后设置 tcpdump 运行。在 00:02 左右,其中一个 DHCP 计时器到期,所有 3 个接口都整齐地获得了它们的 IP 地址,没有提出任何问题:
https://isstatic.askoverflow.dev/xGQpq.png
基本上我不需要更改 /etc/dhcpcd.conf 中的任何内容。似乎 dhcpcd 的构建方式比 dhclient 更智能。至少在我的情况下。
(旁注:我必须说从 isc-dhcp-client 迁移到 dhcpcd 非常容易。Debian 8 具有内置支持;似乎如果您安装 dhcpcd5 并删除 isc-dhcp-client 并重新启动,系统会选择自动新客户端。关于脚本,似乎没有 dhcpcd 的脚本目录,但所有进入挂钩的单个文件和所有退出挂钩的单个文件。文件命名为:/etc/dhcpcd.enter-hook 和 /etc/dhcpcd。 exit-hook 。如果您将 dhclient 挂钩脚本放入这些文件中,它们无需修改即可工作。我印象深刻!)