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 }