Package: guix-patches;
Reported by: Maxim Cournoyer <maxim.cournoyer <at> gmail.com>
Date: Mon, 8 May 2023 16:09:01 UTC
Severity: normal
Done: Ludovic Courtès <ludo <at> gnu.org>
Bug is archived. No further changes may be made.
Message #11 received at 63375 <at> debbugs.gnu.org (full text, mbox):
From: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> To: 63375 <at> debbugs.gnu.org Cc: Maxim Cournoyer <maxim.cournoyer <at> gmail.com> Subject: [cuirass v3] doc: Document authentication. Date: Thu, 11 May 2023 00:34:52 -0400
* etc/new-client-cert.scm: Add script. * doc/cuirass.texi (Authentication): Document it. * Makefile.am (noinst_SCRIPTS): Register it. --- Makefile.am | 2 +- doc/cuirass.texi | 86 ++++++++++++++++++++++++++++ etc/new-client-cert.scm | 121 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100755 etc/new-client-cert.scm diff --git a/Makefile.am b/Makefile.am index a40a76d..62b0860 100644 --- a/Makefile.am +++ b/Makefile.am @@ -25,7 +25,7 @@ bin_SCRIPTS = \ bin/cuirass -noinst_SCRIPTS = pre-inst-env +noinst_SCRIPTS = pre-inst-env etc/new-client-cert.scm guilesitedir = $(datarootdir)/guile/site/@GUILE_EFFECTIVE_VERSION@ guileobjectdir = $(libdir)/guile/@GUILE_EFFECTIVE_VERSION@/site-ccache diff --git a/doc/cuirass.texi b/doc/cuirass.texi index db46a33..728ca7f 100644 --- a/doc/cuirass.texi +++ b/doc/cuirass.texi @@ -13,6 +13,7 @@ Copyright @copyright{} 2016, 2017 Mathieu Lirzin@* Copyright @copyright{} 2017, 2020, 2021 Mathieu Othacehe@* Copyright @copyright{} 2018, 2021 Ludovic Courtès@* Copyright @copyright{} 2018 Clément Lassieur +Copyright @copyright{} 2023 Maxim Cournoyer@* @quotation Permission is granted to copy, distribute and/or modify this document @@ -57,6 +58,7 @@ Documentation License''. * Parameters:: Cuirass parameters. * Build modes:: Build modes. * Invocation:: How to run Cuirass. +* Authentication:: Configuring TLS authentication. * Web API:: Description of the Web API. * Database:: About the database schema. @@ -711,6 +713,90 @@ Display the actual version of @code{cuirass}. Display an help message that summarize all the options provided. @end table +@c ********************************************************************* +@node Authentication +@chapter Authentication +@cindex authentication + +Cuirass does not provide its own authentication mechanism; by default, +any user can do anything via its web interface. To restrict this to +only authorized users, one approach is to proxy the Cuirass web site via +a web server such as Nginx and configure the web server to require +client certificate verification for pages under the @samp{/admin} +prefix. The following minimal Nginx configuration can be used to +accomplish this on a Guix System: + +@lisp +(service nginx-service-type + (nginx-configuration + (server-blocks + (list + ;; TLS is required for authentication; serve the site via + ;; HTTPS only. + (nginx-server-configuration + (listen '("80")) + (raw-content + (list "return 308 https://$host$request_uri;"))) + + (nginx-server-configuration + (listen '("443 ssl")) + (server-name '("ci.your-host.org")) + (ssl-certificate "/etc/certs/ci.your-host.org.crt") + (ssl-certificate-key "/etc/certs/ci.your-host.org.key") + (locations + (list + ;; Proxy the whole Cuirass web site... + (nginx-location-configuration + (uri "/") + (body (list "proxy_pass http://localhost:8081;"))) + ;; ... but require authentication for the admin pages. + (nginx-location-configuration + (uri "~ ^/admin") + (body + (list "if ($ssl_client_verify != SUCCESS) \ +@{ return 403; @} proxy_pass http://localhost:8081;"))))) + (raw-content + ;; Register your self-generated certificate authority. + (list "ssl_client_certificate /etc/ssl-ca/certs/ca.crt;" + "ssl_verify_client optional;"))))))) +@end lisp + +Your host TLS certificate could have been obtained via Let's Encrypt or +directly via the @command{openssl} command, among other means. To +create a private certificate authority (CA) that can sign user +certificates, a convenience script is provided. It's main requirement +is to have the @command{guix} command available. It can be invoked +like: + +@example +sudo -E ./etc/new-client-cert.scm --generate-ca +@end example + +It should generate the @file{/etc/ssl-ca/private/ca.key} private key as +well as the @file{/etc/ssl-ca/certs/ca.crt} certificate authority as +used in the Nginx configuration above. + +To issue a new user certificate, run the same script from your home +directory with: + +@example +sudo -E ./etc/new-client-cert.scm +@end example + +You will be asked to input the password for the CA private key, if any, +and again for your new certificate; save it carefully. The script +requires to run as root to have access to the private certificate +authority key; it outputs the new user certificate files to the current +working directory. + +After your new CA-signed user certificate is generated, it needs to be +registered with your web browser. To do so using GNU IceCat, for +example, you can navigate to @samp{Parameters -> Security -> Show +certificates} and then click the @samp{Import...} button and select your +@file{.pk12} personal certificate file. The web interface of Cuirass +should now only allow authenticated users to perform administrative +tasks. + @c ********************************************************************* @node Web API @chapter Web API diff --git a/etc/new-client-cert.scm b/etc/new-client-cert.scm new file mode 100755 index 0000000..4fac772 --- /dev/null +++ b/etc/new-client-cert.scm @@ -0,0 +1,121 @@ +#!/usr/bin/env -S guix shell guile openssl -- guile \\ +--no-auto-compile -e main -s +!# +;;;; cuirass.scm -- Cuirass public interface. +;;; Copyright © 2023 Ricardo Wurmus <rekado <at> elephly.net> +;;; Copyright © 2023 Maxim Cournoyer <maxim.cournoyer <at> gmail.com> +;;; +;;; This file is part of Cuirass. +;;; +;;; Cuirass is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published by +;;; the Free Software Foundation, either version 3 of the License, or +;;; (at your option) any later version. +;;; +;;; Cuirass is distributed in the hope that it will be useful, +;;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;;; GNU General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with Cuirass. If not, see <http://www.gnu.org/licenses/>. + +(use-modules (ice-9 format) + (ice-9 match) + (guix build utils)) + +(define %user (or (getenv "SUDO_USER") + (getenv "USER"))) + +(define %user-id (passwd:uid (getpwnam %user))) + +(define %group-id (passwd:gid (getpwnam %user))) + +(define %CA-directory + "/etc/ssl-ca") + +(define subject-template + "/C=DE/ST=Berlin/L=Berlin/O=GNU Guix/OU=Cuirass/CN=~a") + +(define CA-key + (string-append %CA-directory "/private/ca.key")) +(define CA-cert + (string-append %CA-directory "/certs/ca.crt")) + +(define* (output who file) + (string-append (getcwd) "/" who file)) + +(define (key-file who) + "Return the absolute file name of the key file for WHO." + (output who ".key")) + +(define (csr-file who) + "Return the absolute file name of the CSR file for WHO." + (output who ".csr")) + +(define (client-cert-file who) + "Return the absolute file name of the client certificate file for +WHO." + (output who ".crt")) + +(define (exported-cert-file who) + "Return the absolute file name of the pkcs12 client certificate file +for WHO. This is the file that users should import into their +browsers." + (output who ".p12")) + +(define (generate-ca!) + "Generate a private certificate authority (CA) valid for 10 years." + (mkdir-p (dirname CA-key)) + (mkdir-p (dirname CA-cert)) + (invoke "openssl" "req" "-newkey" "rsa" "-x509" "-days" "3650" + "-noenc" ;no password + "-subj" (format #false "~@?" subject-template "Cuirass CA") + "-keyout" CA-key "-out" CA-cert)) + +(define (generate-csr! who) + "Generate a new certificate signing request and key for WHO." + (let ((key (key-file who)) + (csr (csr-file who))) + (invoke "openssl" "req" "-newkey" "rsa" + "-noenc" ;no password + "-subj" (format #false "~@?" subject-template who) + "-keyout" key + "-out" csr) + (chown key %user-id %group-id) + (chown csr %user-id %group-id))) + +(define* (generate-client-certificate! who #:key (expiry 365)) + "Generate a client certificate for WHO." + (let ((cert (client-cert-file who))) + (invoke "openssl" "x509" "-req" + "-in" (csr-file who) + "-CA" CA-cert + "-CAkey" CA-key + "-out" cert + "-days" (number->string expiry)) + (chown cert %user-id %group-id))) + +(define (export-p12! who) + (let ((key (key-file who)) + (exported-cert (exported-cert-file who))) + (invoke "openssl" "pkcs12" "-export" + "-in" (client-cert-file who) + "-inkey" key + "-out" exported-cert) + (chown key %user-id %group-id) + (chown exported-cert %user-id %group-id))) + +(define (main args) + (match (command-line) + ((script) + (set-program-arguments (list script %user)) + (apply main args)) + ((script "--generate-ca") + (generate-ca!)) + ((script who) + (generate-csr! who) + (generate-client-certificate! who) + (export-p12! who)) + ((script . rest) + (format (current-error-port) "usage: ~a [--generate-ca|name]~%" script)))) base-commit: cf4e3e4ac4a9c8d6f0d82b0a173826f15bbca7f3 -- 2.39.2
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.