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