From 2b05e6da6bc45741dda5dac6766670c15c6124d3 Mon Sep 17 00:00:00 2001 From: Clayton Craft Date: Tue, 21 Jul 2026 22:28:22 -0700 Subject: [PATCH] systemd/postmarketos-base-systemd: symlink resolv.conf to resolved stub This logic is "borrowed" from Fedora, and replaces /etc/resolv.conf with a symlink to the systemd-resolved stub. Fedora does this from an install script, but that doesn't work for image-based installs since those never run install scripts on the device, and /etc persists across updates. I've also seen cases in testing where the symlink was removed by e.g. accidentally running resolvconf or something similar. So this runs from a oneshot unit at boot instead, which is ordered before network-pre.target so NetworkManager doesn't get there first. The old resolved.post-install script is dropped since the unit covers both cases. There are some conditions where resolv.conf is **not** replaced: - when resolv.conf is already a symlink - when systemd-resolved isn't enabled - when its stub listener is disabled (via DNSStubListener= in config) - when systemd isn't running, since resolved isn't either and replacing resolv.conf would just break dns (e.g. when running the unit's script by hand) - when resolv.conf is a bind mount (e.g. in a chroot or container) This assumes that if a user/sys admin wants to hand-roll their own resolv.conf, that they either disable the systemd-resolved unit or disable the stub listener in config if they want to use foreign mode. The resolved drop-ins are also renamed with a 10- prefix, to match the numbering ranges UAPI.6 recommends for vendor config in /usr. Signed-off-by: Clayton Craft Part-of: --- .../postmarketos-base-systemd/APKBUILD | 27 ++++++++------- ...arketos-base-systemd-resolved.post-install | 5 --- .../rootfs-usr-bin-resolv-conf-stub-link | 33 +++++++++++++++++++ ...esolved.conf.d-10-disable-dnsovertls.conf} | 0 ...temd-resolved.conf.d-10-disable-mdns.conf} | 0 ...r-lib-systemd-system-preset-90-base.preset | 1 + ...stemd-system-resolv-conf-stub-link.service | 15 +++++++++ 7 files changed, 65 insertions(+), 16 deletions(-) delete mode 100644 extra-repos/systemd/postmarketos-base-systemd/postmarketos-base-systemd-resolved.post-install create mode 100644 extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-bin-resolv-conf-stub-link rename extra-repos/systemd/postmarketos-base-systemd/{rootfs-usr-lib-systemd-resolved.conf.d-disable-dnsovertls.conf => rootfs-usr-lib-systemd-resolved.conf.d-10-disable-dnsovertls.conf} (100%) rename extra-repos/systemd/postmarketos-base-systemd/{rootfs-usr-lib-systemd-resolved.conf.d-disable-mdns.conf => rootfs-usr-lib-systemd-resolved.conf.d-10-disable-mdns.conf} (100%) create mode 100644 extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-resolv-conf-stub-link.service diff --git a/extra-repos/systemd/postmarketos-base-systemd/APKBUILD b/extra-repos/systemd/postmarketos-base-systemd/APKBUILD index fc1bd4a58..ba82832f5 100644 --- a/extra-repos/systemd/postmarketos-base-systemd/APKBUILD +++ b/extra-repos/systemd/postmarketos-base-systemd/APKBUILD @@ -1,7 +1,7 @@ # pmbootstrap installs this, if systemd is selected in "pmbootstrap init". maintainer="Clayton Craft " pkgname=postmarketos-base-systemd -pkgver=90 +pkgver=91 pkgrel=0 pkgdesc="Meta package for running postmarketOS with systemd" url="https://postmarketos.org" @@ -49,7 +49,6 @@ install=" $pkgname.post-install $pkgname.post-upgrade $pkgname.pre-upgrade - $pkgname-resolved.post-install " subpackages=" $pkgname-resolved @@ -63,12 +62,13 @@ _source644=" usr/lib/NetworkManager/conf.d/50-dns.conf usr/lib/systemd/journald.conf.d/10-postmarketos.conf usr/lib/systemd/logind.conf - usr/lib/systemd/resolved.conf.d/disable-dnsovertls.conf - usr/lib/systemd/resolved.conf.d/disable-mdns.conf + usr/lib/systemd/resolved.conf.d/10-disable-dnsovertls.conf + usr/lib/systemd/resolved.conf.d/10-disable-mdns.conf usr/lib/systemd/system-preset/90-base.preset usr/lib/systemd/system/-.slice.d/10-oomd-defaults.conf usr/lib/systemd/system/apk-inhibit.path usr/lib/systemd/system/apk-inhibit.service + usr/lib/systemd/system/resolv-conf-stub-link.service usr/lib/systemd/system/system.slice.d/10-oomd-defaults.conf usr/lib/systemd/system/tmp.mount.d/10-min-memory.conf usr/lib/systemd/system/unudhcpd@usb0.service.d/udc-only.conf @@ -80,9 +80,10 @@ _source644=" _source755=" etc/apk/commit_hooks.d/postmarketos-base-systemd + usr/bin/resolv-conf-stub-link usr/bin/setup-timezone - usr/libexec/systemd-apk-trigger usr/libexec/apk-inhibit + usr/libexec/systemd-apk-trigger " flatpath() { @@ -113,9 +114,11 @@ package() { resolved() { install_if="$pkgname=$pkgver-r$pkgrel systemd-resolved" - amove usr/lib/systemd/resolved.conf.d/disable-dnsovertls.conf - amove usr/lib/systemd/resolved.conf.d/disable-mdns.conf + amove usr/bin/resolv-conf-stub-link amove usr/lib/NetworkManager/conf.d/50-dns.conf + amove usr/lib/systemd/resolved.conf.d/10-disable-dnsovertls.conf + amove usr/lib/systemd/resolved.conf.d/10-disable-mdns.conf + amove usr/lib/systemd/system/resolv-conf-stub-link.service } _apk() { @@ -139,12 +142,13 @@ ff5b22d095d240a7a222afcdea14cbca8ee78472df3553827c5c02753ee97d84b59624a87952afa5 94063e3a3f983b7613d9de6bfc067096f79b12688f45667faf968f9a9bae194c4c8e554311f2ab5614edcc4d4499f6d30aa965a67b7417c26ce4d07edc847178 rootfs-usr-lib-NetworkManager-conf.d-50-dns.conf b7c3e70f5e4d88d6df6a8d58f4bb6af3d3051c5130cf13ad86a491fcbf7a69ae33ba31d663946c35ddaed03a16b6eb9d9d4b7cabcb58bfec7a254920ff375178 rootfs-usr-lib-systemd-journald.conf.d-10-postmarketos.conf bd85f6153d857e1aec191b5fc8c8fc0d87125bf0198bef20d1e91ef40ca7e9ed1209a64ae279f98dc8733969ad6e71e29623180ef2203e386023a950d9ce8269 rootfs-usr-lib-systemd-logind.conf -e49972d276441e9da284315bab5f70d8d25ccba5e43d7e7ec6607c34a3d4dfa512f7303d5ce41076819ef24f5dced5acc74001b4d569258269de34da27912466 rootfs-usr-lib-systemd-resolved.conf.d-disable-dnsovertls.conf -93ab180810dbd2a1477f7ea0f0959be90f099272fe5840030a0772771c97a066b70068c476d32c6a4610b8f7b9fc5bfcf1d7a93f071cec026553ac6a3b8b5324 rootfs-usr-lib-systemd-resolved.conf.d-disable-mdns.conf -c349260b91a80f1850744259ec920cb94b5b50bd4071899061919fe02f727679a3bb8bd427309deea3d091dab18ffdc7c5fcfec5eef1988e7a51e87196f703f4 rootfs-usr-lib-systemd-system-preset-90-base.preset +e49972d276441e9da284315bab5f70d8d25ccba5e43d7e7ec6607c34a3d4dfa512f7303d5ce41076819ef24f5dced5acc74001b4d569258269de34da27912466 rootfs-usr-lib-systemd-resolved.conf.d-10-disable-dnsovertls.conf +93ab180810dbd2a1477f7ea0f0959be90f099272fe5840030a0772771c97a066b70068c476d32c6a4610b8f7b9fc5bfcf1d7a93f071cec026553ac6a3b8b5324 rootfs-usr-lib-systemd-resolved.conf.d-10-disable-mdns.conf +a06c76afda2abe4e9fd721b9484a044d909cc0c5d94fd1062c41436c3c1a5c4b70b4a02bcb18599b725d8cbee2fa2355135ebc131194736c2add75ecce1ff00c rootfs-usr-lib-systemd-system-preset-90-base.preset bde7052939d1ddde22fe1df86439d3f1b0cd41810911cee7acf26aac08afe1610360cbbd257b3c1a2e5e7409dff27ade8f3a302a38cd1b99c6cc6eed4cc64a78 rootfs-usr-lib-systemd-system--.slice.d-10-oomd-defaults.conf e81ffc21ef12fe41555bf065836b01bdaeb4e332e8fbb083fb3f1743f920f1d2a1a4fe848d759ec486f7da0add32478ff2fd7f24c0dec9f9974406ac075f61b0 rootfs-usr-lib-systemd-system-apk-inhibit.path 5af6294b8936dee1e2e8429c7eecd28c0e641adffb55d45b05624845971d0ed99ce31b4a1f3c80bc8aa1c59dc2b60ab9e32f78f03c21650c61957c567547f464 rootfs-usr-lib-systemd-system-apk-inhibit.service +7e7a6151d0739f1ec89dcaaef4c2ca491a761afb7ee5aa2bcc0dab08f8f7a3773c0a969fde2b298f269c154f5c325158a950e50c432d308e82d026ce6d388331 rootfs-usr-lib-systemd-system-resolv-conf-stub-link.service bde7052939d1ddde22fe1df86439d3f1b0cd41810911cee7acf26aac08afe1610360cbbd257b3c1a2e5e7409dff27ade8f3a302a38cd1b99c6cc6eed4cc64a78 rootfs-usr-lib-systemd-system-system.slice.d-10-oomd-defaults.conf cedd159b98ce47ee9d03e5f332c4132c7c3eff32135aa7b7993e19c4867d55aff689b418fc549e139c0ea4690f1094e86efcee7a5bc6cd6998ba99821064a917 rootfs-usr-lib-systemd-system-tmp.mount.d-10-min-memory.conf 9f589ac903f9d1bec228cc6ae45ecba974fbb45a08ce81b68566a98296402822382b166543e62966a1630b482a645063990d905def42d7956e79cd462395fe9b rootfs-usr-lib-systemd-system-unudhcpd@usb0.service.d-udc-only.conf @@ -153,7 +157,8 @@ c6b22809e77d3134285233988d805c9cdbc3e3c90af320e920aaf4dcfd83582c2a85278f2edf07e7 4217385ab8e0d0e53a6f6eb2ad0ef5c1ae88cab431c9fdca3528f147241edfefe7eec8f2927670dcf79c6f853d2c8a930782fad7e2a28ef6575b55df115f2f83 rootfs-usr-lib-systemd-user-app.slice.d-10-oomd-defaults.conf 15423bfda57c90ab62fe69865ca4072a0aeb83bf77d9c278257e346f4da81843d010b41003c91ae9f3fcb1c67447645e7c19078eea2bf11312051e6ad7523ad1 rootfs-usr-share-mkinitfs-files-extra-01-initramfs-base-systemd.files 6ff3fbd88493e50de5821c6e3db92623b38de52be4e8e967f4f297d8f70e31a86d91f1243b973387b80c8520edcc89a8233db6f234bca22a56ee61a1b4333670 rootfs-etc-apk-commit_hooks.d-postmarketos-base-systemd +031b1c3a39249ce8fe4b0ec8e68813fd3ffe042366b9e49e8f8f700d7731edb71f7ade333987684c7b9d658e06d8e7998aae9de6bb88550bd620e9ae80145761 rootfs-usr-bin-resolv-conf-stub-link 605df1f004783d2e0ec5dd99a688bca27502c8c24bc05fb4dc26589b2070b0fbd1cf9bd56e6861d7cda2f8ac8147e7eb040acfd886185c01c8cf9de8b1ce2dcd rootfs-usr-bin-setup-timezone -d96898efb28508b172f148c0a468a7dddd363dde94efea7c2274b9f746544b4e8bf7905ce3f8134a97c1eb33210ad97380f3da452082f346f1f3f0f665f79d47 rootfs-usr-libexec-systemd-apk-trigger 237f5478bed05128bba6b44f1545e904447b53779d37bf0bedb1c1bc68c53394ba767ef52d3ff4980d593f02daea0b05454a316a0348821de924308109deced6 rootfs-usr-libexec-apk-inhibit +d96898efb28508b172f148c0a468a7dddd363dde94efea7c2274b9f746544b4e8bf7905ce3f8134a97c1eb33210ad97380f3da452082f346f1f3f0f665f79d47 rootfs-usr-libexec-systemd-apk-trigger " diff --git a/extra-repos/systemd/postmarketos-base-systemd/postmarketos-base-systemd-resolved.post-install b/extra-repos/systemd/postmarketos-base-systemd/postmarketos-base-systemd-resolved.post-install deleted file mode 100644 index 5d8aa9757..000000000 --- a/extra-repos/systemd/postmarketos-base-systemd/postmarketos-base-systemd-resolved.post-install +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -[ "$(realpath /etc/resolv.conf)" == /run/systemd/resolve/stub-resolv.conf ] && exit 0 -rm -f /etc/resolv.conf -ln -s /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf diff --git a/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-bin-resolv-conf-stub-link b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-bin-resolv-conf-stub-link new file mode 100644 index 000000000..ecb3fe2fe --- /dev/null +++ b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-bin-resolv-conf-stub-link @@ -0,0 +1,33 @@ +#!/bin/sh +# This script replaces /etc/resolv.conf with a symlink to the systemd-resolved +# stub config if certain conditions are met. + +# bail out early if it's already a symlink +[ -L /etc/resolv.conf ] && exit 0 + +# Only touch resolv.conf if resolved is enabled and its stub listener isn't +# turned off. +# This assumes that anyone running their own resolver will disable the unit (or +# set DNSStubListener=no), in which case we leave their resolv.conf file alone. + +# In case the DNSStubListener option is set several times in differnt +# config/drop-ins, the last one parsed wins. +# So, this tries to get the last printed config for the DNSStubListener option. +stub=$(systemd-analyze cat-config systemd/resolved.conf 2>/dev/null | + tr -d ' \t' | + grep -ioE '^DNSStubListener=[^#]*' | + tail -n1) +if systemctl is-enabled systemd-resolved.service >/dev/null 2>&1 && + ! echo "$stub" | grep -iqxE 'DNSStubListener=(no?|f(alse)?|0|off)'; then + + # skip bind-mounted resolv.conf, because it was probably mounted by a chroot or + # container, otherwise replace whatever is there. Also skip if systemd isn't + # running, since resolved isn't either and we would just break dns if we + # replaced resolv.conf with a symlink to the stub (this only comes up when + # running the script by hand, the unit implies it's up.) + if ! mountpoint -q /etc/resolv.conf && + [ -d /run/systemd/system ]; then + ln -fs ../run/systemd/resolve/stub-resolv.conf /etc/resolv.conf + fi +fi + diff --git a/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-disable-dnsovertls.conf b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-10-disable-dnsovertls.conf similarity index 100% rename from extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-disable-dnsovertls.conf rename to extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-10-disable-dnsovertls.conf diff --git a/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-disable-mdns.conf b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-10-disable-mdns.conf similarity index 100% rename from extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-disable-mdns.conf rename to extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-resolved.conf.d-10-disable-mdns.conf diff --git a/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-preset-90-base.preset b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-preset-90-base.preset index 51a6882f7..4e048b306 100644 --- a/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-preset-90-base.preset +++ b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-preset-90-base.preset @@ -43,6 +43,7 @@ enable unudhcpd@.service usb0 enable dbus-broker.service enable avahi-daemon.service enable routewrangler.service +enable resolv-conf-stub-link.service # Note: technically these two shouldn't be enabled at the same time, but # pmos-base-wifi provides should make sure that only one is installed at the diff --git a/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-resolv-conf-stub-link.service b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-resolv-conf-stub-link.service new file mode 100644 index 000000000..639fd4e38 --- /dev/null +++ b/extra-repos/systemd/postmarketos-base-systemd/rootfs-usr-lib-systemd-system-resolv-conf-stub-link.service @@ -0,0 +1,15 @@ +[Unit] +Description=Migrate /etc/resolv.conf to the systemd-resolved stub +Documentation=man:systemd-resolved.service(8) +ConditionPathIsSymbolicLink=!/etc/resolv.conf +Wants=network-pre.target +Before=network-pre.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/bin/resolv-conf-stub-link + +[Install] +WantedBy=multi-user.target +