systemd-resolved-rs 0.1.1

A compatibility-oriented reimplementation of systemd-resolved
# Certified replacement procedure

`systemd-resolved-rs` must not replace the host resolver merely because it
builds or because ordinary CI is green. Replacement is permitted only when a
single immutable Git tree has a portable schema-2 certificate with every gate
set to `pass`.

The distribution's `systemd-resolved` package remains installed throughout the
procedure. It is the rollback payload and must not be removed.

## Certification gates

The certificate is fail-closed and binds all evidence to the same Git tree,
upstream systemd commit, daemon SHA-256, client SHA-256, and NSS module
SHA-256. It requires:

- a clean source tree and immutable pinned upstream baseline;
- complete pinned D-Bus, Varlink, configuration, and `resolvectl` surface
  inventory coverage;
- Rust formatting, Clippy, all-target tests, Rust 1.74 compatibility, native
  C/Fortran checks, packaging checks, and NSS integration;
- byte-identical daemon, client, NSS, and normalized replacement packages from
  two independent release builds;
- live UDP, TCP, D-Bus, Varlink, NSS, mDNS resolver, mDNS responder, simultaneous
  resolver/responder, and DNS-SD publication/reload tests;
- host shadow comparison against the installed resolver without changing
  `/etc/resolv.conf`;
- the pinned upstream `TEST-75-RESOLVED` suite with the candidate daemon,
  client, and NSS module, plus `TEST-89-RESOLVED-MDNS`, with bound proof that
  the candidate daemon actually ran;
- libFuzzer, AddressSanitizer, UndefinedBehaviorSanitizer, Miri strict
  provenance, ThreadSanitizer, and Valgrind evidence;
- two QEMU boots with the candidate healthy on both boots followed by a healthy
  rollback to the distribution resolver.

A skipped, stale, missing, malformed, or failed gate makes `certified` false.

## Produce one exact-SHA certificate

In GitHub Actions, run **Full replacement certification**. Leave `source_sha`
blank to select the dispatch-time `main` commit, or provide a full 40-character
commit ID.

The orchestrator dispatches and waits for:

1. Replacement security gates
2. Replacement upstream TEST-75 proof
3. Replacement upstream TEST-89 mDNS proof
4. Replacement boot and rollback proof
5. Replacement security proof
6. Replacement readiness certificate

Download the final `replacement-readiness-<sha>` artifact. The workflow only
succeeds when `replacement-certification.json` says:

```json
{"certified": true}
```

The artifact also contains the verified daemon, client, logs, proof files, and
reproducible release output.

## Verify the downloaded bundle

Check out the exact source commit named by the certificate, then verify the
bundle before acquiring root privileges:

```sh
python3 scripts/verify-readiness-bundle.py \
  --certificate /path/to/replacement-certification.json
```

The verifier rejects stale certificates, unsafe relative paths, missing files,
and daemon, client, or NSS module hash mismatches. A certificate is accepted for
at most 24 hours by default.

## Transactionally switch the host

Run the switch script from the exact certified repository checkout:

```sh
sudo bash scripts/switch-resolved-transactionally-v2.sh \
  --certificate /path/to/replacement-certification.json \
  --external-name example.com
```

The operation:

- installs versioned candidate binaries without deleting the distribution
  package;
- snapshots the existing drop-in, mask/enable state, active state, guard unit,
  `/etc/resolv.conf`, and `/etc/nsswitch.conf`;
- changes only the `systemd-resolved.service` `ExecStart` drop-in;
- verifies the actual executable, UDP, TCP, D-Bus, Varlink, statistics,
  `_localdnsstub`, NSS, `resolv.conf`, and the optional external name;
- restores the prior resolver automatically if any immediate check fails;
- leaves a boot guard active until a successful reboot is confirmed.

The script prints a transaction identifier. Reboot once, then confirm only
after the boot guard and health checks pass:

```sh
sudo reboot
sudo /usr/lib/systemd/systemd-resolved-rs-switch \
  --confirm TRANSACTION_ID
```

## Roll back

Rollback remains available before or after confirmation:

```sh
sudo /usr/lib/systemd/systemd-resolved-rs-switch \
  --rollback TRANSACTION_ID
```

The rollback restores the exact previous service drop-in and service state,
then restarts the distribution resolver. Omitting the identifier selects the
active transaction:

```sh
sudo /usr/lib/systemd/systemd-resolved-rs-switch --rollback
```

## Prohibited shortcut

Do not remove, purge, mask permanently, or overwrite the distribution
`systemd-resolved` package. Do not manually replace files under `/usr/lib` or
change `/etc/resolv.conf` as part of the switch. A failed certificate or an
uncertified source tree is a hard stop, not a warning.