add authorizedKeys option to ssh service

this has no apparent use as it stands, but opens the door to
having the keys managed by an external secrets service
This commit is contained in:
Daniel Barlow 2024-08-23 20:35:07 +01:00
parent e835473945
commit 869a508c0a
3 changed files with 35 additions and 4 deletions

View File

@ -184,7 +184,11 @@ in rec {
dependencies = [ config.services.hostname ]; dependencies = [ config.services.hostname ];
}; };
services.sshd = svc.ssh.build { }; services.sshd = svc.ssh.build {
authorizedKeys = {
root = rsecrets.root.openssh.authorizedKeys.keys;
};
};
services.lns-address = let services.lns-address = let
ns = "$(output_word ${services.bootstrap-dhcpc} dns 1)"; ns = "$(output_word ${services.bootstrap-dhcpc} dns 1)";

View File

@ -19,6 +19,7 @@ in {
type = liminix.lib.types.serviceDefn; type = liminix.lib.types.serviceDefn;
}; };
}; };
config.programs.busybox.options.FEATURE_FANCY_ECHO = "y";
config.system.service = { config.system.service = {
ssh = config.system.callService ./ssh.nix { ssh = config.system.callService ./ssh.nix {
address = mkOption { address = mkOption {
@ -41,6 +42,16 @@ in {
type = types.bool; default = false; type = types.bool; default = false;
description = "Allow remote hosts to connect to local forwarded ports (by default they are bound to loopback)"; description = "Allow remote hosts to connect to local forwarded ports (by default they are bound to loopback)";
}; };
authorizedKeys = mkOption {
type = types.nullOr (types.attrsOf (types.listOf types.nonEmptyStr));
example = {
root = ["ssh-rsa AAAAB3N...aZaZ"];
alice = ["ssh-rsa AAAAB3N...qS4r"];
bob = [];
};
default = null;
description = "Authorized SSH public keys for each username. If this optin is provided it overrides any keys found in /home/{username}/.ssh";
};
extraConfig = mkOption { extraConfig = mkOption {
type = types.separatedString " "; type = types.separatedString " ";
default = ""; default = "";

View File

@ -3,10 +3,11 @@
, dropbear , dropbear
, lib , lib
}: }:
p : {authorizedKeys, ...} @ p :
let let
name = "sshd";
inherit (liminix.services) longrun; inherit (liminix.services) longrun;
inherit (lib) concatStringsSep; inherit (lib) concatStringsSep mapAttrs mapAttrsToList;
options = options =
[ [
"-e" # pass environment to child "-e" # pass environment to child
@ -21,19 +22,34 @@ let
(lib.optional (! p.allowLocalPortForward) "-j") ++ (lib.optional (! p.allowLocalPortForward) "-j") ++
(lib.optional (! p.allowRemotePortForward) "-k") ++ (lib.optional (! p.allowRemotePortForward) "-k") ++
(lib.optional (! p.allowRemoteConnectionToForwardedPorts) "-a") ++ (lib.optional (! p.allowRemoteConnectionToForwardedPorts) "-a") ++
(lib.optionals (authorizedKeys != null)
["-U" "/run/${name}/authorized_keys/%n"]) ++
[(if p.address != null [(if p.address != null
then "-p ${p.address}:${p.port}" then "-p ${p.address}:${p.port}"
else "-p ${builtins.toString p.port}")] ++ else "-p ${builtins.toString p.port}")] ++
[p.extraConfig]; [p.extraConfig];
authKeysConcat =
if authorizedKeys != null
then mapAttrs
(n : v : concatStringsSep "\\n" v)
authorizedKeys
else {};
in in
longrun { longrun {
name = "sshd"; inherit name;
# we need /run/dropbear to point to hostkey storage, as that # we need /run/dropbear to point to hostkey storage, as that
# pathname is hardcoded into the binary. # pathname is hardcoded into the binary.
# env -i clears the environment so we don't pass anything weird to # env -i clears the environment so we don't pass anything weird to
# ssh sessions # ssh sessions
run = '' run = ''
ln -s $(mkstate dropbear) /run ln -s $(mkstate dropbear) /run
mkdir -p /run/${name}/authorized_keys
${concatStringsSep "\n"
(mapAttrsToList
(n : v : "echo -e '${v}' > /run/${name}/authorized_keys/${n} ")
authKeysConcat
)
}
. /etc/profile # sets PATH but do we need this? it's the same file as ashrc . /etc/profile # sets PATH but do we need this? it's the same file as ashrc
exec env -i ENV=/etc/ashrc PATH=$PATH ${dropbear}/bin/dropbear ${concatStringsSep " " options} exec env -i ENV=/etc/ashrc PATH=$PATH ${dropbear}/bin/dropbear ${concatStringsSep " " options}
''; '';