diff --git a/clanServices/sshd/README.md b/clanServices/sshd/README.md index 88df4ab25..5989c6e65 100644 --- a/clanServices/sshd/README.md +++ b/clanServices/sshd/README.md @@ -1,91 +1,39 @@ -# Clan service: sshd -What it does -- Generates and persists SSH host keys via `vars`. -- Optionally issues CA‑signed host certificates for servers. -- Installs the `server` CA public key into `clients` `known_hosts` for TOFU‑less verification. +The `sshd` Clan service manages SSH to make it easy to securely access your +machines over the internet. The service uses `vars` to store the SSH host keys +for each machine to ensure they remain stable across deployments. +`sshd` also generates SSH certificates for both servers and clients allowing for +certificate-based authentication for SSH. -When to use it -- Zero‑TOFU SSH for dynamic fleets: admins/CI can connect to frequently rebuilt hosts (e.g., server-1.example.com) without prompts or per‑host `known_hosts` churn. +The service also disables password-based authentication over SSH, to access your +machines you'll need to use public key authentication or certificate-based +authentication. -Roles -- Server: runs sshd, presents a CA‑signed host certificate for `.`. -- Client: trusts the CA for the given domains to verify servers’ certificates. - Tip: assign both roles to a machine if it should both present a cert and verify others. - -Quick start (with host certificates) -Useful if you never want to get a prompt about trusting the ssh fingerprint. -```nix -{ - inventory.instances = { - sshd-with-certs = { - module = { name = "sshd"; input = "clan-core"; }; - # Servers present certificates for .example.com - roles.server.tags.all = { }; - roles.server.settings = { - certificate.searchDomains = [ "example.com" ]; - # Optional: also add RSA host keys - # hostKeys.rsa.enable = true; - }; - # Clients trust the CA for *.example.com - roles.client.tags.all = { }; - roles.client.settings = { - certificate.searchDomains = [ "example.com" ]; - }; - }; - }; -} -``` - -Basic: only add persistent host keys (ed25519), no certificates -Useful if you want to get an ssh "trust this server" prompt once and then never again. +## Usage ```nix { inventory.instances = { + # By default this service only generates ed25519 host keys sshd-basic = { module = { name = "sshd"; input = "clan-core"; }; roles.server.tags.all = { }; + roles.client.tags.all = { }; }; - }; -} -``` - -Example: selective trust per environment -Admins should trust only production; CI should trust prod and staging. Servers are reachable under both domains. -```nix -{ - inventory.instances = { - sshd-env-scoped = { - module = { name = "sshd"; input = "clan-core"; }; - - # Servers present certs for both prod and staging FQDNs + # Also generate RSA host keys for all servers + sshd-with-rsa = { + module = { + name = "sshd"; + input = "clan-core"; + }; roles.server.tags.all = { }; roles.server.settings = { - certificate.searchDomains = [ "prod.example.com" "staging.example.com" ]; - }; - - # Admin laptop: trust prod only - roles.client.machines."admin-laptop".settings = { - certificate.searchDomains = [ "prod.example.com" ]; - }; - - # CI runner: trust prod and staging - roles.client.machines."ci-runner-1".settings = { - certificate.searchDomains = [ "prod.example.com" "staging.example.com" ]; + hostKeys.rsa.enable = true; }; + roles.client.tags.all = { }; }; }; } ``` -- Admin -> server1.prod.example.com: zero‑TOFU (verified via cert). -- Admin -> server1.staging.example.com: falls back to TOFU (or is blocked by policy). -- CI -> either prod or staging: zero‑TOFU for both. -Note: server and client searchDomains don’t have to be identical; they only need to overlap for the hostnames you actually use. - -Notes -- Connect using a name that matches a cert principal (e.g., `server1.example.com`); wildcards are not allowed inside the certificate. -- CA private key stays in `vars` (not deployed); only the CA public key is distributed. -- Logins still require your user SSH keys on the server (passwords are disabled). \ No newline at end of file