A remote-administration module for a hypervisor nobody sits at #68

Closed
opened 2026-09-29 20:15:50 +01:00 by vnprc-agent · 2 comments

Give a hypervisor that nobody sits at a way to be administered over SSH, as a module that machine imports, so that a hypervisor which does not import it has no listener by construction.

Primary goals:

  • A posture module, not a switch — nixosModules.remoteAdmin has no enable option; a machine either imports it or runs no sshd, the shape allod/archetypes modules/public-host.nix already uses for internet-facing machines.
  • Never open globally — the port opens only on the interfaces the machine names, and an empty interface list is refused at evaluation.
  • Keys only — no password authentication, no root login.
  • The default host is unchanged — a hypervisor that does not import the module evaluates exactly as it does today.

Current state and specifics

The host module runs no sshd and opens no port: nix/configuration.nix sets networking.firewall.allowedTCPPorts = [ ] and no services.openssh option. That is the right posture for a machine someone sits at, and it is the only posture available. A headless hypervisor has no way in.

The module belongs in this repository, not in allod/archetypes, because of where a hypervisor can import it from. The hypervisor builder composes the machine's profile definition, so the import is made by profiles; profiles cannot take archetypes as an input without a cycle, and it can take nexus. This repository also already owns the firewall being opened.

Shape:

  • options interfaces (non-empty list of interface names) and port;
  • services.openssh.enable = true, openFirewall = false, PasswordAuthentication = false, KbdInteractiveAuthentication = false, PermitRootLogin = "no";
  • networking.firewall.interfaces.<name>.allowedTCPPorts carries the port, so the global list stays empty.

Which keys the hypervisor accepts is not this module's business: the hypervisor builder sets the account's authorized keys from the identity record, tracked in allod/archetypes#89.

Validation

A check that composes the module onto the template host and reads the evaluated options: sshd on, passwords and root login off, the global port list still empty, the port present on each named interface. A second fixture with an empty interface list must fail evaluation.

Scope

In scope: the module, its export, its check, and a README section.

Tracked in allod/archetypes#89: more than one hypervisor in a deployment, and which keys a hypervisor authorizes.

Not in scope: unlocking an encrypted disk at boot on a machine with no console. That is hardware, or a separate issue if it is ever wanted in software.

Give a hypervisor that nobody sits at a way to be administered over SSH, as a module that machine imports, so that a hypervisor which does not import it has no listener by construction. Primary goals: - **A posture module, not a switch** — `nixosModules.remoteAdmin` has no `enable` option; a machine either imports it or runs no sshd, the shape `allod/archetypes` `modules/public-host.nix` already uses for internet-facing machines. - **Never open globally** — the port opens only on the interfaces the machine names, and an empty interface list is refused at evaluation. - **Keys only** — no password authentication, no root login. - **The default host is unchanged** — a hypervisor that does not import the module evaluates exactly as it does today. ### Current state and specifics The host module runs no sshd and opens no port: `nix/configuration.nix` sets `networking.firewall.allowedTCPPorts = [ ]` and no `services.openssh` option. That is the right posture for a machine someone sits at, and it is the only posture available. A headless hypervisor has no way in. The module belongs in this repository, not in `allod/archetypes`, because of where a hypervisor can import it from. The hypervisor builder composes the machine's profile definition, so the import is made by `profiles`; `profiles` cannot take `archetypes` as an input without a cycle, and it can take `nexus`. This repository also already owns the firewall being opened. Shape: - options `interfaces` (non-empty list of interface names) and `port`; - `services.openssh.enable = true`, `openFirewall = false`, `PasswordAuthentication = false`, `KbdInteractiveAuthentication = false`, `PermitRootLogin = "no"`; - `networking.firewall.interfaces.<name>.allowedTCPPorts` carries the port, so the global list stays empty. Which keys the hypervisor accepts is not this module's business: the hypervisor builder sets the account's authorized keys from the identity record, tracked in allod/archetypes#89. ### Validation A check that composes the module onto the template host and reads the evaluated options: sshd on, passwords and root login off, the global port list still empty, the port present on each named interface. A second fixture with an empty interface list must fail evaluation. ### Scope In scope: the module, its export, its check, and a README section. Tracked in allod/archetypes#89: more than one hypervisor in a deployment, and which keys a hypervisor authorizes. Not in scope: unlocking an encrypted disk at boot on a machine with no console. That is hardware, or a separate issue if it is ever wanted in software.
Author

Prepared on branch agent/remote-admin, awaiting relay. The module is nixosModules.remoteAdmin with options interfaces and port, and a remote-admin check.

Review found two defects, both fixed on the branch: sshd's port was not set from port, so a non-default port opened a port with no listener; and the empty-interface fixture passed on an unrelated assertion of the template host, so it is now selected by its own message.

Prepared on branch `agent/remote-admin`, awaiting relay. The module is `nixosModules.remoteAdmin` with options `interfaces` and `port`, and a `remote-admin` check. Review found two defects, both fixed on the branch: sshd's port was not set from `port`, so a non-default port opened a port with no listener; and the empty-interface fixture passed on an unrelated assertion of the template host, so it is now selected by its own message.
Author

nixosModules.remoteAdmin is on master with its check, and allod/nexus#70's hardening of it is merged.

nixosModules.remoteAdmin is on master with its check, and allod/nexus#70's hardening of it is merged.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
allod/nexus#68
No description provided.