diff mbox

openssh service

Message ID 20160926184219.56cfe149@polymos
State New
Headers show

Commit Message

Julien Lepiller Sept. 26, 2016, 4:42 p.m. UTC
On Fri, 26 Aug 2016 12:51:56 +0200
Andy Wingo <wingo@igalia.com> wrote:

> Hi Julien,
> 
> Thanks for the documentation update!
> 
> On Fri 19 Aug 2016 16:31, Julien Lepiller <julien@lepiller.eu> writes:
> 
> > +@deffn {Scheme Procedure} openssh-service [#:pidfile
> > "/var/run/sshd.pid"] @
> > +       [#:port-number 22] [#:root-login "without-password"] @
> > +       [#:allow-empty-passwords #f] [#:password-authentication?
> > #t] @
> > +       [#:pubkey-authentication? #t] [#:rsa-authentication? #t] @
> > +       [#:x11-forwarding? #f] [#:protocol-number "2"]
> > +"Run the @command{sshd} program from @var{openssh} on port
> > @var{port-number}. +@command{sshd} runs an ssh daemon and writes
> > its PID to @var{pidfile}. It +understands ssh protocol
> > @var{protocol-number}. The @var{protocol-number} can +be one of
> > \"1\", \"2\" or \"1,2\". +
> > +@var{PermitRootLogin} takes one of @var{yes},
> > @var{without-password} and +@var{no}. It is used to allow root
> > login through ssh. @var{without-password} +means that root login is
> > allowed, except when loging with a password (eg: a +public key).  
> 
> The variable needs to be changed to @var{root-login} (and I think
> probably @var{permit-root-login} would be more expected), and probably
> "without-password" should be a symbol rather than a string.  In
> general I think naming the keywords after the upstream options is
> going to be the least confusing thing for users.  Consider changing
> from yes/no/without-password to #t/#f/without-password, and renaming
> the option to #:permit-root-login?.  Consider requiring that the
> protocol number be either 1 or 2.  In general we want to make errors
> happen early, when building the OS, rather than when the OS is booted.

Sorry for the delay, here is a new version of the patch.

Meanwhile, sysconfdir was set to /etc, but I changed this for /etc/ssh,
because openssh looks for its configuration and other files (about 10)
directly in sysconfdir, not a subdirectory. Also, I fixed a mistake in
openssh-service (it was not following what the doc said).

> 
> WDYT?
> 
> Andy

Comments

Ludovic Courtès Sept. 29, 2016, 9:15 p.m. UTC | #1
Hi Julien,

Julien Lepiller <julien@lepiller.eu> skribis:

> Sorry for the delay, here is a new version of the patch.
>
> Meanwhile, sysconfdir was set to /etc, but I changed this for /etc/ssh,
> because openssh looks for its configuration and other files (about 10)
> directly in sysconfdir, not a subdirectory. Also, I fixed a mistake in
> openssh-service (it was not following what the doc said).

[...]

> From cf879a47c8f9b0733fac906cd4bd28dc646aa9fb Mon Sep 17 00:00:00 2001
> From: Julien Lepiller <julien@lepiller.eu>
> Date: Fri, 5 Aug 2016 15:20:15 +0200
> Subject: [PATCH] services: Add openssh
>
> * gnu/packages/ssh.scm: Openssh reads its configuration from /etc
> * gnu/services/ssh.scm: Add openssh-service
> * doc/guix.texi (Networking Services): Document 'openssh-services'.

Pushed as 071fbb42a6e2dcdfd566cba9525e6ae6a4dfdc7d with a few changes.
In particular, I changed the config file to be passed as a command-line
option rather than added to /etc/ssh (this is generally preferable.)

Eventually I’d like to document and expose of ‘openssh-configuration’.

Thanks!

Ludo’.
Ludovic Courtès Oct. 2, 2016, 10:42 p.m. UTC | #2
ludo@gnu.org (Ludovic Courtès) skribis:

> Julien Lepiller <julien@lepiller.eu> skribis:

[...]

>> From cf879a47c8f9b0733fac906cd4bd28dc646aa9fb Mon Sep 17 00:00:00 2001
>> From: Julien Lepiller <julien@lepiller.eu>
>> Date: Fri, 5 Aug 2016 15:20:15 +0200
>> Subject: [PATCH] services: Add openssh
>>
>> * gnu/packages/ssh.scm: Openssh reads its configuration from /etc
>> * gnu/services/ssh.scm: Add openssh-service
>> * doc/guix.texi (Networking Services): Document 'openssh-services'.
>
> Pushed as 071fbb42a6e2dcdfd566cba9525e6ae6a4dfdc7d with a few changes.
> In particular, I changed the config file to be passed as a command-line
> option rather than added to /etc/ssh (this is generally preferable.)
>
> Eventually I’d like to document and expose of ‘openssh-configuration’.

Done in d8f3128119d32bcc186c8a1fe15b037bba25b4b8, let me know what you
think!

I also added a basic system test in
d5b0c9024ed174907aed4816b2607ada814a035c.  It makes sure that sshd is
started and that we can connect to it as root with an empty password, as
specified in the system config.

Ludo’.
Ludovic Courtès Oct. 3, 2016, 4:01 p.m. UTC | #3
ludo@gnu.org (Ludovic Courtès) skribis:

> I also added a basic system test in
> d5b0c9024ed174907aed4816b2607ada814a035c.  It makes sure that sshd is
> started and that we can connect to it as root with an empty password, as
> specified in the system config.

Commit 2b4363891c70bbf641bff8ff0a6fb7526babd5b9 extends the test for
Dropbear.  :-)

(lshd is harder to test because it needs keyboard input to generate the
seed, or we’d need to provide it with a dummy seed or something.)

Ludo’.
diff mbox

Patch

From cf879a47c8f9b0733fac906cd4bd28dc646aa9fb Mon Sep 17 00:00:00 2001
From: Julien Lepiller <julien@lepiller.eu>
Date: Fri, 5 Aug 2016 15:20:15 +0200
Subject: [PATCH] services: Add openssh

* gnu/packages/ssh.scm: Openssh reads its configuration from /etc
* gnu/services/ssh.scm: Add openssh-service
* doc/guix.texi (Networking Services): Document 'openssh-services'.
---
 doc/guix.texi        |  34 ++++++++++++++
 gnu/packages/ssh.scm |   2 +-
 gnu/services/ssh.scm | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 161 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 808fbdc..bcd8b6b 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8199,6 +8199,40 @@  root.
 The other options should be self-descriptive.
 @end deffn
 
+@deffn {Scheme Procedure} openssh-service [#:pidfile "/var/run/sshd.pid"] @
+       [#:port-number 22] [#:permit-root-login 'without-password] @
+       [#:allow-empty-passwords #f] [#:password-authentication? #t] @
+       [#:pubkey-authentication? #t] [#:rsa-authentication? #t] @
+       [#:x11-forwarding? #f] [#:protocol-number "2"]
+"Run the @command{sshd} program from @var{openssh} on port @var{port-number}.
+@command{sshd} runs an ssh daemon and writes its PID to @var{pidfile}. It
+understands ssh protocol @var{protocol-number}. The @var{protocol-number} can
+be either 1 or 2.
+
+@var{permit-root-login} takes one of @var{yes}, @var{without-password} and
+@var{no}. It is used to allow root login through ssh. @var{without-password}
+means that root login is allowed, except when loging with a password (eg: a
+public key).
+
+When @var{allow-empty-passwords?} is true, users with empty passwords may log
+in. When false, they may not.
+
+When @var{password-authentication?} is true, users may log in with their
+password. When false, they have to use other means of authentication.
+
+When @var{pubkey-authentication?} is true, users may log in using public key
+authentication. When false, users have to use other means of authentication.
+Authorized public keys are stored in ~/.ssh/authorized_keys. This is used only
+by protocol 2.
+
+When @var{rsa-authentication?} is true, users may log in using pure RSA
+authentication. When false, users have to use other means of authentication.
+This is used only by protocol 1.
+
+When @var{x11-forwarding} is true, @command{ssh} options -X and -Y will work.
+
+@end deffn
+
 @deffn {Scheme Procedure} dropbear-service [@var{config}]
 Run the @uref{https://matt.ucc.asn.au/dropbear/dropbear.html,Dropbear SSH
 daemon} with the given @var{config}, a @code{<dropbear-configuration>}
diff --git a/gnu/packages/ssh.scm b/gnu/packages/ssh.scm
index b2612a4..88bfd06 100644
--- a/gnu/packages/ssh.scm
+++ b/gnu/packages/ssh.scm
@@ -144,7 +144,7 @@  a server that supports the SSH-2 protocol.")
              ("xauth" ,xauth)))                   ;for 'ssh -X' and 'ssh -Y'
    (arguments
     `(#:test-target "tests"
-      #:configure-flags '("--sysconfdir=/etc"
+      #:configure-flags '("--sysconfdir=/etc/ssh"
 
                           ;; Default value of 'PATH' used by sshd.
                           "--with-default-path=/run/current-system/profile/bin"
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index 462988c..5484463 100644
--- a/gnu/services/ssh.scm
+++ b/gnu/services/ssh.scm
@@ -19,9 +19,11 @@ 
 
 (define-module (gnu services ssh)
   #:use-module (gnu packages ssh)
+  #:use-module (gnu packages admin)
   #:use-module (gnu services)
   #:use-module (gnu services shepherd)
   #:use-module (gnu system pam)
+  #:use-module (gnu system shadow)
   #:use-module (guix gexp)
   #:use-module (guix records)
   #:use-module (srfi srfi-26)
@@ -30,6 +32,11 @@ 
             lsh-service
             lsh-service-type
 
+            openssh-configuration
+            openssh-configuration?
+            openssh-service-type
+            openssh-service
+
             dropbear-configuration
             dropbear-configuration?
             dropbear-service-type
@@ -244,7 +251,125 @@  The other options should be self-descriptive."
                                public-key-authentication?)
                               (initialize? initialize?))))
 
-
+;;;
+;;; OpenSSH.
+;;;
+
+(define-record-type* <openssh-configuration>
+  openssh-configuration make-openssh-configuration
+  openssh-configuration?
+  (pidfile               openssh-configuration-pidfile)
+  (port-number           openssh-configuration-port-number)
+  (permit-root-login?    openssh-configuration-permit-root-login)
+  (allow-empty-passwords? openssh-configuration-allow-empty-passwords?)
+  (password-authentication? openssh-configuration-password-authentication?)
+  (pubkey-authentication? openssh-configuration-pubkey-authentication?)
+  (rsa-authentication?   openssh-configuration-rsa-authentication?)
+  (x11-forwarding?       openssh-configuration-x11-forwarding?)
+  (protocol-number       openssh-configuration-protocol-number))
+
+(define %openssh-accounts
+  (list (user-group (name "sshd") (system? #t))
+        (user-account
+          (name "sshd")
+          (group "sshd")
+          (system? #t)
+          (comment "sshd privilege separation user")
+          (home-directory "/var/run/sshd")
+          (shell #~(string-append #$shadow "/sbin/nologin")))))
+
+(define (openssh-activation config)
+  "Return the activation GEXP for CONFIG."
+  #~(begin
+      (mkdir-p "/etc/ssh")
+      (mkdir-p (basename #$(openssh-configuration-pidfile config)))
+      (system* (string-append #$openssh "/bin/ssh-keygen") "-A")
+      (call-with-output-file "/etc/ssh/sshd_config"
+         (lambda (port)
+           (display
+             "# Generated by 'openssh-service'.\n"
+             port)
+           (format port "Protocol ~a\n"
+              #$(if (eq? (openssh-configuration-protocol-number config) 1)
+                     "1" "2"))
+           (format port "Port ~a\n" 
+              #$(number->string (openssh-configuration-port-number config)))
+           (format port "PermitRootLogin ~a\n"
+              #$(if (eq? (openssh-configuration-permit-root-login config) #t)
+                    "yes" (if (eq?
+                              (openssh-configuration-permit-root-login config)
+                               #f)
+                               "no" "without-password")))
+           (format port "PermitEmptyPasswords ~a\n"
+              #$(if (openssh-configuration-allow-empty-passwords? config)
+                    "yes" "no"))
+           (format port "PasswordAuthentication ~a\n"
+              #$(if (openssh-configuration-password-authentication? config)
+                    "yes" "no"))
+           (format port "PubkeyAuthentication ~a\n"
+              #$(if (openssh-configuration-pubkey-authentication? config)
+                    "yes" "no"))
+           (format port "RSAAuthentication ~a\n"
+              #$(if (openssh-configuration-rsa-authentication? config)
+                    "yes" "no"))
+           (format port "X11Forwarding ~a\n"
+              #$(if (openssh-configuration-x11-forwarding? config)
+                    "yes" "no"))
+           (format port "PidFile ~a\n"
+              #$(openssh-configuration-pidfile config))))))
+
+(define (openssh-shepherd-service config)
+  "Return a <shepherd-service> for openssh with CONFIG."
+
+  (define pid-file
+    (openssh-configuration-pidfile config))
+
+  (define openssh-command
+    #~(list (string-append #$openssh "/sbin/sshd")
+            "-D"))
+
+  (define requires
+        '(networking syslogd))
+
+  (list (shepherd-service
+         (documentation "Openssh SSH server.")
+         (requirement requires)
+         (provision '(ssh-daemon))
+         (start #~(make-forkexec-constructor #$openssh-command
+                                             #:pid-file #$pid-file))
+         (stop #~(make-kill-destructor)))))
+
+(define openssh-service-type
+  (service-type (name 'openssh)
+                (extensions
+                 (list (service-extension shepherd-root-service-type
+                                          openssh-shepherd-service)
+                       (service-extension activation-service-type
+                                          openssh-activation)
+                       (service-extension account-service-type
+                                          (const %openssh-accounts))))))
+
+(define* (openssh-service #:key 
+                          (pidfile "/var/run/sshd.pid")
+                          (port-number 22)
+                          (permit-root-login? 'without-password)
+                          (allow-empty-passwords? #f)
+                          (password-authentication? #t)
+                          (pubkey-authentication? #t)
+                          (rsa-authentication? #t)
+                          (x11-forwarding? #f)
+                          (protocol-number 2))
+  (service openssh-service-type (openssh-configuration (pidfile pidfile)
+                                 (port-number port-number)
+                                 (permit-root-login? permit-root-login?)
+                                 (allow-empty-passwords? allow-empty-passwords?)
+                                 (password-authentication? password-authentication?)
+                                 (pubkey-authentication? pubkey-authentication?)
+                                 (rsa-authentication? rsa-authentication?)
+                                 (x11-forwarding? x11-forwarding?)
+                                 (protocol-number protocol-number))))
+
+                                                                                
 ;;;
 ;;; Dropbear.
 ;;;
-- 
2.10.0