liminix

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

ssh.nix (2315B)


      1 {
      2   liminix,
      3   dropbear,
      4   lib,
      5   watch-ssh-keys,
      6 }:
      7 {
      8   address,
      9   allowLocalPortForward,
     10   allowPasswordLogin,
     11   allowPasswordLoginForRoot,
     12   allowRemoteConnectionToForwardedPorts,
     13   allowRemotePortForward,
     14   allowRoot,
     15   authorizedKeys,
     16   port,
     17   extraConfig,
     18 }:
     19 let
     20   name = "sshd";
     21   inherit (builtins) toString typeOf;
     22   inherit (liminix.services) longrun;
     23   inherit (lib) concatStringsSep mapAttrs mapAttrsToList;
     24   keydir = "/run/${name}/authorized_keys";
     25   options = [
     26     "-e" # pass environment to child
     27     "-E" # log to stderr
     28     "-R" # create hostkeys if needed
     29     "-P /run/dropbear.pid"
     30     "-F" # don't fork into background
     31   ]
     32   ++ (lib.optional (!allowRoot) "-w")
     33   ++ (lib.optional (!allowPasswordLogin) "-s")
     34   ++ (lib.optional (!allowPasswordLoginForRoot) "-g")
     35   ++ (lib.optional (!allowLocalPortForward) "-j")
     36   ++ (lib.optional (!allowRemotePortForward) "-k")
     37   ++ (lib.optional (!allowRemoteConnectionToForwardedPorts) "-a")
     38   ++ (lib.optionals (authorizedKeys != null) [
     39     "-U"
     40     "${keydir}/%n"
     41   ])
     42   ++ [
     43     (if address != null then "-p ${address}:${toString port}" else "-p ${toString port}")
     44   ]
     45   ++ [ extraConfig ];
     46   isKeyservice = authorizedKeys ? __functor;
     47   authKeysConcat =
     48     if authorizedKeys != null && !isKeyservice then
     49       mapAttrs (n: v: concatStringsSep "\\n" v) authorizedKeys
     50     else
     51       { };
     52   keyservice = longrun {
     53     name = "${name}-watch-keys";
     54     run = ''
     55       mkdir -p ${keydir}
     56       exec ${watch-ssh-keys}/bin/watch-ssh-keys -d ${keydir} ${authorizedKeys "service"} ${authorizedKeys "path"}
     57     '';
     58     dependencies = [ (authorizedKeys "service") ];
     59   };
     60 in
     61 longrun {
     62   inherit name;
     63   # we need /run/dropbear to point to hostkey storage, as that
     64   # pathname is hardcoded into the binary.
     65   # env -i clears the environment so we don't pass anything weird to
     66   # ssh sessions
     67   run = ''
     68     ln -s $(mkstate dropbear) /run
     69     mkdir -p /run/${name}/authorized_keys
     70     ${concatStringsSep "\n" (
     71       mapAttrsToList (n: v: "echo -e '${v}' > /run/${name}/authorized_keys/${n} ") authKeysConcat
     72     )}
     73     . /etc/profile # sets PATH but do we need this?  it's the same file as ashrc
     74     exec env -i ENV=/etc/ashrc PATH=$PATH ${dropbear}/bin/dropbear ${concatStringsSep " " options}
     75   '';
     76   dependencies = lib.optional isKeyservice keyservice;
     77 }