summaryrefslogtreecommitdiff
path: root/tw/services/wireguard.scm
blob: 3d35cd2ec746aab52f10e2b4a0a8905e3acd5800 (about) (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
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))))))