summary refs log tree commit diff
path: root/nixos/modules/services/networking/ssh/lshd.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixos/modules/services/networking/ssh/lshd.nix')
-rw-r--r--nixos/modules/services/networking/ssh/lshd.nix189
1 files changed, 189 insertions, 0 deletions
diff --git a/nixos/modules/services/networking/ssh/lshd.nix b/nixos/modules/services/networking/ssh/lshd.nix
new file mode 100644
index 00000000000..862ff7df054
--- /dev/null
+++ b/nixos/modules/services/networking/ssh/lshd.nix
@@ -0,0 +1,189 @@
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+  inherit (pkgs) lsh;
+
+  cfg = config.services.lshd;
+
+in
+
+{
+
+  ###### interface
+
+  options = {
+
+    services.lshd = {
+
+      enable = mkOption {
+        type = types.bool;
+        default = false;
+        description = ''
+          Whether to enable the GNU lshd SSH2 daemon, which allows
+          secure remote login.
+        '';
+      };
+
+      portNumber = mkOption {
+        default = 22;
+        type = types.port;
+        description = ''
+          The port on which to listen for connections.
+        '';
+      };
+
+      interfaces = mkOption {
+        default = [];
+        type = types.listOf types.str;
+        description = ''
+          List of network interfaces where listening for connections.
+          When providing the empty list, `[]', lshd listens on all
+          network interfaces.
+        '';
+        example = [ "localhost" "1.2.3.4:443" ];
+      };
+
+      hostKey = mkOption {
+        default = "/etc/lsh/host-key";
+        type = types.str;
+        description = ''
+          Path to the server's private key.  Note that this key must
+          have been created, e.g., using "lsh-keygen --server |
+          lsh-writekey --server", so that you can run lshd.
+        '';
+      };
+
+      syslog = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to enable syslog output.";
+      };
+
+      passwordAuthentication = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to enable password authentication.";
+      };
+
+      publicKeyAuthentication = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to enable public key authentication.";
+      };
+
+      rootLogin = mkOption {
+        type = types.bool;
+        default = false;
+        description = "Whether to enable remote root login.";
+      };
+
+      loginShell = mkOption {
+        default = null;
+        type = types.nullOr types.str;
+        description = ''
+          If non-null, override the default login shell with the
+          specified value.
+        '';
+        example = "/nix/store/xyz-bash-10.0/bin/bash10";
+      };
+
+      srpKeyExchange = mkOption {
+        default = false;
+        type = types.bool;
+        description = ''
+          Whether to enable SRP key exchange and user authentication.
+        '';
+      };
+
+      tcpForwarding = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to enable TCP/IP forwarding.";
+      };
+
+      x11Forwarding = mkOption {
+        type = types.bool;
+        default = true;
+        description = "Whether to enable X11 forwarding.";
+      };
+
+      subsystems = mkOption {
+        type = types.listOf types.path;
+        description = ''
+          List of subsystem-path pairs, where the head of the pair
+          denotes the subsystem name, and the tail denotes the path to
+          an executable implementing it.
+        '';
+      };
+
+    };
+
+  };
+
+
+  ###### implementation
+
+  config = mkIf cfg.enable {
+
+    services.lshd.subsystems = [ ["sftp" "${pkgs.lsh}/sbin/sftp-server"] ];
+
+    systemd.services.lshd = {
+      description = "GNU lshd SSH2 daemon";
+
+      after = [ "network.target" ];
+
+      wantedBy = [ "multi-user.target" ];
+
+      environment = {
+        LD_LIBRARY_PATH = config.system.nssModules.path;
+      };
+
+      preStart = ''
+        test -d /etc/lsh || mkdir -m 0755 -p /etc/lsh
+        test -d /var/spool/lsh || mkdir -m 0755 -p /var/spool/lsh
+
+        if ! test -f /var/spool/lsh/yarrow-seed-file
+        then
+            # XXX: It would be nice to provide feedback to the
+            # user when this fails, so that they can retry it
+            # manually.
+            ${lsh}/bin/lsh-make-seed --sloppy \
+               -o /var/spool/lsh/yarrow-seed-file
+        fi
+
+        if ! test -f "${cfg.hostKey}"
+        then
+            ${lsh}/bin/lsh-keygen --server | \
+            ${lsh}/bin/lsh-writekey --server -o "${cfg.hostKey}"
+        fi
+      '';
+
+      script = with cfg; ''
+        ${lsh}/sbin/lshd --daemonic \
+          --password-helper="${lsh}/sbin/lsh-pam-checkpw" \
+          -p ${toString portNumber} \
+          ${if interfaces == [] then ""
+            else (concatStrings (map (i: "--interface=\"${i}\"")
+                                     interfaces))} \
+          -h "${hostKey}" \
+          ${if !syslog then "--no-syslog" else ""} \
+          ${if passwordAuthentication then "--password" else "--no-password" } \
+          ${if publicKeyAuthentication then "--publickey" else "--no-publickey" } \
+          ${if rootLogin then "--root-login" else "--no-root-login" } \
+          ${if loginShell != null then "--login-shell=\"${loginShell}\"" else "" } \
+          ${if srpKeyExchange then "--srp-keyexchange" else "--no-srp-keyexchange" } \
+          ${if !tcpForwarding then "--no-tcpip-forward" else "--tcpip-forward"} \
+          ${if x11Forwarding then "--x11-forward" else "--no-x11-forward" } \
+          --subsystems=${concatStringsSep ","
+                                          (map (pair: (head pair) + "=" +
+                                                      (head (tail pair)))
+                                               subsystems)}
+      '';
+    };
+
+    security.pam.services.lshd = {};
+  };
+}