secure-network: fix intermittent DNS failure on Ubuntu runners (resolv.conf symlink)#175
secure-network: fix intermittent DNS failure on Ubuntu runners (resolv.conf symlink)#175
Conversation
…overwrite on Ubuntu runners On GitHub-hosted Ubuntu runners, /etc/resolv.conf is a symlink to /run/systemd/resolve/stub-resolv.conf on tmpfs. Writing through the symlink let systemd-resolved silently overwrite our nameserver change, and chattr +i was a no-op on tmpfs. This caused intermittent DNS failures: DNS queries went to 127.0.0.53 (systemd-resolved's stub), which was blocked by iptables and not listening anyway. Fix: remove any symlink before writing, so /etc/resolv.conf becomes a real file on /etc (ext4) that chattr can lock. Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
There was a problem hiding this comment.
Claude Code Review
This repository is configured for manual code reviews. Comment @claude review to trigger a review and subscribe this PR to future pushes, or @claude review once for a one-time review.
Tip: disable this comment in your organization's Code Review settings.
🦋 Changeset detectedLatest commit: 4bdf82b The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
GeraldRequired Reviewers
Don't want to be involved in this pull request? Comment |
| } catch (_) { | ||
| /* not a symlink or doesn't exist — proceed */ | ||
| } |
There was a problem hiding this comment.
this catch feels a little over-general -- if we want the "doesn't exist" case, we could fo fs.existsSync(path) && fs.lstatSync(path).isSymbolicLink()
Summary
secure-networkwould set up Unbound correctly but DNS queries would still fail/etc/resolv.confis a symlink to/run/systemd/resolve/stub-resolv.confon tmpfs. Writing through the symlink put ournameserver 127.0.0.1on tmpfs, wherechattr +iis a no-op — so systemd-resolved could silently overwrite the file back tonameserver 127.0.0.53/etc/resolv.confbecomes a regular file on/etc(ext4), wherechattr +iactually locks itHow the failure manifested
Post-job diagnostics (added in #171) showed:
/etc/resolv.confcontainednameserver 127.0.0.53(systemd-resolved's stub) instead ofnameserver 127.0.0.1connection refused to 127.0.0.53#53— systemd-resolved was stopped but iptables also REJECTs queries to127.0.0.53(only127.0.0.1:53is allowed)Why it was intermittent
systemd-resolved only rewrites its stub file in response to network events (DHCP renewals, interface changes, etc.). Most runs complete without such an event in the narrow window between our
writeFileSyncand the failedchattr +i, so it usually works. Occasionally a runner gets a network event mid-job and the file is overwritten.Test plan
secure-networkand confirm the new log line appears:Removed /etc/resolv.conf symlink (was managed by systemd-resolved).nameserver 127.0.0.1in/etc/resolv.conf🤖 Generated with Claude Code