Fix fips-dns.service pulling in systemd-resolved and hanging on missing fips0

The fips-dns.service unit had three issues:

1. Wants=systemd-resolved.service caused systemd to start systemd-resolved
   on systems that weren't using it, breaking existing DNS by rewriting
   /etc/resolv.conf to the stub resolver at 127.0.0.53.

2. The ExecStart busy-wait loop for fips0 had no timeout, hanging forever
   if fips.service failed to create the TUN device.

3. Installers unconditionally enabled fips-dns.service regardless of whether
   systemd-resolved was present.

Fix by replacing Wants= with ConditionPathExists=/run/systemd/resolve (skips
cleanly if resolved isn't running), adding Requires=fips.service (won't start
without the daemon), bounding the fips0 wait loop to 30 seconds, and making
the installers conditional on systemd-resolved being active.
This commit is contained in:
Johnathan Corgan
2026-03-10 19:19:24 +00:00
parent 7d9e7f8e18
commit b33d6531ce
5 changed files with 54 additions and 15 deletions
+14 -3
View File
@@ -1,11 +1,22 @@
[Unit]
Description=Configure DNS routing for .fips domain
After=systemd-resolved.service
Wants=systemd-resolved.service
After=fips.service systemd-resolved.service
Requires=fips.service
ConditionPathExists=/run/systemd/resolve
[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c 'while ! ip link show fips0 >/dev/null 2>&1; do sleep 1; done; /usr/bin/resolvectl dns fips0 127.0.0.1:5354; /usr/bin/resolvectl domain fips0 ~fips'
ExecStart=/usr/bin/bash -c '\
for i in $(seq 1 30); do \
ip link show fips0 >/dev/null 2>&1 && break; \
sleep 1; \
done; \
if ! ip link show fips0 >/dev/null 2>&1; then \
echo "fips0 interface not found after 30s" >&2; \
exit 1; \
fi; \
/usr/bin/resolvectl dns fips0 127.0.0.1:5354; \
/usr/bin/resolvectl domain fips0 ~fips'
RemainAfterExit=yes
[Install]
+6 -2
View File
@@ -18,12 +18,16 @@ case "$1" in
if [ -d /run/systemd/system ]; then
systemctl daemon-reload
systemctl enable fips.service 2>/dev/null || true
systemctl enable fips-dns.service 2>/dev/null || true
if systemctl is-active --quiet systemd-resolved.service 2>/dev/null; then
systemctl enable fips-dns.service 2>/dev/null || true
fi
# On upgrade, restart services that were running before
if [ -n "$2" ]; then
systemctl start fips.service 2>/dev/null || true
systemctl start fips-dns.service 2>/dev/null || true
if systemctl is-enabled --quiet fips-dns.service 2>/dev/null; then
systemctl start fips-dns.service 2>/dev/null || true
fi
fi
fi
;;
+12 -5
View File
@@ -76,19 +76,26 @@ peers:
connect_policy: auto_connect
```
### 4. DNS Resolver
### 4. DNS Resolver (optional, requires systemd-resolved)
FIPS includes a DNS responder for `.fips` domain names (port 5354).
To integrate with systemd-resolved:
On systems running `systemd-resolved`, the installer automatically enables
`fips-dns.service` to route `.fips` queries to the FIPS resolver.
If `systemd-resolved` is not running at install time, DNS integration is
skipped. To enable it later (after starting `systemd-resolved`):
```bash
sudo systemctl enable --now fips-dns.service
```
For manual configuration without `fips-dns.service`:
```bash
sudo resolvectl dns fips0 127.0.0.1:5354
sudo resolvectl domain fips0 ~fips
```
To make this persistent, create a systemd-networkd override or add a
drop-in for the fips0 interface.
## Firewall Ports
| Port | Protocol | Purpose |
+14 -3
View File
@@ -1,11 +1,22 @@
[Unit]
Description=Configure DNS routing for .fips domain
After=systemd-resolved.service
Wants=systemd-resolved.service
After=fips.service systemd-resolved.service
Requires=fips.service
ConditionPathExists=/run/systemd/resolve
[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c 'while ! ip link show fips0 >/dev/null 2>&1; do sleep 1; done; /usr/bin/resolvectl dns fips0 127.0.0.1:5354; /usr/bin/resolvectl domain fips0 ~fips'
ExecStart=/usr/bin/bash -c '\
for i in $(seq 1 30); do \
ip link show fips0 >/dev/null 2>&1 && break; \
sleep 1; \
done; \
if ! ip link show fips0 >/dev/null 2>&1; then \
echo "fips0 interface not found after 30s" >&2; \
exit 1; \
fi; \
/usr/bin/resolvectl dns fips0 127.0.0.1:5354; \
/usr/bin/resolvectl domain fips0 ~fips'
RemainAfterExit=yes
[Install]
+8 -2
View File
@@ -116,8 +116,14 @@ echo "tmpfiles.d entry created for /run/fips/ ownership."
# --- Enable service ---
systemctl enable fips.service
systemctl enable fips-dns.service
echo "Services enabled (will start on boot)."
if systemctl is-active --quiet systemd-resolved.service 2>/dev/null; then
systemctl enable fips-dns.service
echo "Services enabled (will start on boot)."
else
echo "fips.service enabled (will start on boot)."
echo " Note: fips-dns.service not enabled (systemd-resolved is not running)."
echo " To enable .fips DNS later: sudo systemctl enable --now fips-dns.service"
fi
# Restart if they were running before
if $was_active; then