aboutsummaryrefslogtreecommitdiff
path: root/src/infrastructure/machines.scm
blob: f51e74adbaeb985be71b76ebee2f55f34502491e (plain) (blame)
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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
(use-modules (gnu)
             (curth0)
             (srfi srfi-26)

             (gnu packages ssh)

             (gnu services certbot)
             (gnu services mcron)
             (gnu services mail)
             (gnu services networking)
             (gnu services ssh)
             (gnu services web))


(define ssh.conf #"""-
	ClientAliveInterval 30
	ClientAliveCountMax 20
	MaxSessions 20

	Host suyin
	  HostName ch-s010.rsync.net
	  User 16686
	"""#)

(define profile-extra
  (plain-file "profile-extra" #"""-
	export BORG_REMOTE_PATH='borg1'
	export BORG_PASSPHRASE_FD='/opt/secrets/borg-passphrase.txt'
"""#))

(define bashrc-extra
  (plain-file "bashrc-extra" #"""-
	alias l='ls -lahF --color'
	alias info='info --init-file /etc/infokey'

	export EDITOR=vi
"""#))

(define ps1.sh
  (plain-file "ps1.sh" #"""-
	end="\033[0m"

	gray() {
		printf "\033[0;90m$1$end"
	}

	yellow() {
		printf "\033[1;33m$1$end"
	}

	red() {
		printf "\033[1;31m$1$end"
	}

	redl() {
		printf "\033[0;31m$1$end"
	}

	error_marker() {
		STATUS=$?
		if [ "$STATUS" != 0 ]; then
			red " (!! $STATUS !!) "
		fi
	}

	export PS1='`error_marker`'$(gray '\T')' '$(yellow '\w/')'\n'$(redl '\\u@\h')'\$ '
"""#))

(define infokey
  (plain-file "infokey" #"""-
	^e down-line
	^y up-line
"""#))

(define with-email.sh
  (plain-file "with-email.sh" #"""-
	#!/bin/sh
	set -u

	while getopts 's:' flag; do
		case "$flag" in
			s)
				SUBJECT="$OPTARG"
				;;
			*)
				exit 2
				;;
		esac
	done
	shift $((OPTIND - 1))

	now() {
		date '+%Y-%m-%dT%H:%M:%S%Z'
	}

	uuid() {
		# Taken from:
		# https://serverfault.com/a/799198
		od -xN20 /dev/urandom |
			head -n1 |
			awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}'
	}

	mkstemp() {
		name="${TMPDIR:-/tmp}/uuid-tmpname with spaces.$(uuid)"
		touch "$name"
		echo "$name"
	}

	OUT="$(mkstemp)"
	printf 'Running command: %s\nStarting at: %s\n\n' "$*" "$(now)" >> "$OUT"
	("$@" 2>&1) >> "$OUT"
	STATUS="$?"
	printf '\nFinished at: %s\n' "$(now)" >> "$OUT"

	mail \
		-a 'Content-Type: text/plain; charset=UTF-8'         \
		-a 'From:cron@arrobaponto.org'                       \
		-s "(exit status: $STATUS) - ${SUBJECT:-NO SUBJECT}" \
		eu@euandre.org < "$OUT"

	cat "$OUT"
"""#))

(define backup.sh
  (plain-file "backup.sh" #"""-
	#!/bin/sh
	set -eux
	. /etc/profile-extra

	finish() {
		STATUS=$?
		printf '\n>>>\n>>> exit status: %s\n>>>\n\n' "$STATUS" >&2
	}
	trap finish EXIT

	borg init -e repokey-blake2 suyin:borg/toph ||:
	borg key export suyin:borg/toph /opt/secrets/borg-key.txt

	borg create \
		--exclude /root/.cache/                          \
		--stats                                          \
		--compression lzma,9                             \
		suyin:borg/toph::{hostname}-{now}-${1:-cronjob}" \
		/root/                                           \
		/home/                                           \
		/etc/letsencrypt/                                \
		/var/lib/certbot/                                \
		/var/lib/letsencrypt                             \
		/opt/

	borg check \
		--verbose    \
		suyin:borg/toph

	borg prune \
		--verbose         \
		--list            \
		--keep-within=6m  \
		--keep-weekly=52  \
		--keep-monthly=24 \
		suyin:borg/toph
"""#))

(define vi.exrc
  (plain-file "vi.exrc" #"""-
	" set number
	set autoindent
	set tabstop=8
	set shiftwidth=8
	set ruler
	set showmode
	set showmatch
"""#))

(define opensmtpd.conf
  (plain-file "opensmtpd.conf" #"""-
	listen on 0.0.0.0

	action inbound mbox
	match for local action inbound

	action outbound relay
	match from local for any action outbound
"""#))

(define opensmtpd.conf1
  (plain-file "opensmtpd.conf" #"""-
	table aliases file:/etc/aliases
	table creds { }

	pki mail.arrobaponto.org cert "/etc/letsencrypt/live/arrobaponto.org/fullchain.pem"
	pki mail.arrobaponto.org key  "/etc/letsencrypt/live/arrobaponto.org/privkey.pem"

	listen on eth0

	filter check_dyndns phase connect match rdns regex { '.*\.dyn\..*', '.*\.dsl\..*' } junk
	filter check_rdns phase connect match !rdns junk
	filter check_fcrdns phase connect match !fcrdns junk

	accept from any for domain "arrobaponto.org" alias <aliases> deliver to maildir
	accept for local alias <aliases> deliver to maildir

	accept for any relay
"""#))


(define cronjobs
  (list
   #~(job "0 30 * * 0" "guix gc -d 1m -F 10G")))


(define admin-user "andreh")

(define andreh-pk
  "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDnUv7iWOejQNa3fZ6v4lkHT6qFRp2+NuzIpFJ2Vy7eP58XZoiz6HJPcCU8Hf95JXwaXEwS4S7mXdw1x60hd8JIe058Ek6MZSSVQmlLfocGsAYj1wTrLmnQ8+PV0IeQlNj1aytBI1fL+v3IPt+JdLt6b+g3vwcEUU9efzxx2E0KZ5GIpb2meiCQ6ha+tcd7XqegB53eQj/h/coE2zLJodpaJ3xbj894pE/OJCNC0+4d0Sv7oHhY7QoLYldTQbSgPyhyfl4iZpJf6OEPZxK2cJaB+cbeoBB6aGNyU+CIJToM+uAJJ7H7EpvxfcnfJQ1PuY5szTdvFbW820euiUEKEW69mW4uaFNPSc6D4Z8tZ5hXQIqBD40irULhF0CYNkIILmyNV/KJIZ5HkbQ1q+UrCFHJyvuH/3aCTjj9OSfE7xHPQ3xd3Xw8vvj0Mjie09xFbbcklBTw5WRzH7cw8c+Q0O69kZZ8b+ykcdzWTeZeWNdnzptNqnMjfheig90rUIJ7DN0c+53jCUcGpWJxJhcYF9Uk1RNHmSE5+VzK1y+20t0grVFX90nApm4Tl35QPrX7Qxp9C81cWiUB8xCAE6jYrmd4x+P/3wSQfc1Xg0Eg3QjJB+6JD7cbyDJpzDR3ja+CLZCAr9I0B4rDKD2d6et/z67iXPnZUWMyZ8RVVZPFbBMOTw== openpgp:0xF727046D")

(define users
  `(((#:username . "andreh")
     (#:extra-groups . ("wheel"))
     (#:public-keys . (,andreh-pk)))))

(define user-accounts
  (map (lambda (user)
         (let ((name (assoc-ref user #:username))
               (groups (or (assoc-ref user #:extra-groups) '())))
           (user-account
             (name name)
             (comment name)
             (group "users")
             (supplementary-groups groups))))
       users))

(define authorized-keys
  (map (lambda (user)
         (let* ((name (assoc-ref user #:username))
                (pk-strs (assoc-ref user #:public-keys))
                (pk-files (map (cut plain-file "id_rsa.pub" <>) pk-strs)))
           `(,name . ,pk-files)))
       users))


(define toph
  (operating-system
    (locale "fr_FR.utf8")
    (timezone "America/Sao_Paulo")
    (host-name "toph")
    (users (append user-accounts %base-user-accounts))
    (sudoers-file (plain-file "sudoers" #"""-
                    root ALL=(ALL) ALL
                    %wheel ALL=NOPASSWD: ALL
                    """#))
    (packages
      (append (map (compose list specification->package+output symbol->string)
                   '(nss-certs    ; required for guix pull
                     git-minimal
                     borg))
              %base-packages))
    (services
      (append
       (list
        (service openssh-service-type
          (openssh-configuration
            (port-number 38123)
            (openssh openssh-sans-x)
            (password-authentication? #f)
            (subsystems '())
            (log-level 'verbose)
            (authorized-keys authorized-keys)
            (extra-content ssh.conf)))
        (service dhcp-client-service-type)
        (service mcron-service-type
          (mcron-configuration
            (jobs cronjobs)))
        (simple-service 'extra-etc-file etc-service-type
          `(("backup.sh"     ,backup.sh)
            ("profile-extra" ,profile-extra)
            ("bashrc-extra"  ,bashrc-extra)
            ("ps1.sh"        ,ps1.sh)
            ("vi.exrc"       ,vi.exrc)
            ("infokey"       ,infokey)
            ("with-email.sh" ,with-email.sh)))
        (service certbot-service-type
          (certbot-configuration
            (email "eu@euandre.org")
            (certificates
              (list
               (certificate-configuration
                 (domains '("arrobaponto.org"))
                 (deploy-hook
                   (program-file
                    "nginx-deploy-hook"
                    #~(let ((pid (call-with-input-file
                                  "/var/run/nginx/pid"
                                  read)))
                        (kill pid SIGHUP)))))))))
        (service nginx-service-type
          (nginx-configuration
            (run-directory "/var/run/nginx")
            (server-blocks
              (list
               (nginx-server-configuration
                 (server-name '("arrobaponto.org"))
                 (listen '("[::]:443 ssl http2" "443 ssl http2"))
                 (root "/opt/www/arrobaponto.org/static/")
                 (ssl-certificate     "/etc/letsencrypt/live/arrobaponto.org/fullchain.pem")
                 (ssl-certificate-key "/etc/letsencrypt/live/arrobaponto.org/privkey.pem")
                 (raw-content '(#"""-
                                  autoindex on;
                                  add_header Strict-Transport-Security 'max-age=86400; includeSubdomains' always;
                                  """#)))))))
       (service mail-aliases-service-type
         `(("webmaster"  ,admin-user)
           ("abuse"      ,admin-user)
           ("root"       ,admin-user)
           ("postmaster" ,admin-user)))
       (service opensmtpd-service-type
         (opensmtpd-configuration
           (config-file opensmtpd.conf))))
       (modify-services
        %base-services
        (guix-service-type
           config => (guix-configuration
                       (inherit config)
                       (authorized-keys
                         (append
                          (list
                           (local-file "/etc/guix/signing-key.pub"))
                          %default-authorized-guix-keys)))))))
    (bootloader
      (bootloader-configuration
        (bootloader grub-bootloader)
        (targets '("/dev/vda"))))
    (swap-devices
      (list
       (swap-space
         (target (uuid "30122738-f2f6-4f93-a37c-62023f56c73b")))))
    (file-systems
      (append
       (list
        (file-system
          (mount-point "/")
          (device
            (uuid "455682d0-7ce7-4144-9728-a6d07beb049a"
                  'btrfs))
          (type "btrfs")))
       %base-file-systems))))



(list
 (machine
   (operating-system toph)
   (environment managed-host-environment-type)
   (configuration (machine-ssh-configuration
                    (host-name "toph")
                    (system "x86_64-linux")
                    (user admin-user)
                    (port 38123)
                    (host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILoz1gFl6chY91vQ5SrZXSP5yHqRI3TdYy2ccEDpS7Z4")))))

;; toph     -> euandre.org
;; kuvira   -> euandreh.xyz
;; ???      -> arrobaponto.org
;; asami    -> discussions.site
;; zhu-li   -> mediator.ht
;; lily     -> hinarioespirita.org  ; musician
;; kyoshi   -> standardify.sh       ; standardtized warriors
;; suyin    -> rsync.net            ; city with a metal shell
;; ???      -> amber.ht
;; yangchen -> multipatch.xyz
;; mai      -> mailbug.xyz