起因
这几天尝试将本站的服务器操作系统迁移到Arch Linux,发现NetworkManager一直没办法正常的获取到由VPS分配的IPv6地址,而是会获取到一串随机的IPv6地址。
一开始看了一下archiso和Arch Linux官方的Cloud Image,发现它们都使用systemd-networkd,没有任何问题。遂将服务器的的网络管理软件换成了systemd-networkd,并同时将DNS解析软件换成了systemd-resolved。
如果只是这样我觉得是不够的,我不知道systemd-networkd日后的更新会不会出现同样的问题,于是顺便再次研究了一下NetworkManager的这个问题。
然后发现了导致了这两个问题的根本原因。
原因
第一个原因是NetworkManager自动启用了稳定隐私地址(Stable private addressing,RFC7217)功能。简单来说就是,在同一个的网络中通过特定的算法生成一个在该网络下唯一的IPv6地址,而在不同的网络中会生成不同的IPv6地址,保证了IP的稳定性也保证了隐私保护的能力。对于桌面环境来说确实不错,但是对于服务器环境不太友好。大部分云服务器提供商(包括我的)一般都通过DHCPv6提供稳定的IPv6地址,这个功能直接导致了公网IPv6地址不稳定的问题。
RHEL系的服务器环境,默认会把NetworkManager中的连接配置的稳定隐私地址关闭,所以一般不会有这个问题。
第二个原因是IPv6的隐私扩展(Privacy Extension)功能,在启用该功能之后,系统会通过原来的地址经过特定算法得到一些临时地址,当连接远程服务器时,就会使用这些临时地址。经过查阅,NetworkManager和内核均为默认不打开此功能,所以问题不大。
解决方案
直接把NetworkManager的稳定隐私地址功能禁用掉就行了。
$ nmcli conn
NAME UUID TYPE DEVICE
Wired connection 1 f2e9eaf1-eaf9-3be8-895f-28637f9eff13 ethernet ens160
$ sudo nmcli conn modify 'Wired connection 1' ipv6.addr-gen-mode eui64
完成设置后重启系统,此时IPv6即分配正常。
从上面的步骤也可知道,systemd-networkd在日后的更新,不会出现上面的问题。
最后
既然解决了问题,实际上可以考虑继续使用NetworkManager。不过本站服务器最终还是没有使用NetworkManager,毕竟已经有配置好的systemd-networkd和systemd-resolved了,少装一个包还是好的。
顺便记录另外一个小问题
在使用systemd-resolved的时候也遇到一个小问题:当Docker内的程序访问主机的MySQL时,可能出现访问极其缓慢的情况,这是由于MySQL尝试调用系统的反向DNS服务出现了超时。一种解决办法是my.ini
内使用skip-name-resolve
来解决,不过这样做,形似root@localhost
的用户在连接时可能出问题。
尝试使用resolvectl反向解析Docker容器IP,会发现次次超时。解决的办法是编辑/etc/systemd/resolved.conf
,禁用MulticastDNS。MulticastDNS (mDNS)在内网环境还算好用,甚至可以用于固定WSL访问宿主机的IP,但是放在服务器环境就明显的不合适了。
另外,还可以禁用掉DNSStubListener选项,这样systemd-resolved就可以不占用主机的53端口,也不会影响到systemd-resolved的DNS解析能力。