Skip to content

Brev base image's first-boot script renames the host without updating /etc/hosts; sudo / hostname -f hang for ~10s on every call #399

@robobryce

Description

@robobryce

What

Brev's first-boot /opt/setup.sh renames the host to brev-${BREV_ENV_ID} but doesn't add a matching /etc/hosts entry. The default Ubuntu NSS order (hosts: files dns ... in /etc/nsswitch.conf, with resolv.conf symlinked to systemd-resolved's stub) then sends every gethostbyname() on the local hostname to upstream DNS, which has no record for it. The lookup times out at ~10s before LLMNR / mDNS finally answers with a link-local IPv6 address.

Anything that resolves the local hostname pays that ~10s on every invocation:

  • sudo (it does a hostname lookup to match Defaults and host rules in sudoers — so sudo true itself is enough).
  • hostname -f.
  • mail, sendmail, cron, anything that calls Sys::Hostname from Perl, etc.

The user-visible symptom is "every sudo command on a fresh Brev VM takes ten seconds before it does anything." First-time users tend to attribute it to the VM still being slow / first-boot still finishing; the actual cause survives a reboot and never goes away on its own.

Reproducer

On any fresh Brev workspace immediately after brev create:

$ time sudo true

real	0m10.021s
user	0m0.004s
sys	0m0.006s

$ time sudo -n true     # non-interactive — no password prompt, still 10s

real	0m10.020s
user	0m0.003s
sys	0m0.006s

$ hostname
brev-gen8x2a9s

$ grep \"\$(hostname)\" /etc/hosts || echo \"hostname not in /etc/hosts\"
hostname not in /etc/hosts

$ time getent hosts \$(hostname)
fdd1:eccf:8581:6581:2894:2e00:ff7c:bdf5 brev-gen8x2a9s
fd7a:115c:a1e0::9b3b:1064 brev-gen8x2a9s
fe80::4001:aff:fe8a:527 brev-gen8x2a9s
fe80::83fd:9880:6452:8b5d brev-gen8x2a9s

real	0m10.010s
user	0m0.002s
sys	0m0.001s

The getent hosts block confirms the chain: NSS asks files (no entry), falls through to dns via systemd-resolved (10s timeout), then the only answers come from LLMNR / mDNS as link-local IPv6 / Tailscale ULA addresses — none of which are useful, and arrive only after the 10s the user already paid.

/etc/hosts on a fresh box looks like this:

127.0.0.1 localhost

# The following lines are desirable for IPv6 capable hosts
::1 ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
ff02::3 ip6-allhosts
169.254.169.254 metadata.google.internal metadata

— note the absence of any line mapping the actual machine hostname (brev-<env_id>).

Suggested fix

In whichever stage of /opt/setup.sh performs the hostnamectl set-hostname brev-${BREV_ENV_ID} (or equivalent), append the matching loopback line to /etc/hosts. The Debian / Ubuntu convention is 127.0.1.1, distinct from 127.0.0.1 localhost:

hostnamectl set-hostname \"brev-${BREV_ENV_ID}\"
if ! awk -v h=\"brev-${BREV_ENV_ID}\" '
    !/^[[:space:]]*#/ { for (i=2; i<=NF; i++) if (\$i==h) { found=1; exit } }
    END { exit !found }
' /etc/hosts; then
    printf '127.0.1.1\t%s\n' \"brev-${BREV_ENV_ID}\" >>/etc/hosts
fi

This mirrors what cloud-init's update_etc_hosts module and most distros' /etc/hostname/etc/hosts linkage do automatically when a hostname is set at install time. The Brev base image diverges by setting the hostname later (after first boot, in /opt/setup.sh), so the standard tooling never closes the loop.

Impact

Cumulatively significant for any automation that runs many sudo calls on a Brev VM (CI runners, bootstrap scripts, anything ssh'ing in and shelling out): each sudo invocation eats 10s before doing real work. Interactive users feel it as the whole shell being sluggish. The fix is one line in the first-boot script and is invisible to users who never noticed the slowdown.

Workaround

Append 127.0.1.1 \$(hostname) to /etc/hosts once after the workspace boots:

echo \"127.0.1.1 \$(hostname)\" | sudo tee -a /etc/hosts >/dev/null

sudo true drops from ~10s to <50ms immediately.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions