diff --git a/hosts/common/ssh.nix b/hosts/common/ssh.nix index 5f411b3f..83d495b1 100644 --- a/hosts/common/ssh.nix +++ b/hosts/common/ssh.nix @@ -1,19 +1,27 @@ -{ config, lib, ... }: +{ config, lib, sane-data, sane-lib, ... }: + { - sane.ssh = rec { - pubkeys."colin@lappy" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu"; - pubkeys."root@lappy" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc"; + sane.ssh.pubkeys = + let + # path is a DNS-style path like [ "org" "uninsane" "root" ] + keyNameForPath = path: + let + rev = lib.reverseList path; + name = builtins.head rev; + host = lib.concatStringsSep "." (builtins.tail rev); + in + "${name}@${host}"; - pubkeys."colin@desko" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX"; - pubkeys."root@desko" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk"; - - pubkeys."colin@moby" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU"; - pubkeys."root@moby" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw"; - - pubkeys."colin@servo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX"; - pubkeys."root@servo" = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8"; - pubkeys."root@uninsane.org" = pubkeys."root@servo"; - # XXX: git.uninsane.org uses the same host key as servo, so we use this to populate known_hosts - pubkeys."root@git.uninsane.org" = pubkeys."root@servo"; - }; + # given a DNS-style recursive AttrSet, return a flat AttrSet that maps ssh id => pubkey. + keysFor = attrs: + let + by-path = sane-lib.flattenAttrs attrs; + in + sane-lib.mapToAttrs ({ path, value }: { + name = keyNameForPath path; + inherit value; + }) by-path; + globalKeys = keysFor sane-data.keys; + localKeys = keysFor sane-data.keys.org.uninsane.local; + in lib.mkMerge [ globalKeys localKeys ]; } diff --git a/modules/data/default.nix b/modules/data/default.nix new file mode 100644 index 00000000..583e9092 --- /dev/null +++ b/modules/data/default.nix @@ -0,0 +1,9 @@ +# this directory contains data of a factual nature. +# for example, public ssh keys, GPG keys, DNS-type name mappings. +# +# don't put things like fully-specific ~/.config files in here, +# even if they're "relatively unopinionated". + +{ + keys = import ./keys.nix; +} diff --git a/modules/data/keys.nix b/modules/data/keys.nix new file mode 100644 index 00000000..be0db164 --- /dev/null +++ b/modules/data/keys.nix @@ -0,0 +1,24 @@ +# hierarchical, DNS-like mapping from => ssh host/user for that name. +# host keys are represented as user keys, just with the user specified as "root". + +{ + org.uninsane = rec { + root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOfdSmFkrVT6DhpgvFeQKm3Fh9VKZ9DbLYOPOJWYQ0E8"; + git.root = root; + + local = { + # machine aliases i specify on my lan; not actually asserted as DNS + desko.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPU5GlsSfbaarMvDA20bxpSZGWviEzXGD8gtrIowc1pX"; + desko.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFw9NoRaYrM6LbDd3aFBc4yyBlxGQn8HjeHd/dZ3CfHk"; + + lappy.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDpmFdNSVPRol5hkbbCivRhyeENzb9HVyf9KutGLP2Zu"; + lappy.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILSJnqmVl9/SYQ0btvGb0REwwWY8wkdkGXQZfn/1geEc"; + + moby.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICrR+gePnl0nV/vy7I5BzrGeyVL+9eOuXHU1yNE3uCwU"; + moby.root = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO1N/IT3nQYUD+dBlU1sTEEVMxfOyMkrrDeyHcYgnJvw"; + + servo.colin = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPS1qFzKurAdB9blkWomq8gI1g0T3sTs9LsmFOj5VtqX"; + servo.root = root; + }; + }; +} diff --git a/modules/default.nix b/modules/default.nix index 5eedd758..a2e6a1a9 100644 --- a/modules/default.nix +++ b/modules/default.nix @@ -18,5 +18,6 @@ _module.args = { sane-lib = import ./lib { inherit lib utils; }; + sane-data = import ./data; }; } diff --git a/modules/lib/default.nix b/modules/lib/default.nix index 565f7344..d2998fa4 100644 --- a/modules/lib/default.nix +++ b/modules/lib/default.nix @@ -1,6 +1,6 @@ { lib, ... }@moduleArgs: -{ +rec { feeds = import ./feeds.nix moduleArgs; fs = import ./fs.nix moduleArgs; path = import ./path.nix moduleArgs; @@ -12,8 +12,26 @@ else default; + # removes null entries from the provided AttrSet. acts recursively. + # Type: filterNonNull :: AttrSet -> AttrSet filterNonNull = attrs: lib.filterAttrsRecursive (n: v: v != null) attrs; - # transform a list into an attrset via a function which maps an element to a name + value + + # transform a list into an AttrSet via a function which maps an element to a name + value # Type: mapToAttrs :: (a -> { name, value }) -> [a] -> AttrSet mapToAttrs = f: list: builtins.listToAttrs (builtins.map f list); + + # flatten a nested AttrSet into a list of { path = [str]; value } items. + # Type: flattenAttrs :: AttrSet[item|AttrSet] -> [{ path; value; }] + flattenAttrs = flattenAttrs' []; + flattenAttrs' = path: value: if builtins.isAttrs value then ( + builtins.concatLists ( + lib.mapAttrsToList + (name: flattenAttrs' (path ++ [ name ])) + value + ) + ) else [ + { + inherit path value; + } + ]; }