liminix

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

ssh.nix (2366B)


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