ssh: port to modules system
This commit is contained in:
@@ -1,10 +1,22 @@
|
||||
{ config, lib, ... }:
|
||||
{
|
||||
# persist the host key
|
||||
environment.etc."ssh/host_keys".source = "/nix/persist/etc/ssh/host_keys";
|
||||
|
||||
# let openssh find our host keys
|
||||
services.openssh.hostKeys = [
|
||||
{ type = "rsa"; bits = 4096; path = "/etc/ssh/host_keys/ssh_host_rsa_key"; }
|
||||
{ type = "ed25519"; path = "/etc/ssh/host_keys/ssh_host_ed25519_key"; }
|
||||
];
|
||||
|
||||
sane.ssh.pubkeys = {
|
||||
"colin@lappy" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
|
||||
"root@lappy" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
|
||||
"root@desko" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
|
||||
"colin@desko" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
|
||||
"root@servo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
|
||||
"colin@servo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX";
|
||||
"root@moby" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
|
||||
"colin@moby" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
|
||||
};
|
||||
}
|
||||
|
@@ -52,7 +52,11 @@ in
|
||||
passwordFile = lib.mkIf (config.sops.secrets ? "colin-passwd") config.sops.secrets.colin-passwd.path;
|
||||
|
||||
shell = pkgs.zsh;
|
||||
openssh.authorizedKeys.keys = builtins.attrValues (import ../../modules/pubkeys.nix).users;
|
||||
openssh.authorizedKeys.keys =
|
||||
let
|
||||
user-keys = filter (k: k.user == "colin") (attrValues config.sane.ssh.pubkeys);
|
||||
in
|
||||
map (k: k.asUserKey) user-keys;
|
||||
|
||||
# mount encrypted stuff at login
|
||||
# some other nix pam users:
|
||||
|
@@ -12,6 +12,7 @@
|
||||
./persist
|
||||
./services
|
||||
./sops.nix
|
||||
./ssh.nix
|
||||
];
|
||||
|
||||
_module.args = {
|
||||
|
@@ -1,19 +1,22 @@
|
||||
{ config, lib, pkgs, sane-lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
host = config.networking.hostName;
|
||||
user_pubkey = (import ../pubkeys.nix).users."${host}";
|
||||
known_hosts_text = builtins.concatStringsSep
|
||||
user-pubkey = config.sane.ssh.pubkeys."colin@${host}".asUserKey;
|
||||
host-keys = filter (k: k.user == "root") (attrValues config.sane.ssh.pubkeys);
|
||||
known-hosts-text = concatStringsSep
|
||||
"\n"
|
||||
(builtins.attrValues (import ../pubkeys.nix).hosts);
|
||||
(map (k: k.asHostKey) host-keys)
|
||||
;
|
||||
in lib.mkIf config.sane.home-manager.enable {
|
||||
# ssh key is stored in private storage
|
||||
sane.persist.home.private = [ ".ssh/id_ed25519" ];
|
||||
sane.fs."/home/colin/.ssh/id_ed25519.pub" = sane-lib.fs.wantedText user_pubkey;
|
||||
sane.fs."/home/colin/.ssh/id_ed25519.pub" = sane-lib.fs.wantedText user-pubkey;
|
||||
|
||||
home-manager.users.colin = {
|
||||
programs.ssh.enable = true;
|
||||
# this optionally accepts multiple known_hosts paths, separated by space.
|
||||
programs.ssh.userKnownHostsFile = builtins.toString (pkgs.writeText "known_hosts" known_hosts_text);
|
||||
programs.ssh.userKnownHostsFile = toString (pkgs.writeText "known_hosts" known-hosts-text);
|
||||
};
|
||||
}
|
||||
|
@@ -1,34 +0,0 @@
|
||||
# create ssh key by running:
|
||||
# - `ssh-keygen -t ed25519`
|
||||
let
|
||||
withHost = host: key: "${host} ${key}";
|
||||
withUser = user: key: "${key} ${user}";
|
||||
|
||||
keys = rec {
|
||||
lappy = {
|
||||
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc";
|
||||
users.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu";
|
||||
};
|
||||
desko = {
|
||||
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk";
|
||||
users.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX";
|
||||
};
|
||||
servo = {
|
||||
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8";
|
||||
users.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX";
|
||||
};
|
||||
moby = {
|
||||
host = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw";
|
||||
users.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU";
|
||||
};
|
||||
|
||||
"uninsane.org" = servo;
|
||||
"git.uninsane.org" = servo;
|
||||
};
|
||||
in {
|
||||
# map hostname -> something suitable for known_keys
|
||||
hosts = builtins.mapAttrs (host: keys: withHost host keys.host) keys;
|
||||
# map hostname -> something suitable for authorized_keys to allow access to colin@<hostname>
|
||||
users = builtins.mapAttrs (host: keys: withUser "colin@${host}" keys.users.colin) keys;
|
||||
}
|
||||
|
66
modules/ssh.nix
Normal file
66
modules/ssh.nix
Normal file
@@ -0,0 +1,66 @@
|
||||
{ lib, ... }:
|
||||
|
||||
with lib;
|
||||
let
|
||||
key = types.submodule ({ name, config, ...}: {
|
||||
options = {
|
||||
typedPubkey = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
the pubkey with type attached.
|
||||
e.g. "ssh-ed25519 <base64>"
|
||||
'';
|
||||
};
|
||||
# type = mkOption {
|
||||
# type = types.str;
|
||||
# description = ''
|
||||
# the type of the key, e.g. "id_ed25519"
|
||||
# '';
|
||||
# };
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
the hostname of a key
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
the username of a key
|
||||
'';
|
||||
};
|
||||
asUserKey = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
append the "user@host" value to the pubkey to make it usable for ~/.ssh/id_<x>.pub or authorized_keys
|
||||
'';
|
||||
};
|
||||
asHostKey = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
prepend the "host" value to the pubkey to make it usable for ~/.ssh/known_hosts
|
||||
'';
|
||||
};
|
||||
};
|
||||
config = rec {
|
||||
user = head (lib.splitString "@" name);
|
||||
host = last (lib.splitString "@" name);
|
||||
asUserKey = "${config.typedPubkey} ${name}";
|
||||
asHostKey = "${host} ${config.typedPubkey}";
|
||||
};
|
||||
});
|
||||
coercedToKey = types.coercedTo types.str (typedPubkey: {
|
||||
inherit typedPubkey;
|
||||
}) key;
|
||||
in
|
||||
{
|
||||
options = {
|
||||
sane.ssh.pubkeys = mkOption {
|
||||
type = types.attrsOf coercedToKey;
|
||||
default = [];
|
||||
description = ''
|
||||
mapping from "user@host" to pubkey.
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user