1
0
mirror of https://git.savannah.gnu.org/git/guix.git synced 2026-04-06 21:20:33 +02:00

services: openssh: Add 'authorized-keys' field.

* gnu/services/ssh.scm (<openssh-configuration>)[authorized-keys]: New
field.
(authorized-key-directory): New procedure.
(openssh-config-file): Honor 'authorized-keys'.
(openssh-activation): Use 'with-imported-modules'.  Make /etc/ssh
755.  Create /etc/ssh/authorized_keys.d.
* doc/guix.texi (Networking Services): Document it.
This commit is contained in:
Ludovic Courtès
2017-07-25 15:27:58 +02:00
parent 75bddb13eb
commit 4892eb7c6a
2 changed files with 93 additions and 16 deletions

View File

@@ -28,6 +28,7 @@
#:use-module (gnu system shadow)
#:use-module (guix gexp)
#:use-module (guix records)
#:use-module (guix modules)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
#:export (lsh-configuration
@@ -295,7 +296,11 @@ The other options should be self-descriptive."
(default #t))
;; list of two-element lists
(subsystems openssh-configuration-subsystems
(default '(("sftp" "internal-sftp")))))
(default '(("sftp" "internal-sftp"))))
;; list of user-name/file-like tuples
(authorized-keys openssh-authorized-keys
(default '())))
(define %openssh-accounts
(list (user-group (name "sshd") (system? #t))
@@ -309,22 +314,64 @@ The other options should be self-descriptive."
(define (openssh-activation config)
"Return the activation GEXP for CONFIG."
#~(begin
(use-modules (guix build utils))
(mkdir-p "/etc/ssh")
(mkdir-p (dirname #$(openssh-configuration-pid-file config)))
(with-imported-modules '((guix build utils))
#~(begin
(use-modules (guix build utils))
(define (touch file-name)
(call-with-output-file file-name (const #t)))
(define (touch file-name)
(call-with-output-file file-name (const #t)))
(let ((lastlog "/var/log/lastlog"))
(when #$(openssh-configuration-print-last-log? config)
(unless (file-exists? lastlog)
(touch lastlog))))
;; Make sure /etc/ssh can be read by the 'sshd' user.
(mkdir-p "/etc/ssh")
(chmod "/etc/ssh" #o755)
(mkdir-p (dirname #$(openssh-configuration-pid-file config)))
;; Generate missing host keys.
(system* (string-append #$(openssh-configuration-openssh config)
"/bin/ssh-keygen") "-A")))
;; 'sshd' complains if the authorized-key directory and its parents
;; are group-writable, which rules out /gnu/store. Thus we copy the
;; authorized-key directory to /etc.
(catch 'system-error
(lambda ()
(delete-file-recursively "/etc/authorized_keys.d"))
(lambda args
(unless (= ENOENT (system-error-errno args))
(apply throw args))))
(copy-recursively #$(authorized-key-directory
(openssh-authorized-keys config))
"/etc/ssh/authorized_keys.d")
(chmod "/etc/ssh/authorized_keys.d" #o555)
(let ((lastlog "/var/log/lastlog"))
(when #$(openssh-configuration-print-last-log? config)
(unless (file-exists? lastlog)
(touch lastlog))))
;; Generate missing host keys.
(system* (string-append #$(openssh-configuration-openssh config)
"/bin/ssh-keygen") "-A"))))
(define (authorized-key-directory keys)
"Return a directory containing the authorized keys specified in KEYS, a list
of user-name/file-like tuples."
(define build
(with-imported-modules (source-module-closure '((guix build utils)))
#~(begin
(use-modules (ice-9 match) (srfi srfi-26)
(guix build utils))
(mkdir #$output)
(for-each (match-lambda
((user keys ...)
(let ((file (string-append #$output "/" user)))
(call-with-output-file file
(lambda (port)
(for-each (lambda (key)
(call-with-input-file key
(cut dump-port <> port)))
keys))))))
'#$keys))))
(computed-file "openssh-authorized-keys" build))
(define (openssh-config-file config)
"Return the sshd configuration file corresponding to CONFIG."
@@ -367,6 +414,11 @@ The other options should be self-descriptive."
(format port "PrintLastLog ~a\n"
#$(if (openssh-configuration-print-last-log? config)
"yes" "no"))
;; Add '/etc/authorized_keys.d/%u', which we populate.
(format port "AuthorizedKeysFile \
.ssh/authorized_keys .ssh/authorized_keys2 /etc/ssh/authorized_keys.d/%u\n")
(for-each
(match-lambda
((name command) (format port "Subsystem\t~a\t~a\n" name command)))