testsAndMisc-archive/linux_configuration/scripts/periodic_background/hosts/guard
Krzysztof kuhy Rudnicki fab9d6ecf8 fix(hosts-guard): stop setup aborting silently, so the guards actually enable
setup_hosts_guard.sh died partway on every run under `set -euo pipefail`,
which is why hosts-guard.path / hosts-bind-mount.service / nsswitch-guard.path
sat installed-but-disabled since 2026-02-02 and resolved-guard.path was never
installed at all — /etc/hosts had no watcher to restore it if tampered.

Two aborts, both silent:

1. `local_dot=$(grep -E '^\s*DNSOverTLS\s*=' ... | tail -1 | sed ...)` — grep
   exits 1 when the key is absent, pipefail propagates, the assignment returns
   1, set -e kills the script. DNSOverTLS is absent from a default
   resolved.conf, so this fired on EVERY run, right before resolved-guard.path
   was enabled. The fix-if-missing branch below it was unreachable because
   detecting "missing" aborted first. Same trap on the ReadEtcHosts probe.
   check_and_enable_services.sh already guarded its copy with `|| true`.

2. `systemctl restart systemd-resolved` — resolved is MASKED here (dnsmasq
   serves DNS), so the restart failed and aborted the script on its last step,
   after everything was already configured. Now skipped with a note.

Before: exit 1, resolved-guard disabled, nsswitch-guard start-limit-hit.
After: exit 0; hosts-guard.path, hosts-bind-mount.service, nsswitch-guard.path
and resolved-guard.path all enabled+active. DNS still resolves; getent ahosts
on doubleclick/googlesyndication/facebook returns 0.0.0.0; /etc/hosts still
immutable at 176888 lines.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JsCs1GUyiinA7bg68YvAh1
2026-07-17 08:25:51 +02:00
..
pacman-hooks refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
psychological refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
enforce-hosts.sh refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
enforce-nsswitch.sh refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
enforce-resolved.sh refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
hosts-bind-mount.service refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
hosts-guard.path refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
hosts-guard.service refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
install_pacman_hooks.sh refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
nsswitch-guard.path refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
nsswitch-guard.service refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
README_FOR_LLM.md refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
README.md refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
resolved-guard.path refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
resolved-guard.service refactor(linux_configuration): move remaining dirs + scripts/ to meta/ 2026-05-15 00:53:01 +02:00
setup_hosts_guard.sh fix(hosts-guard): stop setup aborting silently, so the guards actually enable 2026-07-17 08:25:51 +02:00

Hosts Guard Components

This directory contains templates for hardening /etc/hosts against impulsive tampering by adding friction, NOT providing absolute security against a determined root user.

Components:

  1. enforce-hosts.sh – Idempotent script that: compares /etc/hosts with canonical copy at /usr/local/share/locked-hosts and restores if different; reapplies immutable attribute.
  2. systemd units (to be installed under /etc/systemd/system):
    • hosts-guard.service (oneshot enforcement)
    • hosts-guard.path (triggers on PathChanged=/etc/hosts)
    • hosts-bind-mount.service (bind mounts /etc/hosts read-only after boot)
  3. psychological/ directory – scripts that add delay + journaling before allowing a maintenance/unlock operation.
  4. pacman hooks – automatically unlock/re-lock /etc/hosts around package transactions so pacman never fails due to the read-only bind mount.

Install Flow (suggested):

  1. After generating /etc/hosts via your existing hosts/install.sh, copy it to /usr/local/share/locked-hosts.
  2. Install enforce-hosts.sh to /usr/local/sbin/ (chmod 755).
  3. Place units and enable: systemctl daemon-reload systemctl enable --now hosts-guard.path systemctl enable --now hosts-bind-mount.service
  4. (Optional) Use psychological/unlock-hosts.sh as the ONLY sanctioned way to modify hosts (it removes protections temporarily, launches an editor after a delay, and re-enforces on close).
  5. Make pacman automatic (recommended): ./install_pacman_hooks.sh This installs hooks under /etc/pacman.d/hooks that:
    • PreTransaction: temporarily disable guard and make /etc/hosts writable
    • PostTransaction: re-run enforcement and re-enable guard (bind mount + path watcher)

Limitations:

  • A root user can still disable units, remount, remove attributes.
  • Purpose is to interrupt habit loops and create intentional friction.