diff mbox

openssh service

Message ID 20160819163125.0be91283@polymos
State New
Headers show

Commit Message

Julien Lepiller Aug. 19, 2016, 2:31 p.m. UTC
On Fri, 19 Aug 2016 16:15:48 +0200
Vincent Legoll <vincent.legoll@gmail.com> wrote:

> Hello,
> 
> On Fri, Aug 19, 2016 at 4:03 PM, Julien Lepiller <julien@lepiller.eu>
> wrote:
> > Does that mean I need to add an entry to the manual myself (if so,
> > could you tell me what file to edit?)  
> 
> I think that would be doc/guix.texi
> in http://git.savannah.gnu.org/cgit/guix.git
> 

Thank you, here is the patch with the documentation.

Comments

Andy Wingo Aug. 26, 2016, 10:51 a.m. UTC | #1
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.

WDYT?

Andy
Ludovic Courtès Aug. 29, 2016, 3:06 p.m. UTC | #2
Hi Julien,

I just discovered this patch as I go through my backlog, which is fun
because I used sshd as an example to illustrate how GuixSD services work
just a week ago.  :-)

Julien Lepiller <julien@lepiller.eu> skribis:

> +@deffn {Scheme Procedure} openssh-service [#:pidfile "/var/run/sshd.pid"] @

#:pid-file

> +       [#: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"]

I agree with Andy’s latest comments regarding naming.

Also, make sure to consistently use question marks for Boolean options,
as in #:allow-empty-passwords?.

Last thing, I would prefer to expose and document
<openssh-configuration>, as is done for Dropbear.  We should encourage
this style now, IMO.

(In commit 39012aab3333868d5ab3b39c95682f95212437e2 I enabled PAM
support in OpenSSH, though it’s off by default; maybe in a future patch
we can add #:pam-support?.)

> --- a/gnu/packages/ssh.scm
> +++ b/gnu/packages/ssh.scm
> @@ -142,7 +142,8 @@ a server that supports the SSH-2 protocol.")
>               ("zlib" ,zlib)
>               ("xauth" ,xauth)))                   ;for 'ssh -X' and 'ssh -Y'
>     (arguments
> -    `(#:test-target "tests"
> +    `(#:configure-flags `("--sysconfdir=/etc/ssh")
> +      #:test-target "tests"

I committed this part independently as
af493726ce16483bd09ed7f73028bab3294131e2.  :-)

> +When @var{x11-forwarding} is true, @command{ssh} options -X and -Y will work."

@option{-X} and @option{-Y}.

These are all cosmetic details.  If you prefer I can do it on your
behalf, just let me know; otherwise, please send an updated patch.

Thank you for your work!

Ludo’.
diff mbox

Patch

From 070513c1768763c80cad47832f895320fcc223be 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 |   3 +-
 gnu/services/ssh.scm | 139 ++++++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 174 insertions(+), 2 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 5330238..6be91ee 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -8042,6 +8042,40 @@  root.
 The other options should be self-descriptive.
 @end deffn
 
+@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).
+
+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 16cd6e2..457e78b 100644
--- a/gnu/packages/ssh.scm
+++ b/gnu/packages/ssh.scm
@@ -142,7 +142,8 @@  a server that supports the SSH-2 protocol.")
              ("zlib" ,zlib)
              ("xauth" ,xauth)))                   ;for 'ssh -X' and 'ssh -Y'
    (arguments
-    `(#:test-target "tests"
+    `(#:configure-flags `("--sysconfdir=/etc/ssh")
+      #:test-target "tests"
       #:phases
       (modify-phases %standard-phases
         (add-after 'configure 'reset-/var/empty
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index 9a7ea0f..60b9cec 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,137 @@  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
+                         (default "/var/run/sshd.pid"))
+  (port-number           openssh-configuration-port-number
+                         (default 22))
+  (root-login            openssh-configuration-root-login
+                         (default "without-password"))
+  (allow-empty-passwords? openssh-configuration-allow-empty-passwords?
+                          (default #f))
+  (password-authentication? openssh-configuration-password-authentication?
+                            (default #t))
+  (pubkey-authentication? openssh-configuration-pubkey-authentication?
+                            (default #t))
+  (rsa-authentication?   openssh-configuration-rsa-authentication?
+                            (default #t))
+  (x11-forwarding?       openssh-configuration-x11-forwarding?
+                            (default #f))
+  (protocol-number       openssh-configuration-protocol-number
+                         (default "2")))
+
+(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"
+              #$(openssh-configuration-protocol-number config))
+           (format port "Port ~a\n" 
+              #$(number->string (openssh-configuration-port-number config)))
+           (format port "PermitRootLogin ~a\n"
+              #$(openssh-configuration-root-login config))
+           (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 #:optional (config (openssh-configuration)))
+  "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).
+
+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."
+  (service openssh-service-type config))
+
 ;;;
 ;;; Dropbear.
 ;;;
-- 
2.9.3