diff options
Diffstat (limited to 'tw/services/wireguard.scm')
-rw-r--r-- | tw/services/wireguard.scm | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/tw/services/wireguard.scm b/tw/services/wireguard.scm new file mode 100644 index 00000000..3d35cd2e --- /dev/null +++ b/tw/services/wireguard.scm @@ -0,0 +1,107 @@ +(define-module (tw services wireguard) + #:use-module (ice-9 regex) + #:use-module ((srfi srfi-1) #:select (append-map every)) + #:use-module ((srfi srfi-26) #:select (cut)) + #:use-module (gnu services) + #:use-module (gnu services base) + #:use-module (gnu services configuration) + #:use-module (gnu services vpn) + #:export (%wireguard-peers + tw-wireguard-configuration + tw-wireguard-service-type)) + +(define %wireguard-peers + `(("lap.twilken.net" . + ,(wireguard-peer + (name "lap.wg") + (public-key "lap/DvCb8xXLUCqcaPEx8kCRcoeV4ScTMVZW5hvvNzA=") + (preshared-key "/etc/wireguard/lap.psk") + (allowed-ips '("10.0.0.1/32" "fc00::1/128")))) + ("lud.twilken.net" . + ,(wireguard-peer + (name "lud.wg") + (endpoint "lud.twilken.net:58921") + (public-key "lud/9sbXVdOYXxOkRgAB+b/17QxbwllfJY/pbA3/MkE=") + (preshared-key "/etc/wireguard/lud.psk") + (allowed-ips '("10.0.0.2/32" "fc00::2/128")))) + ("vin.twilken.net" . + ,(wireguard-peer + (name "vin.wg") + (endpoint "vin.twilken.net:58921") + (public-key "vin/Im+sOszZFE01UF1+QlyxLP1PsPXJgTz4KmgvL3Y=") + (preshared-key "/etc/wireguard/vin.psk") + (allowed-ips '("10.0.0.3/32" "fc00::3/128")))) + ("fp4.twilken.net" . + ,(wireguard-peer + (name "fp4.wg") + (public-key "fp4/aLAVBADTy+UGmNh011w1CFOOwq70Df6EWlZRkAs=") + (preshared-key "/etc/wireguard/fp4.psk") + (allowed-ips '("10.0.0.4/32" "fc00::4/128")))) + ("pi3.twilken.net" . + ,(wireguard-peer + (name "pi3.wg") + (endpoint "pi3.twilken.net:58922") + (public-key "pi3/ThUH4qDTuyvNQIiiyy2dbziF/xLRTwO0+vcUoVY=") + (preshared-key "/etc/wireguard/pi3.psk") + (allowed-ips '("10.0.0.5/32" "fc00::5/128")))))) + +(define (wireguard-peers-list? object) + (and (list? object) + (every (compose string? car) object) + (every (compose wireguard-peer? cdr) object))) + +(define-configuration/no-serialization tw-wireguard-configuration + (this-host + (string) + "The host name of the machine being configured.") + (peers + (wireguard-peers-list %wireguard-peers) + "An alist of WireGuard peers to install.")) + +(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))) + (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))))))) + +(define (peer->ips peer) + "Extract IP addresses assigned to the given `wireguard-peer' PEER." + (map (compose car (cut string-split <> #\/)) + (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 tw-wireguard-service-type + (service-type + (name 'tw-wireguard) + (description "Set up my personal WireGuard network.") + (extensions + (cons* (service-extension hosts-service-type tw-wireguard-hosts) + ;; FIXME: `wireguard-service-type' cannot be extended, so copy its + ;; service-extensions directly. + (map (lambda (ext) + (service-extension (service-extension-target ext) + (compose (service-extension-compute ext) + tw-wireguard-service))) + (service-type-extensions wireguard-service-type)))))) |