summary refs log tree commit diff
path: root/gnu/home/services
diff options
context:
space:
mode:
authorSaku Laesvuori <saku@laesvuori.fi>2023-04-20 14:30:24 +0300
committerLudovic Courtès <ludo@gnu.org>2023-04-21 17:09:50 +0200
commit9043e23196ba28590ee272fb5f71f30a4ab73385 (patch)
tree29b396ceb716a3b3baf41f88750e31dd431f738a /gnu/home/services
parentfb17c47efe7a9b8b7a5cf86b357dc89dca2bc7bf (diff)
downloadguix-9043e23196ba28590ee272fb5f71f30a4ab73385.tar.gz
home: services: openssh: Add configuration option for jump proxies
Add a new 'proxy' field to openssh-host to allow ProxyCommand or
ProxyJump, but not both, to be configured. Configuring both would cause
the serialization order to determine which one is used. Deprecate the
'proxy-command' field because the 'proxy' field replaces it.

* gnu/home/services/ssh.scm (proxy-jump->string,
proxy-command-or-jump-list?, serialize-proxy-command-or-jump-list,
sanitize-proxy-command): New procedure.
(proxy-jump, proxy-command): New record type.
(openssh-host)[proxy-command]: Mark field as deprecated because OpenSSH
can't have ProxyCommand and ProxyJump configured at the same time.
* doc/guix.texi (Secure Shell): Update to match the changes to the
service.

Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Diffstat (limited to 'gnu/home/services')
-rw-r--r--gnu/home/services/ssh.scm65
1 files changed, 64 insertions, 1 deletions
diff --git a/gnu/home/services/ssh.scm b/gnu/home/services/ssh.scm
index 01917a29cd..6aeb6ad5a7 100644
--- a/gnu/home/services/ssh.scm
+++ b/gnu/home/services/ssh.scm
@@ -20,6 +20,7 @@
 (define-module (gnu home services ssh)
   #:use-module (guix gexp)
   #:use-module (guix records)
+  #:use-module (guix deprecation)
   #:use-module (guix diagnostics)
   #:use-module (guix i18n)
   #:use-module (gnu services)
@@ -32,6 +33,8 @@
   #:autoload   (gnu packages base) (glibc-utf8-locales)
   #:use-module (gnu packages ssh)
   #:use-module (srfi srfi-1)
+  #:use-module (srfi srfi-9)
+  #:use-module (srfi srfi-9 gnu)
   #:use-module (srfi srfi-34)
   #:use-module (srfi srfi-35)
   #:use-module (ice-9 match)
@@ -55,6 +58,12 @@
             openssh-host-host-key-algorithms
             openssh-host-accepted-key-types
             openssh-host-extra-content
+            proxy-jump
+            proxy-jump-host-name
+            proxy-jump-port
+            proxy-jump-user
+            proxy-command
+            proxy-command->string
 
             home-openssh-service-type
             home-ssh-agent-service-type))
@@ -114,6 +123,54 @@
 
 (define-maybe string-list)
 
+(define-record-type <proxy-command>
+  (proxy-command command)
+  proxy-command?
+  (command proxy-command->string))
+
+(set-record-type-printer! <proxy-command>
+  (lambda (obj port)
+    (format port "#<proxy-command ~s>" (proxy-command->string obj))))
+
+(define-configuration/no-serialization proxy-jump
+  (user
+   maybe-string
+   "User name on the remote host.")
+  (host-name
+   (string)
+   "Host name---e.g., @code{foo.example.org} or @code{192.168.1.2}.")
+  (port
+   maybe-natural-number
+   "TCP port number to connect to."))
+
+(define (proxy-jump->string proxy-jump)
+  (match-record proxy-jump <proxy-jump>
+    (host-name user port)
+    (string-append
+      (if (maybe-value-set? user) (string-append user "@") "")
+      host-name
+      (if (maybe-value-set? port) (string-append ":" (number->string port)) ""))))
+
+(define (proxy-command-or-jump-list? x)
+  (or (proxy-command? x)
+      (and (list? x)
+           (every proxy-jump? x))))
+
+(define (serialize-proxy-command-or-jump-list field value)
+  (if (proxy-command? value)
+    (serialize-string 'proxy-command (proxy-command->string value))
+    (serialize-string-list 'proxy-jump (map proxy-jump->string value))))
+
+(define-maybe proxy-command-or-jump-list)
+
+(define (sanitize-proxy-command properties)
+  (lambda (value)
+  (when (maybe-value-set? value)
+    (warn-about-deprecation 'proxy-command properties #:replacement 'proxy))
+  (unless (maybe-string? value)
+    (configuration-field-error (source-properties->location properties) 'proxy-command value))
+  value))
+
 (define-configuration openssh-host
   (name
    (string)
@@ -155,7 +212,13 @@ machine.")
    maybe-string
    "The command to use to connect to the server.  As an example, a command
 to connect via an HTTP proxy at 192.0.2.0 would be: @code{\"nc -X
-connect -x 192.0.2.0:8080 %h %p\"}.")
+connect -x 192.0.2.0:8080 %h %p\"}.  Using 'proxy-command' is deprecated, use
+'proxy' instead."
+   (sanitizer (sanitize-proxy-command (current-source-location))))
+  (proxy
+   maybe-proxy-command-or-jump-list
+   "The command to use to connect to the server or a list of SSH hosts to jump
+through before connecting to the server.")
   (host-key-algorithms
    maybe-string-list
    "The list of accepted host key algorithms---e.g.,