(我发现这与有关nscd
;请参阅问题的底部)
我正在尝试通过笔记本电脑连接到无头服务器;它们通过 Linksys 无线路由器和 TP-Link 以太网交换机共享有线链路。我在两台机器上运行 Arch Linux,使用非常默认的 Systemd 设置和 dhcpcd 进行网络配置。
最近在笔记本电脑上进行系统升级后,当我尝试 ssh 到服务器(我们称之为“myserver”)时出现以下错误:
$ ssh -v -v -F /dev/null myserver
OpenSSH_7.7p1, OpenSSL 1.1.0h 27 Mar 2018
debug1: Reading configuration data /dev/null
debug2: resolving "myserver" port 22
debug2: ssh_connect_direct: needpriv 0
debug1: Connecting to myserver [fe80::9cd8:b045:5974:c5cf] port 22.
debug1: connect to address fe80::9cd8:b045:5974:c5cf port 22: Invalid argument
ssh: connect to host myserver port 22: Invalid argument
运行相同的命令strace
显示错误来自connect
:
connect(3, {sa_family=AF_INET6, sin6_port=htons(22), inet_pton(AF_INET6, "fe80::9cd8:b045:5974:c5cf", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=0}, 28) = -1 EINVAL (Invalid argument)
但是,ping myserver
效果很好:
$ ping myserver
PING myserver(myserver (fe80::9cd8:b045:5974:c5cf)) 56 data bytes
64 bytes from myserver (fe80::9cd8:b045:5974:c5cf%en0): icmp_seq=1 ttl=64 time=0.533 ms
64 bytes from myserver (fe80::9cd8:b045:5974:c5cf%en0): icmp_seq=2 ttl=64 time=0.549 ms
通常我有一个本地named
转发 DNS 查询,但是当我返回直接使用路由器的 DNS 服务器时,错误仍然存在:
$ sudo cat /etc/resolv.conf
# Generated by resolvconf
nameserver 192.168.1.1
错误是间歇性的:每隔几分钟我就能成功连接。当我能够成功连接时,我看到它connect
正在使用 IPv4 地址:
connect(3, {sa_family=AF_INET, sin_port=htons(22), sin_addr=inet_addr("192.168.1.149")}, 16) = 0
但是,host
无论连接正常还是中断,该命令都会显示相同的 IPv4 地址:
$ host myserver
myserver has address 192.168.1.149
看完之后这问题 我想到手动指定接口(ssh -v -v -F /dev/null -B en0 myserver
)。这可以在错误发生时消除错误,但对我来说这不是永久的解决方案,也不能解释为什么错误突然出现。
我while
在我的 shell 中使用了一个循环来确定从工作到不工作以及反之亦然的最接近秒数的时间ssh
,并且我无法将这些事件与输出中的任何内容(journalctl
包括dhcpcd
消息)关联起来。
我最初在 Network Engineering 上发布了这篇文章,但那里的主机配置与主题无关。在该网站上,用户瑞奇·比姆发布了部分答案:
无论执行主机名解析的是什么,返回的都是对所选接口(即“任何”)无效的本地链路 IPv6 地址。本地链路地址必须指定接口 - 例如 fe80:...:1%eth0
不知道您为什么会得到链接本地地址。也许熟悉 Arch Linux 的人可以提供进一步的帮助。
更新:这似乎是nscd
“名称服务缓存守护程序”的问题,这解释了我遇到的间歇性问题(可能与缓存过期有关)。已修复:
sudo systemctl stop nscd.service
当我停止 ncsd 时,ssh
就可以使用链路本地地址进行连接,但这次调用connect
还指定了我的主接口“en0”,并且成功了:
connect(3, {sa_family=AF_INET6, sin6_port=htons(22), inet_pton(AF_INET6, "fe80::9cd8:b045:5974:c5cf", &sin6_addr), sin6_flowinfo=htonl(0), sin6_scope_id=if_nametoindex("en0")}, 28) = 0
write(2, "debug1: Connection established.\r"..., 33) = 33
我想剩下的问题(我可以单独问)是,这是 nscd 中的一个错误吗?我应该使用 nscd 吗?
答案1
当我将 Raspberry Pi 接入网络时,这个问题以一种新的方式表现出来,我最终能够对其进行诊断。
该问题与有关systemd-resolved
。这已经影响到其他用户,例如请参阅 Ask Ubuntu 的nslookup 找到 ip,但 ping 不通
或者systemd-resolved 不会查询 DNS 服务器以获取本地域。
我曾假设这ssh myserver
会触发 DNS 查找
myserver
。但是,在我的系统上并非如此,以下是默认的nsswitch.conf
:
$ cat /etc/nsswitch.conf
# Name Service Switch configuration file.
# See nsswitch.conf(5) for details.
...
hosts: files mymachines myhostname resolve [!UNAVAIL=return] dns
...
该resolve
组件是systemd-resolved
Lennart Poettering 项目,旨在实现
零配置
协议多播 DNS
和链路本地多播名称解析。
这[!UNAVAIL=return]
意味着当systemd-resolved
可用时,永远不会使用 DNS 主机解析。通常这不是问题,因为systemd-resolved
也可以创建 DNS 查询。但是,它显然不会对单标签主机名(如)执行此操作
myserver
,即使 DNS 服务器位于我的本地路由器 (192.168.1.1) 上也是如此。这是因为单标签主机名不应该暴露给外部网络,正如 Lennart 在这个 Github 线程。
host myserver
这解释了产生 IPv4 地址(来自路由器)同时ssh myserver
产生 IPv6 地址(来自多播 DNS 或 LLNR,不确定是哪一个)的事实。
我对此感到困惑,因为我从未了解过多播 DNS 或 LLNR 或 IPv6。我从未了解过这些技术,因为我认为熟悉的 IPv4 和 DNS 技术对我来说已经足够了。
显然,systemd-resolved
不仅对于生成 Zeroconf 请求是必要的,对于回复这些请求也是必要的。我接入网络的 Raspberry Pisystemd-resolved
由于某种原因停止了运行,因此尽管我能够使用 和 查找主机名 ,host
但dig
我无法通过ssh
或看到它ping
:
$ ping raspberrypi
ping: raspberrypi: Name or service not known
[2]$ host raspberrypi
raspberrypi has address 192.168.1.135
这让我找到了上面的第一个 Ask Ubuntu 错误报告,并找到了解决方案。如果我systemd-resolved
在 Pi 上启动,那么我就可以ping
和ssh
它连接。但是,如果我systemd-resolved
在本地禁用,那么我也能够和Pi 连接ping
。ssh
现在我已经systemd-resolved
在所有系统上禁用了,
$ sudo systemctl stop systemd-resolved.service
$ sudo systemctl disable systemd-resolved.service
因为它似乎会给 GNU libc 带来问题nscd
,而且它要求我学习 IPv6、mDNS 和 LLNR 等技术,而这些技术我目前不需要——因为我的计算机都连接到一个基本的消费者路由器,它提供了开箱即用的熟悉的 DNS 和 NAT 技术。
感谢那些对我的原始问题发表评论的人,但最终没有必要通过“在您的家用路由器中进行设置(如果它不是一团糟)”或“对您的 ISP 大喊大叫”来“为自己配置一个 ULA 前缀,或获得全球 IPv6 连接,或两者兼而有之”。我只需要禁用 Lennart 的一些新软件,就可以远离前沿技术。Github 线程对软件是否真正正常运行进行了一些讨论,但我发现自己与许多其他用户处于相同的位置:在花了几个小时的时间找出罪魁祸首之后systemd-resolved
,我宁愿不花更多的时间来了解如何修复它,因为禁用它是如此容易。