feat: automate SSH config ('known_hosts', 'authorized_keys' ...)

This commit is contained in:
2026-01-17 17:37:37 +01:00
parent 33b022c659
commit 8464884fdb
15 changed files with 143 additions and 9 deletions

View File

@@ -0,0 +1,24 @@
{ lib, config, ... }:
{
options.ssh = {
authorizedHosts = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
};
username = lib.mkOption {
type = lib.types.str;
default = "h";
};
};
# auto generate authorized_keys from `authorizedHosts`
config.users.users.${config.ssh.username}.openssh.authorizedKeys.keys = lib.flatten (
map (
hostname:
let
keyFile = ../../hosts/${hostname}/ssh_user.pub;
in
lib.optionals (builtins.pathExists keyFile) (lib.splitString "\n" (builtins.readFile keyFile))
) config.ssh.authorizedHosts
);
}

View File

@@ -0,0 +1,24 @@
{ lib, config, ... }:
let
username = config.ssh.username;
in
{
# auto extract SSH keys
system.activationScripts.extractSshKeys = lib.stringAfter [ "etc" ] ''
HOST_KEY="/etc/ssh/ssh_host_ed25519_key.pub"
HOST_DIR="/home/${username}/nix/hosts/${config.networking.hostName}"
if [ -f "$HOST_KEY" ] && [ -d "$HOST_DIR" ]; then
cp "$HOST_KEY" "$HOST_DIR/ssh_host.pub"
chown ${username}:users "$HOST_DIR/ssh_host.pub"
chmod 644 "$HOST_DIR/ssh_host.pub"
fi
USER_KEY="/home/${username}/.ssh/id_ed25519.pub"
if [ -f "$USER_KEY" ] && [ -d "$HOST_DIR" ]; then
cp "$USER_KEY" "$HOST_DIR/ssh_user.pub"
chown ${username}:users "$HOST_DIR/ssh_user.pub"
chmod 644 "$HOST_DIR/ssh_user.pub"
fi
'';
}

View File

@@ -4,9 +4,17 @@ let
cfg = config.services.openssh;
in
{
imports = [
./known-hosts.nix
./authorized-keys.nix
./extract-keys.nix
];
options.services.openssh.harden = mkEnableOption "harden ssh server configuration";
config = {
networking.firewall.allowedTCPPorts = [ 22 ];
services.openssh.settings = optionalAttrs cfg.harden {
PermitRootLogin = "no";
PasswordAuthentication = false;

View File

@@ -0,0 +1,19 @@
{
lib,
config,
outputs,
...
}:
let
hosts = lib.attrNames outputs.nixosConfigurations;
hostsWithKeys = lib.filter (
hostname: builtins.pathExists ../../hosts/${hostname}/ssh_host.pub
) hosts;
in
{
# auto generate known_hosts for all hosts in flake
programs.ssh.knownHosts = lib.genAttrs hostsWithKeys (hostname: {
publicKeyFile = ../../hosts/${hostname}/ssh_host.pub;
extraHostNames = lib.optional (hostname == config.networking.hostName) "localhost";
});
}