diff --git a/examples/router-with-l2tp.nix b/examples/router-with-l2tp.nix index 704efcb..e9c53c7 100644 --- 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 index 5d19975..0ed716b 100644 --- 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 index 1d81061..a2a97aa 100644 --- 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; }