summaryrefslogtreecommitdiff
path: root/tw/services/wireguard.scm
diff options
context:
space:
mode:
Diffstat (limited to 'tw/services/wireguard.scm')
-rw-r--r--tw/services/wireguard.scm86
1 files changed, 63 insertions, 23 deletions
diff --git a/tw/services/wireguard.scm b/tw/services/wireguard.scm
index 3d35cd2e..e975fe46 100644
--- a/tw/services/wireguard.scm
+++ b/tw/services/wireguard.scm
@@ -6,6 +6,10 @@
#:use-module (gnu services base)
#:use-module (gnu services configuration)
#:use-module (gnu services vpn)
+ #:use-module (guix gexp)
+ #:use-module ((guix records) #:select (match-record))
+ #:use-module ((guix utils) #:select (current-source-directory))
+ #:use-module (tw services secrets)
#:export (%wireguard-peers
tw-wireguard-configuration
tw-wireguard-service-type))
@@ -56,41 +60,76 @@
"The host name of the machine being configured.")
(peers
(wireguard-peers-list %wireguard-peers)
- "An alist of WireGuard peers to install."))
+ "An alist of WireGuard peers to install.")
+ (private-key-file
+ (string "/etc/wireguard/private.key")
+ "Where to store this host's private key."))
+
+(define (other-peers this-host peers)
+ (let ((own-peer (assoc-ref peers this-host)))
+ (delq own-peer (map cdr peers))))
(define (tw-wireguard-service config)
"Create a full WireGuard config from the personal network CONFIG."
- (let ((own-peer (assoc-ref (tw-wireguard-configuration-peers config)
- (tw-wireguard-configuration-this-host config))))
- (wireguard-configuration
- (addresses
- (map (lambda (cidr)
- (let ((ipv4 (string-match "/32$" cidr))
- (ipv6 (string-match "/128$" cidr)))
- (cond
- (ipv4 (regexp-substitute #f ipv4 'pre "/24"))
- (ipv6 (regexp-substitute #f ipv6 'pre "/64"))
- (#t cidr))))
- (wireguard-peer-allowed-ips own-peer)))
- (port
- (let ((endpoint (wireguard-peer-endpoint own-peer)))
+ (match-record config <tw-wireguard-configuration> (this-host peers private-key-file)
+ (match-record (assoc-ref peers this-host) (@@ (gnu services vpn) <wireguard-peer>) (endpoint allowed-ips)
+ (wireguard-configuration
+ (addresses
+ (map (lambda (cidr)
+ (let ((ipv4 (string-match "/32$" cidr))
+ (ipv6 (string-match "/128$" cidr)))
+ (cond
+ (ipv4 (regexp-substitute #f ipv4 'pre "/24"))
+ (ipv6 (regexp-substitute #f ipv6 'pre "/64"))
+ (#t cidr))))
+ allowed-ips))
+ (port
(if endpoint
(string->number (cadr (string-split endpoint #\:)))
- 58921)))
- (private-key "/etc/wireguard/private.key")
- (peers (delq own-peer (map cdr (tw-wireguard-configuration-peers config)))))))
+ 58921))
+ (private-key private-key-file)
+ (peers (other-peers this-host peers))))))
+
+(define (cut-string-at-char str char-pred)
+ "Return the first part of STR up to the first occurrence of CHAR-PRED."
+ (substring str 0 (string-index str char-pred)))
(define (peer->ips peer)
"Extract IP addresses assigned to the given `wireguard-peer' PEER."
- (map (compose car (cut string-split <> #\/))
+ (map (cut cut-string-at-char <> #\/)
(wireguard-peer-allowed-ips peer)))
(define (tw-wireguard-hosts config)
"Generate a hosts file entries from the personal WireGuard network CONFIG."
- (append-map (lambda (peer)
- (map (cut host <> (wireguard-peer-name peer))
- (peer->ips peer)))
- (map cdr (tw-wireguard-configuration-peers config))))
+ (define (peer->entries peer)
+ (map (cut host <> (wireguard-peer-name peer))
+ (peer->ips peer)))
+ (append-map (compose peer->entries cdr)
+ (tw-wireguard-configuration-peers config)))
+
+(define (tw-wireguard-secrets config)
+ "Install secrets for the host's private key and preshared keys with peers."
+ (define (local-file-here path)
+ (local-file
+ (canonicalize-path
+ (string-append
+ (current-source-directory) "/" path))))
+ (match-record config <tw-wireguard-configuration> (this-host peers private-key-file)
+ (define short-host (cut-string-at-char this-host #\.))
+ (define private-key
+ (secret
+ (encrypted-file
+ (local-file-here (string-append "files/wireguard/" short-host ".key.enc")))
+ (destination private-key-file)))
+ (define (peer->secret peer)
+ (let ((short-peer (cut-string-at-char (wireguard-peer-name peer) #\.)))
+ (secret
+ (encrypted-file
+ (local-file-here
+ (string-append "files/wireguard/" short-host "-" short-peer ".psk.enc")))
+ (destination
+ (string-append "/etc/wireguard/" short-peer ".psk")))))
+ (cons private-key (map peer->secret (other-peers this-host peers)))))
(define tw-wireguard-service-type
(service-type
@@ -98,6 +137,7 @@
(description "Set up my personal WireGuard network.")
(extensions
(cons* (service-extension hosts-service-type tw-wireguard-hosts)
+ (service-extension secrets-service-type tw-wireguard-secrets)
;; FIXME: `wireguard-service-type' cannot be extended, so copy its
;; service-extensions directly.
(map (lambda (ext)