aboutsummaryrefslogtreecommitdiff
path: root/gnu/services/ssh.scm
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/services/ssh.scm')
-rw-r--r--gnu/services/ssh.scm131
1 files changed, 130 insertions, 1 deletions
diff --git a/gnu/services/ssh.scm b/gnu/services/ssh.scm
index ced21c0742..1891db0487 100644
--- a/gnu/services/ssh.scm
+++ b/gnu/services/ssh.scm
@@ -5,6 +5,7 @@
;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org>
;;; Copyright © 2019 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2020 pinoaffe <pinoaffe@airmail.cc>
+;;; Copyright © 2020 Oleg Pykhalov <go.wigust@gmail.com>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -26,6 +27,7 @@
#:use-module (gnu packages admin)
#:use-module (gnu services)
#:use-module (gnu services shepherd)
+ #:use-module (gnu services web)
#:use-module (gnu system pam)
#:use-module (gnu system shadow)
#:use-module (guix gexp)
@@ -50,7 +52,12 @@
autossh-configuration
autossh-configuration?
- autossh-service-type))
+ autossh-service-type
+
+ webssh-configuration
+ webssh-configuration?
+ webssh-service-type
+ %webssh-configuration-nginx))
;;; Commentary:
;;;
@@ -732,4 +739,126 @@ object."
autossh-service-activation)))
(default-value (autossh-configuration))))
+
+;;;
+;;; WebSSH
+;;;
+
+(define-record-type* <webssh-configuration>
+ webssh-configuration make-webssh-configuration
+ webssh-configuration?
+ (package webssh-configuration-package ;package
+ (default webssh))
+ (user-name webssh-configuration-user-name ;string
+ (default "webssh"))
+ (group-name webssh-configuration-group-name ;string
+ (default "webssh"))
+ (policy webssh-configuration-policy ;symbol
+ (default #f))
+ (known-hosts webssh-configuration-known-hosts ;list of strings
+ (default #f))
+ (port webssh-configuration-port ;number
+ (default #f))
+ (address webssh-configuration-address ;string
+ (default #f))
+ (log-file webssh-configuration-log-file ;string
+ (default "/var/log/webssh.log"))
+ (log-level webssh-configuration-log-level ;symbol
+ (default #f)))
+
+(define %webssh-configuration-nginx
+ (nginx-server-configuration
+ (listen '("80"))
+ (locations
+ (list (nginx-location-configuration
+ (uri "/")
+ (body '("proxy_pass http://127.0.0.1:8888;"
+ "proxy_http_version 1.1;"
+ "proxy_read_timeout 300;"
+ "proxy_set_header Upgrade $http_upgrade;"
+ "proxy_set_header Connection \"upgrade\";"
+ "proxy_set_header Host $http_host;"
+ "proxy_set_header X-Real-IP $remote_addr;"
+ "proxy_set_header X-Real-PORT $remote_port;")))))))
+
+(define webssh-account
+ ;; Return the user accounts and user groups for CONFIG.
+ (match-lambda
+ (($ <webssh-configuration> _ user-name group-name _ _ _ _ _ _)
+ (list (user-group
+ (name group-name))
+ (user-account
+ (name user-name)
+ (group group-name)
+ (comment "webssh privilege separation user")
+ (home-directory (string-append "/var/run/" user-name))
+ (shell #~(string-append #$shadow "/sbin/nologin")))))))
+
+(define webssh-activation
+ ;; Return the activation GEXP for CONFIG.
+ (match-lambda
+ (($ <webssh-configuration> _ user-name group-name policy known-hosts _ _
+ log-file _)
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (let* ((home-dir (string-append "/var/run/" #$user-name))
+ (ssh-dir (string-append home-dir "/.ssh"))
+ (known-hosts-file (string-append ssh-dir "/known_hosts")))
+ (call-with-output-file #$log-file (const #t))
+ (mkdir-p ssh-dir)
+ (case '#$policy
+ ((reject)
+ (if '#$known-hosts
+ (call-with-output-file known-hosts-file
+ (lambda (port)
+ (for-each (lambda (host) (display host port) (newline port))
+ '#$known-hosts)))
+ (display-hint (G_ "webssh: reject policy requires `known-hosts'.")))))
+ (for-each (lambda (file)
+ (chown file
+ (passwd:uid (getpw #$user-name))
+ (group:gid (getpw #$group-name))))
+ (list #$log-file ssh-dir known-hosts-file))
+ (chmod ssh-dir #o700)))))))
+
+(define webssh-shepherd-service
+ (match-lambda
+ (($ <webssh-configuration> package user-name group-name policy _ port
+ address log-file log-level)
+ (list (shepherd-service
+ (provision '(webssh))
+ (documentation "Run webssh daemon.")
+ (start #~(make-forkexec-constructor
+ `(,(string-append #$webssh "/bin/wssh")
+ ,(string-append "--log-file-prefix=" #$log-file)
+ ,@(case '#$log-level
+ ((debug) '("--logging=debug"))
+ (else '()))
+ ,@(case '#$policy
+ ((reject) '("--policy=reject"))
+ (else '()))
+ ,@(if #$port
+ (list (string-append "--port=" (number->string #$port)))
+ '())
+ ,@(if #$address
+ (list (string-append "--address=" #$address))
+ '()))
+ #:user #$user-name
+ #:group #$group-name))
+ (stop #~(make-kill-destructor)))))))
+
+(define webssh-service-type
+ (service-type
+ (name 'webssh)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ webssh-shepherd-service)
+ (service-extension account-service-type
+ webssh-account)
+ (service-extension activation-service-type
+ webssh-activation)))
+ (default-value (webssh-configuration))
+ (description
+ "Run the webssh.")))
+
;;; ssh.scm ends here