commit c7164a6f4a971a55ab3dd8aaf1c5c6904c681316
parent 83ca86fe4225dbc12d3cb8ce924ab08432f6bd82
Author: Daniel Barlow <dan@telent.net>
Date: Sun, 25 Aug 2024 16:35:50 +0100
sshd can use outputRef for authorized_keys
Diffstat:
3 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/examples/router-with-l2tp.nix b/examples/router-with-l2tp.nix
@@ -72,15 +72,6 @@ in rec {
dependencies = [ services.wan-address-for-secrets ];
};
- services.ssh-keys = longrun {
- name = "write-ssh-keys";
- run = ''
- mkdir -p /run/authorized_keys
- exec ${pkgs.watch-ssh-keys}/bin/watch-ssh-keys -d /run/authorized_keys ${services.secrets} ssh/authorizedKeys
- '';
- dependencies = [ services.secrets ] ;
- };
-
services.wwan = svc.wwan.huawei-e3372.build {
apn = "data.uk";
username = "user";
@@ -188,9 +179,7 @@ in rec {
};
services.sshd = svc.ssh.build {
- authorizedKeys = {
- root = rsecrets.root.openssh.authorizedKeys.keys;
- };
+ authorizedKeys = outputRef config.services.secrets "ssh/authorizedKeys";
};
services.lns-address = let
diff --git a/modules/ssh/default.nix b/modules/ssh/default.nix
@@ -43,7 +43,7 @@ in {
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));
+ type = types.nullOr (liminix.lib.types.replacable (types.attrsOf (types.listOf types.nonEmptyStr)));
example = {
root = ["ssh-rsa AAAAB3N...aZaZ"];
alice = ["ssh-rsa AAAAB3N...qS4r"];
diff --git a/modules/ssh/ssh.nix b/modules/ssh/ssh.nix
@@ -2,6 +2,7 @@
liminix
, dropbear
, lib
+, watch-ssh-keys
}:
{
address,
@@ -17,9 +18,10 @@
}:
let
name = "sshd";
- inherit (builtins) toString;
+ inherit (builtins) toString typeOf;
inherit (liminix.services) longrun;
inherit (lib) concatStringsSep mapAttrs mapAttrsToList;
+ keydir = "/run/${name}/authorized_keys";
options =
[
"-e" # pass environment to child
@@ -34,18 +36,26 @@ let
(lib.optional (! allowLocalPortForward) "-j") ++
(lib.optional (! allowRemotePortForward) "-k") ++
(lib.optional (! allowRemoteConnectionToForwardedPorts) "-a") ++
- (lib.optionals (authorizedKeys != null)
- ["-U" "/run/${name}/authorized_keys/%n"]) ++
+ (lib.optionals (authorizedKeys != null) ["-U" "${keydir}/%n"]) ++
[(if address != null
then "-p ${address}:${toString port}"
else "-p ${toString port}")] ++
[extraConfig];
+ isKeyservice = typeOf authorizedKeys == "lambda";
authKeysConcat =
- if authorizedKeys != null
+ if authorizedKeys != null && !isKeyservice
then mapAttrs
(n : v : concatStringsSep "\\n" v)
authorizedKeys
else {};
+ keyservice = longrun {
+ name = "${name}-watch-keys";
+ run = ''
+ mkdir -p ${keydir}
+ exec ${watch-ssh-keys}/bin/watch-ssh-keys -d ${keydir} ${authorizedKeys "service"} ${authorizedKeys "path"}
+ '';
+ dependencies = [ (authorizedKeys "service") ] ;
+ };
in
longrun {
inherit name;
@@ -65,4 +75,5 @@ longrun {
. /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}
'';
+ dependencies = lib.optional isKeyservice keyservice;
}