~ruther/guix-local

86d8f6d3efb8300a3354735cbf06be6c01e23243 — Julien Lepiller 9 years ago 01c5c21
services: Add 'openssh-service'.

* gnu/packages/ssh.scm (openssh)[arguments]: Set sysconfdir to /etc/ssh.
* gnu/services/ssh.scm (<openssh-configuration>): New record type.
(%openssh-accounts): New variable.
(openssh-activation, openssh-config-file, openssh-shepherd-service)
(openssh-service): New procedures.
(openssh-service-type): New variable.
* doc/guix.texi (Networking Services): Document 'openssh-services'.

Co-authored-by: Ludovic Courtès <ludo@gnu.org>
3 files changed, 166 insertions(+), 1 deletions(-)

M doc/guix.texi
M gnu/packages/ssh.scm
M gnu/services/ssh.scm
M doc/guix.texi => doc/guix.texi +34 -0
@@ 8199,6 8199,40 @@ root.
The other options should be self-descriptive.
@end deffn

@deffn {Scheme Procedure} openssh-service [#:pid-file "/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{pid-file}.  It understands SSH protocol
@var{protocol-number}. The @var{protocol-number} can be either 1 or 2.

@var{permit-root-login} takes one of @code{#t}, @code{'without-password}
and @code{#f}.  It is used to allow root login through SSH.
@code{'without-password} means that root login is allowed, but not with
password-based authentication.

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
@file{~/.ssh/authorized_keys}.  This is used only by protocol version 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 @option{-X}
and @option{-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>}

M gnu/packages/ssh.scm => gnu/packages/ssh.scm +1 -1
@@ 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"

M gnu/services/ssh.scm => gnu/services/ssh.scm +131 -0
@@ 1,6 1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2014, 2015, 2016 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2016 David Craven <david@craven.ch>
;;; Copyright © 2016 Julien Lepiller <julien@lepiller.eu>
;;;
;;; This file is part of GNU Guix.
;;;


@@ 19,17 20,25 @@

(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)
  #:use-module (ice-9 match)
  #:export (lsh-configuration
            lsh-configuration?
            lsh-service
            lsh-service-type

            openssh-configuration
            openssh-configuration?
            openssh-service-type
            openssh-service

            dropbear-configuration
            dropbear-configuration?
            dropbear-service-type


@@ 246,6 255,128 @@ The other options should be self-descriptive."


;;;
;;; OpenSSH.
;;;

(define-record-type* <openssh-configuration>
  openssh-configuration make-openssh-configuration
  openssh-configuration?
  (pid-file              openssh-configuration-pid-file) ;string
  (port-number           openssh-configuration-port-number) ;integer
  (permit-root-login     openssh-configuration-permit-root-login) ;Boolean | 'without-password
  (allow-empty-passwords? openssh-configuration-allow-empty-passwords?) ;Boolean
  (password-authentication? openssh-configuration-password-authentication?) ;Boolean
  (pubkey-authentication? openssh-configuration-pubkey-authentication?) ;Boolean
  (rsa-authentication?   openssh-configuration-rsa-authentication?) ;Boolean
  (x11-forwarding?       openssh-configuration-x11-forwarding?) ;Boolean
  (protocol-number       openssh-configuration-protocol-number)) ;integer

(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 (dirname #$(openssh-configuration-pid-file config)))

      ;; Generate missing host keys.
      (system* (string-append #$openssh "/bin/ssh-keygen") "-A")))

(define (openssh-config-file config)
  "Return the sshd configuration file corresponding to CONFIG."
  (computed-file
   "sshd_config"
   #~(call-with-output-file #$output
       (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"
                 #$(match (openssh-configuration-permit-root-login config)
                     (#t "yes")
                     (#f "no")
                     ('without-password "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-pid-file config))
         #t))))

(define (openssh-shepherd-service config)
  "Return a <shepherd-service> for openssh with CONFIG."

  (define pid-file
    (openssh-configuration-pid-file config))

  (define openssh-command
    #~(list (string-append #$openssh "/sbin/sshd")
            "-D" "-f" #$(openssh-config-file config)))

  (list (shepherd-service
         (documentation "OpenSSH server.")
         (requirement '(networking syslogd))
         (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
                          (pid-file "/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
                                 (pid-file pid-file)
                                 (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.
;;;