summaryrefslogtreecommitdiff
path: root/tw/system.scm
blob: 290b81c3a6183f9c864422194fd0d0ff0433877e (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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
(define-module (tw system)
  #:use-module (ice-9 format)
  #:use-module (ice-9 regex)
  #:use-module (ice-9 string-fun)
  #:use-module ((srfi srfi-1)
                #:select (fold fold-right))
  #:use-module (gnu)
  #:use-module (gnu services)
  #:use-module (gnu system)
  #:use-module (gnu system keyboard)
  #:use-module (guix gexp))

(use-package-modules admin avahi certs disk file-systems linux lsof man
                     moreutils python rsync search shells version-control vpn)
(use-service-modules mcron monitoring networking ssh vpn)

(define-public %base-system-packages
  (cons* acpi btrfs-progs cpupower efibootmgr exfat-utils git glibc-locales
         hddtemp htop lshw lsof man-db man-pages man-pages-posix mlocate
         moreutils nss-certs nss-mdns python rsync strace wireguard-tools
         %base-packages))

(define-public %british-keyboard
  (keyboard-layout
   "gb" #:options '("caps:swapescape"
                    "parens:swap_brackets"
                    "terminate:ctrl_alt_bksp"
                    "compose:rctrl"
                    "keypad:oss"
                    "kpdl:kposs")))

;; This is used for the servers, and also by (tw home) to generate the
;; appropriate ~/.ssh/config.
(define-public %ssh-ports
  '(("lud.twilken.net" . 22022)
    ("vin.twilken.net" . 22022)
    ("pi3.twilken.net" . 51022)))

(define-public (server-base-services host-name)
  (cons*
   ;; SSH login, allowing access only for me.  To give more public keys
   ;; access, extend `openssh-service-type'.
   (service openssh-service-type
     (openssh-configuration
      (port-number (assoc-ref %ssh-ports host-name))
      (password-authentication? #f)
      (accepted-environment '("LANG" "LC_*"))
      (authorized-keys
       `(("timo"
          ,(local-file "system/files/timo.pub")
          ,(local-file "system/files/timo-phone-gpg.pub"))))))

   ;; Prometheus node exporter
   (service prometheus-node-exporter-service-type
     (prometheus-node-exporter-configuration
      (web-listen-address
       (string-replace-substring
        (car   ; get the IPv4 address
         (wireguard-peer-allowed-ips
          (assoc-ref %wireguard-peers host-name)))
        "/32" ":9100"))))

   (simple-service 'disk-maintenance mcron-service-type
     (list #~(job "0 2 * * *" "guix gc -d 2w")
           #~(job "0 4 * * *"  ; after guix gc
                  (string-append #$(file-append util-linux "/sbin/fstrim")
                                 " --fstab --verbose"))))

   ;; Network setup
   (service dhcp-client-service-type)
   (service ntp-service-type)
   (wireguard-service host-name)

   ;; Delete the annoying message on SSH login.  Beware when setting up a new
   ;; host, as `allow-empty-passwords' will block login and sudo execution for
   ;; all Guix-declared users (as these have no initial password).
   (modify-services %base-services
     (login-service-type
      config =>
      (login-configuration
       (inherit config)
       (motd (plain-file "no-motd" ""))
       (allow-empty-passwords? #f))))))

(define-public %server-base-user-accounts
  (cons* (user-account
          (name "timo")
          (comment "Timo Wilken")
          (group "users")
          (home-directory "/home/timo")
          (supplementary-groups '("wheel" "netdev" "audio" "video"))
          (shell (file-append zsh "/bin/zsh")))
         %base-user-accounts))

(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-public %wireguard-etc-hosts
  (let ((basic-hosts-file "\
# This file was generated from your Guix configuration.
# Any changes will be lost upon reboot or reconfiguration.
127.0.0.1       localhost
255.255.255.255 broadcasthost
::1             localhost ip6-localhost ip6-loopback
fe00::0         ip6-localnet
ff00::0         ip6-mcastprefix
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
ff02::3         ip6-allhosts
"))
    (plain-file
     "hosts"
     (fold (lambda (peer hosts-file)
             (apply string-append hosts-file
                    (map (lambda (allowed-ip-cidr)
                           (format #f "~16a~a~%"
                                   (car (string-split allowed-ip-cidr #\/))
                                   (wireguard-peer-name peer)))
                         (wireguard-peer-allowed-ips peer))))
           basic-hosts-file
           (map cdr %wireguard-peers)))))

(define-public (wireguard-service host-name)
  (let ((own-peer (assoc-ref %wireguard-peers host-name)))
    (service wireguard-service-type
      (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 %wireguard-peers)))))))