[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Revisiting the hostname/FQDN issue, adding libnss-myhostname



On Mon, 13 Oct 2025 at 22:22:45 +0200, Marc Haber wrote:
a new (?) systemd feature

libnss-myhostname started as an independent NSS module before being absorbed into the systemd codebase for more code-sharing (much like udev). There's nothing *particularly* systemd-specific about it.

The biggest question that I still have is why we are writing an /etc/hosts with "127.0.1.1 apollo.example.com apollo". Without that, the FQDN of the system is incorrect.

For some value of "incorrect", anyway: a large part of the problem here is that there's no formal specification I'm aware of for what is considered "correct" or "incorrect", only Unix folklore and some strong opinions (some of which might be contradictory). Some software, especially if it has decades of history, assumes that the hostname (as in gethostname(2)) is resolvable in DNS, but that isn't something that can generally be guaranteed, especially for a portable machine on a network not under your control. Typically[citation needed] laptop owners expect the laptop "apollo" to remain named "apollo" when they connect it to someone else's LAN, even if the network owner has decided that the IP address allocated to "apollo" by their DHCP will be associated with something like "guest01.internal" in their local DNS.

The hostname(1) man page defines the FQDN as the name that the resolver returns when asked for information about the hostname (as in gethostname(2)), and notes that by this definition there might be zero, one or many FQDNs. If the FQDN isn't forced via /etc/hosts, then it might also vary according to the LAN(s) that the machine happens to be connected to right this moment (especially for mobile computers).

One way to describe the purpose of libnss-myhostname is: we know that some software assumes that the result of gethostname(2) is resolvable; and we know that this can't be guaranteed to be true in the global DNS system because mobile computers are a thing that exists; so let's force that assumption to be true at least locally, by having a last-resort mechanism to ensure that the local hostname always resolves to a locally-available IP address at any given time, to try to maximize the amount of software that has its assumptions met and continues to work as designed.

I'm sure we could write a surprisingly lengthy document similar to the classic "Falsehoods Programmers Believe About Names", but for hostnames.

But why 127.0.1.1? Arch Linux does it the same way, but they don't explain why, either.

127.0.1.1 is one of the 256**3 loopback addresses (the whole 127.x block). I believe the reasoning for using that, and not 127.0.0.1, is that it means a reverse-DNS lookup for 127.0.0.1 (for example in the output of netstat, to label a service listening on only the loopback interface) will yield the expected "localhost", and not "apollo.example.com" which would be surprising.

libnss-myhostname does this dynamically rather than by writing static configuration, so it will try to use one of the machine's reachable IP addresses (192.0.2.123 or something), falling back to 127.0.0.2 if there's nothing better available. 127.0.0.2 is conceptually similar to 127.0.1.1, just a slightly different implementation choice.

On some of my trixie systems (but not on all of them), libnss-myhostname got installed. This changed the nsswitch.conf "hosts: files dns" to "hosts: files myhostname dns".

libnss-myhostname is meant to be conceptually equivalent to putting something similar to the conventional "$ipaddress apollo" into /etc/hosts, hence its position close to "files" (which is the plugin that actually implements /etc/hosts lookup).

Because it's sequenced after "files" in nsswitch.conf, whatever is manually configured in /etc/hosts should usually take precedence, but small details can matter here. But because it's sequenced before "dns", it prevents a non-local DNS server (like the one on the wifi network outside your control that you connected your laptop to) from influencing what the machine thinks its own FQDN is.

On those systems, getent hosts hostname returns the short hostname, while on the systems that don't have myhostname installed the same call returns the FQDN.

On a typical affected system, what is in /etc/hostname and what is the result of uname(2)? An easy way to query this interactively is:

    cat /etc/hostname
    python3 -c 'import os; print(repr(os.uname()))'

(It's fine if your answer is redacted to remove the system's real hostname and DNS domain name and instead pretend that it's apollo(.example.com) or something, but please be specific about the number and position of dots, because they can matter. Similarly it's fine to redact the kernel version, etc. which aren't interesting here)

How much our current behavior is standard Unix, how much are Debianisms?

I think we can safely assume that it's all Unix, even (especially?) the contradictory parts, but none of it is standard.

    smcv


Reply to: