summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--doc/guix.texi6
-rw-r--r--gnu/services/ssh.scm23
-rw-r--r--gnu/tests/ssh.scm32
3 files changed, 43 insertions, 18 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 54793c9648..59db00e581 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -18962,6 +18962,12 @@ Name of the file where @command{sshd} writes its PID.
 @item @code{port-number} (default: @code{22})
 TCP port on which @command{sshd} listens for incoming connections.
 
+@item @code{max-connections} (default: @code{200})
+Hard limit on the maximum number of simultaneous client connections,
+enforced by the inetd-style Shepherd service (@pxref{Service De- and
+Constructors, @code{make-inetd-constructor},, shepherd, The GNU Shepherd
+Manual}).
+
 @item @code{permit-root-login} (default: @code{#f})
 This field determines whether and when to allow logins as root.  If
 @code{#f}, root logins are disallowed; if @code{#t}, they are allowed.
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index 5c8fe4eef4..7fbbe383e5 100644
--- a/gnu/services/ssh.scm
+++ b/gnu/services/ssh.scm
@@ -292,6 +292,9 @@ The other options should be self-descriptive."
   ;; integer
   (port-number           openssh-configuration-port-number
                          (default 22))
+  ;; integer
+  (max-connections       openssh-configuration-max-connections
+                         (default 200))
   ;; Boolean | 'prohibit-password
   (permit-root-login     openssh-configuration-permit-root-login
                          (default #f))
@@ -515,6 +518,12 @@ of user-name/file-like tuples."
   (define pid-file
     (openssh-configuration-pid-file config))
 
+  (define port-number
+    (openssh-configuration-port-number config))
+
+  (define max-connections
+    (openssh-configuration-max-connections config))
+
   (define openssh-command
     #~(list (string-append #$(openssh-configuration-openssh config) "/sbin/sshd")
             "-D" "-f" #$(openssh-config-file config)))
@@ -523,9 +532,17 @@ of user-name/file-like tuples."
          (documentation "OpenSSH server.")
          (requirement '(syslogd loopback))
          (provision '(ssh-daemon ssh sshd))
-         (start #~(make-forkexec-constructor #$openssh-command
-                                             #:pid-file #$pid-file))
-         (stop #~(make-kill-destructor))
+         (start #~(if (defined? 'make-inetd-constructor)
+                      (make-inetd-constructor
+                       (append #$openssh-command '("-i"))
+                       (make-socket-address AF_INET INADDR_ANY
+                                            #$port-number)
+                       #:max-connections #$max-connections)
+                      (make-forkexec-constructor #$openssh-command
+                                                 #:pid-file #$pid-file)))
+         (stop #~(if (defined? 'make-inetd-destructor)
+                     (make-inetd-destructor)
+                     (make-kill-destructor)))
          (auto-start? (openssh-auto-start? config)))))
 
 (define (openssh-pam-services config)
diff --git a/gnu/tests/ssh.scm b/gnu/tests/ssh.scm
index 791ff7b73f..e3dd601603 100644
--- a/gnu/tests/ssh.scm
+++ b/gnu/tests/ssh.scm
@@ -1,5 +1,5 @@
 ;;; GNU Guix --- Functional package management for GNU
-;;; Copyright © 2016, 2017, 2018, 2019, 2020, 2021 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2016-2022 Ludovic Courtès <ludo@gnu.org>
 ;;; Copyright © 2017, 2018 Clément Lassieur <clement@lassieur.org>
 ;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
 ;;;
@@ -120,19 +120,21 @@ root with an empty password."
                marionette))
 
             ;; Check sshd's PID file.
-            (test-equal "sshd PID"
-              (wait-for-file #$pid-file marionette)
-              (marionette-eval
-               '(begin
-                  (use-modules (gnu services herd)
-                               (srfi srfi-1))
-
-                  (live-service-running
-                   (find (lambda (live)
-                           (memq 'ssh-daemon
-                                 (live-service-provision live)))
-                         (current-services))))
-               marionette))
+            (test-assert "sshd PID"
+              (let ((pid (marionette-eval
+                          '(begin
+                             (use-modules (gnu services herd)
+                                          (srfi srfi-1))
+
+                             (live-service-running
+                              (find (lambda (live)
+                                      (memq 'ssh-daemon
+                                            (live-service-provision live)))
+                                    (current-services))))
+                          marionette)))
+                (if #$pid-file
+                    (= pid (wait-for-file #$pid-file marionette))
+                    pid)))
 
             (test-assert "wait for port 22"
               (wait-for-tcp-port 22 marionette))
@@ -222,7 +224,7 @@ root with an empty password."
                                  (openssh-configuration
                                   (permit-root-login #t)
                                   (allow-empty-passwords? #t)))
-                        "/var/run/sshd.pid"
+                        #f                        ;inetd-style, no PID file
                         #:sftp? #t))))
 
 (define %test-dropbear