at 24.11-pre 5.3 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 7 inherit (pkgs) lsh; 8 9 cfg = config.services.lshd; 10 11in 12 13{ 14 15 ###### interface 16 17 options = { 18 19 services.lshd = { 20 21 enable = mkOption { 22 type = types.bool; 23 default = false; 24 description = '' 25 Whether to enable the GNU lshd SSH2 daemon, which allows 26 secure remote login. 27 ''; 28 }; 29 30 portNumber = mkOption { 31 default = 22; 32 type = types.port; 33 description = '' 34 The port on which to listen for connections. 35 ''; 36 }; 37 38 interfaces = mkOption { 39 default = []; 40 type = types.listOf types.str; 41 description = '' 42 List of network interfaces where listening for connections. 43 When providing the empty list, `[]`, lshd listens on all 44 network interfaces. 45 ''; 46 example = [ "localhost" "1.2.3.4:443" ]; 47 }; 48 49 hostKey = mkOption { 50 default = "/etc/lsh/host-key"; 51 type = types.str; 52 description = '' 53 Path to the server's private key. Note that this key must 54 have been created, e.g., using "lsh-keygen --server | 55 lsh-writekey --server", so that you can run lshd. 56 ''; 57 }; 58 59 syslog = mkOption { 60 type = types.bool; 61 default = true; 62 description = "Whether to enable syslog output."; 63 }; 64 65 passwordAuthentication = mkOption { 66 type = types.bool; 67 default = true; 68 description = "Whether to enable password authentication."; 69 }; 70 71 publicKeyAuthentication = mkOption { 72 type = types.bool; 73 default = true; 74 description = "Whether to enable public key authentication."; 75 }; 76 77 rootLogin = mkOption { 78 type = types.bool; 79 default = false; 80 description = "Whether to enable remote root login."; 81 }; 82 83 loginShell = mkOption { 84 default = null; 85 type = types.nullOr types.str; 86 description = '' 87 If non-null, override the default login shell with the 88 specified value. 89 ''; 90 example = "/nix/store/xyz-bash-10.0/bin/bash10"; 91 }; 92 93 srpKeyExchange = mkOption { 94 default = false; 95 type = types.bool; 96 description = '' 97 Whether to enable SRP key exchange and user authentication. 98 ''; 99 }; 100 101 tcpForwarding = mkOption { 102 type = types.bool; 103 default = true; 104 description = "Whether to enable TCP/IP forwarding."; 105 }; 106 107 x11Forwarding = mkOption { 108 type = types.bool; 109 default = true; 110 description = "Whether to enable X11 forwarding."; 111 }; 112 113 subsystems = mkOption { 114 type = types.listOf types.path; 115 description = '' 116 List of subsystem-path pairs, where the head of the pair 117 denotes the subsystem name, and the tail denotes the path to 118 an executable implementing it. 119 ''; 120 }; 121 122 }; 123 124 }; 125 126 127 ###### implementation 128 129 config = mkIf cfg.enable { 130 131 services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ]; 132 133 systemd.services.lshd = { 134 description = "GNU lshd SSH2 daemon"; 135 136 after = [ "network.target" ]; 137 138 wantedBy = [ "multi-user.target" ]; 139 140 environment = { 141 LD_LIBRARY_PATH = config.system.nssModules.path; 142 }; 143 144 preStart = '' 145 test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh 146 test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh 147 148 if ! test -f /var/spool/lsh/yarrow-seed-file 149 then 150 # XXX: It would be nice to provide feedback to the 151 # user when this fails, so that they can retry it 152 # manually. 153 ${lsh}/bin/lsh-make-seed --sloppy \ 154 -o /var/spool/lsh/yarrow-seed-file 155 fi 156 157 if ! test -f "${cfg.hostKey}" 158 then 159 ${lsh}/bin/lsh-keygen --server | \ 160 ${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}" 161 fi 162 ''; 163 164 script = with cfg; '' 165 ${lsh}/sbin/lshd --daemonic \ 166 --password-helper="${lsh}/sbin/lsh-pam-checkpw" \ 167 -p ${toString portNumber} \ 168 ${optionalString (interfaces != []) (concatStrings (map (i: "--interface=\"${i}\"") interfaces))} \ 169 -h "${hostKey}" \ 170 ${optionalString (!syslog) "--no-syslog" } \ 171 ${if passwordAuthentication then "--password" else "--no-password" } \ 172 ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \ 173 ${if rootLogin then "--root-login" else "--no-root-login" } \ 174 ${optionalString (loginShell != null) "--login-shell=\"${loginShell}\"" } \ 175 ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \ 176 ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \ 177 ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \ 178 --subsystems=${concatStringsSep "," 179 (map (pair: (head pair) + "=" + 180 (head (tail pair))) 181 subsystems)} 182 ''; 183 }; 184 185 security.pam.services.lshd = {}; 186 }; 187}