{ config, lib, ... }:
let
cfg = config.mjm.ssh;
in
{
options.mjm.ssh = {
<<options>>
};
config = lib.mkIf cfg.enable {
<<config>>
};
}This module has common SSH configuration for both NixOS and nix-darwin hosts.
It is extended with platform-specific configuration:
=> nixos/ssh
enable = lib.mkEnableOption "SSH configuration" // {
default = true;
};The SSH module has an enable option, but it is generally useful and mostly harmless where it's not needed, it is enabled by default.
hostCA = lib.mkOption {
type = lib.types.path;
default = builtins.fetchurl {
url = "https://vault.midna.dev/v1/ssh-host-signer/public_key";
sha256 = "1zy0wvd26iaypwf7zpvdxfhmabdg191q4986aw993j23q87z3g59";
};
readOnly = true;
};The hostCA option isn't meant to be set: it's just exposing a value that this module and possibly others can use. That value is the SSH certificate authority for my server hosts. This authority is fetched from Vault. By configuring this certificate authority on my SSH clients, I can securely log in to my machines without maintaining a known_hosts file and relying on TOFU.
trustedKeys = lib.mkOption {
type = lib.types.path;
default = builtins.fetchurl {
url = "https://vault.midna.dev/v1/ssh-client-signer/public_key";
sha256 = "12kcpl2mnfds458fv0c0jb0lz122q9jd7vqcfc7cw27giqis2dgl";
};
readOnly = true;
};The trustedKeys option is similar to the hostCA option, but in the other direction. My clients will get Vault to sign a public key to produce an SSH certificate, and then use that certificate to login. The trustedKeys value can be configured on the server to make it accept those logins, which avoids needing to maintain an authorized_keys file on the servers.
This option is not read directly in this module, but rather is exposed for other SSH-related modules to use.
programs.ssh.extraConfig = ''
CanonicalizeHostname yes
CanonicalDomains home.mattmoriarity.com
Host aion
Hostname 5.78.46.61
Host niobe
Hostname 152.53.116.186
'';This configuration just makes it easier to log in to my machines by only needing to pass their short hostname to the ssh command. For most machines, that's accomplished by the canonicalization options: all of my homelab servers are .home.mattmoriarity.com. The VPSes I run just get explicit rules to match the short hostname and have it connect by IP address instead.
programs.ssh.knownHosts = {
<<known-hosts>>
};I have a little bit of common known hosts configuration on all machines.
"*.home.mattmoriarity.com" = {
publicKeyFile = "${cfg.hostCA}";
certAuthority = true;
};Most hosts are trusted via an SSH certificate authority. The hosts will sign their host key with Vault and configure the SSH server to present that certificate. Clients don't need a list of individual public keys for hosts. This also means that on machines that don't persist their root filesystem, I don't need to worry about persisting SSH host keys, since they can be regenerated every boot without invalidating trust.
aion = {
hostNames = [
"aion"
"5.78.46.61"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDUWju/ZTNyivso/yzx6RFE/9D50qTiWVXDvITrkyEVh";
};
niobe = {
hostNames = [
"niobe"
"152.53.116.186"
];
publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILDn8zp1d/s5OoGgAqtH14KETvBEMH9pDEf6c2yjcdYs";
};The VPSes don't have direct access to Vault, so they are trusted the old-fashioned way.
text/gemini;lang=en-USThis content has been proxied by September (UNKNO).