Merge pull request 'Revert SSH docs' (#5488) from revert-ssh-docs into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/5488
This commit is contained in:
@@ -1,91 +1,39 @@
|
|||||||
# Clan service: sshd
|
The `sshd` Clan service manages SSH to make it easy to securely access your
|
||||||
What it does
|
machines over the internet. The service uses `vars` to store the SSH host keys
|
||||||
- Generates and persists SSH host keys via `vars`.
|
for each machine to ensure they remain stable across deployments.
|
||||||
- Optionally issues CA‑signed host certificates for servers.
|
|
||||||
- Installs the `server` CA public key into `clients` `known_hosts` for TOFU‑less verification.
|
|
||||||
|
|
||||||
|
`sshd` also generates SSH certificates for both servers and clients allowing for
|
||||||
|
certificate-based authentication for SSH.
|
||||||
|
|
||||||
When to use it
|
The service also disables password-based authentication over SSH, to access your
|
||||||
- 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.
|
machines you'll need to use public key authentication or certificate-based
|
||||||
|
authentication.
|
||||||
|
|
||||||
Roles
|
## Usage
|
||||||
- Server: runs sshd, presents a CA‑signed host certificate for `<machine>.<domain>`.
|
|
||||||
- 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 <machine>.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.
|
|
||||||
```nix
|
```nix
|
||||||
{
|
{
|
||||||
inventory.instances = {
|
inventory.instances = {
|
||||||
|
# By default this service only generates ed25519 host keys
|
||||||
sshd-basic = {
|
sshd-basic = {
|
||||||
module = {
|
module = {
|
||||||
name = "sshd";
|
name = "sshd";
|
||||||
input = "clan-core";
|
input = "clan-core";
|
||||||
};
|
};
|
||||||
roles.server.tags.all = { };
|
roles.server.tags.all = { };
|
||||||
|
roles.client.tags.all = { };
|
||||||
};
|
};
|
||||||
|
# Also generate RSA host keys for all servers
|
||||||
|
sshd-with-rsa = {
|
||||||
|
module = {
|
||||||
|
name = "sshd";
|
||||||
|
input = "clan-core";
|
||||||
};
|
};
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
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
|
|
||||||
roles.server.tags.all = { };
|
roles.server.tags.all = { };
|
||||||
roles.server.settings = {
|
roles.server.settings = {
|
||||||
certificate.searchDomains = [ "prod.example.com" "staging.example.com" ];
|
hostKeys.rsa.enable = true;
|
||||||
};
|
|
||||||
|
|
||||||
# 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" ];
|
|
||||||
};
|
};
|
||||||
|
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).
|
|
||||||
Reference in New Issue
Block a user