使用 Ansible 解决 systemd-resolved 名称服务故障

名称解析和不断变化的网络环境。
86 位读者喜欢这篇文章。
Avoiding data disasters with Sanoid

Opensource.com

大多数人倾向于认为名称服务是理所当然的。它们对于将人类可读的名称(例如 www.example.com)转换为 IP 地址(例如 93.184.216.34)是必要的。对于人类来说,识别和记住名称比 IP 地址更容易,名称服务允许我们使用名称,并且它们还会为我们将其转换为 IP 地址。

域名系统 (DNS) 是全球分布式数据库,它维护执行这些查找和反向查找所需的数据,其中 IP 地址是已知的,而域名是需要的。

我在 2020 年 10 月 Fedora 33 发布的第一天就安装了 Fedora 33。主要更改之一是从旧的名称服务交换机 (NSS) 解析器迁移到 systemd-resolved。不幸的是,在一切都启动并运行后,我无法通过名称连接甚至 ping 我的网络上的任何主机,尽管使用 IP 地址确实有效。

问题

我在我的网络服务器上使用 BIND 运行我自己的名称服务器,并且 20 多年来一切都很好。我配置了我的 DHCP 服务器,以将我的名称服务器的 IP 地址提供给连接到我网络的每个工作站,并且该地址(以及几个备份名称服务器)存储在 /etc/resolv.conf 中。

Michael Catanzaro 描述了 systemd-resolved 应该如何工作,但是 systemd-resolved 的引入导致了我的网络主机上出现各种奇怪的解析问题。症状因主机的用途而异。问题主要表现为在大多数系统上无法找到网络内部主机的 IP 地址。在其他系统上,它根本无法解析任何名称。例如,即使 nslookup 有时返回网络内外主机的正确 IP 地址,ping 也无法联系到指定主机,我也无法 SSH 到同一主机。大多数时候,除非我在命令中使用 IP 地址,否则查找、ping 和 SSH 都不起作用。

新的解析器据称有四种运行模式,本文 Fedora Magazine 文章 中对此进行了描述。当网络有自己的名称服务器旨在执行内部和外部主机的查找时,这些选项似乎都无法正常工作。

从理论上讲,systemd-resolved 应该修复 NSS 解析器在主机连接到 VPN 时无法使用正确的名称服务器的一些边缘问题,这已成为更多人居家办公的常见问题。

新的解析器应该使用 /etc/resolv.conf 现在是一个符号链接的事实来确定它应该如何工作,这取决于它链接到哪个解析文件。systemd-resolved 的手册页包括有关此行为的详细信息。手册页说,将 /etc/resolv.conf 设置为 /run/systemd/resolve/resolv.conf 的符号链接应该使新的解析器以与旧解析器相同的方式工作,但这对我不起作用。

我的修复方法

我在互联网上看到了许多解决此问题的选项,但对我来说唯一可靠的方法是停止并禁用新的解析器。首先,我删除了 resolv.conf 的现有链接,将我首选的 resolv.conf 文件复制到 /run/NetworkManager/resolv.conf,并在 /etc 中添加了指向该文件的新链接

# rm -f /etc/resolv.conf
# ln -s /run/NetworkManager/resolv.conf /etc/resolv.conf

这些命令停止并禁用 systemd-resolved 服务

# systemctl stop systemd-resolved.service ; systemctl disable systemd-resolved.service
Removed /etc/systemd/system/multi-user.target.wants/systemd-resolved.service.
Removed /etc/systemd/system/dbus-org.freedesktop.resolve1.service.

无需重启。旧的解析器接管,名称服务按预期工作。

使用 Ansible 轻松实现

我设置了这个 Ansible playbook,以便在我安装新主机或将解析器恢复为 systemd-resolved 的更新,或者升级到下一个 Fedora 版本时恢复解析器时进行必要的更改。您网络所需的 resolv.conf 文件应位于 /root/ansible/resolver/files/

################################################################################
#                              fixResolver.yml                                 #
#------------------------------------------------------------------------------#
#                                                                              #
# This playbook configures the old nss resolver on systems that have the new   #
# systemd-resolved service installed. It copies the resolv.conf file for my    #
# network to /run/NetworkManager/resolv.conf and places a link to that file    #
# as /etc/resolv.conf. It then stops and disables systemd-resolved which       #
# activates the old nss resolver.                                              #
#                                                                              #
#------------------------------------------------------------------------------#
#                                                                              #
# Change History                                                               #
# Date        Name         Version   Description                               #
# 2020/11/07  David Both   00.00     Started new code                          #
# 2021/03/26  David Both   00.50     Tested OK on multiple hosts.              #
#                                                                              #
################################################################################
---
- name: Revert to old NSS resolver and disable the systemd-resolved service
  hosts: all_by_IP

################################################################################

  tasks:
    - name: Copy resolv.conf for my network
      copy:
        src: /root/ansible/resolver/files/resolv.conf
        dest: /run/NetworkManager/resolv.conf
        mode: 0644
        owner: root
        group: root

    - name: Delete existing /etc/resolv.conf file or link
      file: 
        path: /etc/resolv.conf
        state: absent

    - name: Create link from /etc/resolv.conf to /run/NetworkManager/resolv.conf
      file: 
        src: /run/NetworkManager/resolv.conf
        dest: /etc/resolv.conf
        state: link

    - name: Stop and disable systemd-resolved
      systemd:
        name: systemd-resolved
        state: stopped
        enabled: no

您使用的任何 Ansible 清单都必须有一个使用 IP 地址而不是主机名的组。此命令运行 playbook 并指定我用于按 IP 地址查找主机的清单文件的名称

# ansible-playbook -i /etc/ansible/hosts_by_IP fixResolver.yml

最终想法

有时,解决技术问题的最佳答案是回归您所知道的。当 systemd-resolved 更加健壮时,我很可能会再次尝试它,但就目前而言,我很高兴开源基础设施使我能够快速识别和解决网络问题。使用 Ansible 自动化该过程是一项非常受欢迎的奖励。这里的重要教训是在进行故障排除时进行研究,并且永远不要害怕使您的保修失效。

接下来阅读什么
David Both
David Both 是一位开源软件和 GNU/Linux 的倡导者、培训师、作家和演讲者。自 1996 年以来,他一直从事 Linux 和开源软件方面的工作,自 1969 年以来一直从事计算机方面的工作。他是“系统管理员 Linux 哲学”的坚定拥护者和传播者。

评论已关闭。

知识共享许可协议本作品根据知识共享署名-相同方式共享 4.0 国际许可协议获得许可。
© . All rights reserved.