Skip to content

Commit a34bc22

Browse files
committed
Provision turing with guix
This places a starting point for Guix experiments on Turing. At present, it configures the following things on Turing: - SSH - nginx with `certbot` - PostgreSQL - nftables blocking everything but SSH It serves to test out fully declarative deployments and in no point aims to replace our Ansible setup. This commit is purely proposed for merge to enable collaboration.
1 parent 4fdd086 commit a34bc22

10 files changed

Lines changed: 222 additions & 0 deletions

File tree

.pre-commit-config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ repos:
1111
- id: end-of-file-fixer
1212
- id: trailing-whitespace
1313
args: [--markdown-linebreak-ext=md]
14+
exclude: ^guix/guix-acl-keys/
1415

1516
- repo: local
1617
hooks:

guix/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# DevOps Area 51
2+
3+
> This directory is a declarative deployment... and part of a system of
4+
> declarative deployments... pay attention to it!
5+
6+
Here we test out declarative deployments using Guix on Turing. It serves mainly
7+
as a playground for ideas.
8+
9+
## Deploying
10+
11+
**Prerequisites**
12+
13+
- Relevant SSH key (see `./ssh-keys/`) in your SSH agent
14+
- Guix packaging ACL key deployed on turing
15+
- This is usually at `/etc/guix/signing-key`. If not, run `guix archive
16+
--generate-key` as root.
17+
- This is needed for the remote Guix instance to accept packages we build
18+
locally.
19+
20+
**Deploying**
21+
22+
```sh
23+
# Optional, but recommended
24+
# guix pull
25+
guix deploy turing.scm
26+
```

guix/guix-acl-keys/jc.pub

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(public-key
2+
(ecc
3+
(curve Ed25519)
4+
(q #4D454A6338DCC455670972224BC70BEB22BA45E5D90010B9982B8BADF3BF1391#)
5+
)
6+
)

guix/guix-acl-keys/lovelace.pub

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
(public-key
2+
(ecc
3+
(curve Ed25519)
4+
(q #C2F473C5A16D14256DC6CBE78DB3F2D782B7723AECCCBCB123BE84DB110BF348#)
5+
)
6+
)

guix/ssh-keys/chris-lovelace.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN9bVRTi9UIihz9B2wRpnsyl/1NqXJXuea6aPrH/h+o2 cj@lovelace.box.pydis.wtf

guix/ssh-keys/chris.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFMxOPLzQEOJtBJJ6Od9ucrDUpAFOviqJaUAvoG8NzyM chris@neptune

guix/ssh-keys/jb.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPyNdEOw7tfOHWCM0w2A7UzspnYYpNiF+nak51dcx3d7

guix/ssh-keys/jb2.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBAeclEz5F0yR4ip/cCbsJ6uHdo8QPK5FBPb6aH/e2Fg

guix/ssh-keys/jc.pub

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINoHtDPD+w3rKGW4JVEDXidpRM1UXksC+/cMFgCykQBy jc@turing.box.chrisjl.dev

guix/turing.scm

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
;; Module imports
2+
(use-modules (gnu)
3+
(guix)
4+
(gnu packages databases)
5+
(gnu packages linux)
6+
(gnu packages tmux)
7+
(gnu packages vim)
8+
(gnu services admin)
9+
(gnu services certbot)
10+
(gnu services databases)
11+
(gnu services networking)
12+
(gnu services web))
13+
(use-service-modules networking ssh)
14+
(use-package-modules bootloaders)
15+
16+
;; Getting "unauthorized public key"?
17+
;; your key needs to be in the guix authorized-keys, search for `guix-archive-key`.
18+
;; Add your key there, then:
19+
;; scp -r . turing.box.chrisjl.dev:guix
20+
;; ssh turing.box.chrisjl.dev
21+
;; cd guix
22+
;; vim turing.scm
23+
;; # Delete the `(list (machine ...))` stuff
24+
;; # Add %turing-os
25+
;; # Save
26+
;; sudo guix system reconfigure turing.scm
27+
28+
(define %this-dir (dirname (current-filename)))
29+
30+
(define (file-from-cwd path)
31+
(local-file (string-append %this-dir path)))
32+
33+
(define (ssh-key name)
34+
(file-from-cwd (string-append "/ssh-keys/" name ".pub")))
35+
36+
(define (guix-archive-key name)
37+
(file-from-cwd (string-append "/guix-acl-keys/" name ".pub")))
38+
39+
(define %hidden-service-turing
40+
(simple-service 'hidden-service-turing tor-service-type
41+
(list (tor-onion-service-configuration
42+
(name "turing")
43+
(mapping '((22 "127.0.0.1:22")))))))
44+
45+
(define %certbot-deploy-hook
46+
(program-file
47+
"nginx-deploy-hook"
48+
#~(let ((pid (call-with-input-file "/var/run/nginx/pid" read)))
49+
(kill pid SIGHUP))))
50+
51+
(define (letsencrypt-path hostname filename)
52+
(string-append "/etc/letsencrypt/live/" hostname "/" filename))
53+
54+
(define (letsencrypt-key hostname)
55+
(letsencrypt-path hostname "privkey.pem"))
56+
57+
(define (letsencrypt-cert hostname)
58+
(letsencrypt-path hostname "fullchain.pem"))
59+
60+
(define %services
61+
(append (list (service openssh-service-type
62+
(openssh-configuration
63+
(permit-root-login #f)
64+
(password-authentication? #f)
65+
(authorized-keys `(("cj" ,(ssh-key "chris")
66+
,(ssh-key "chris-lovelace"))
67+
("jc" ,(ssh-key "jc"))
68+
("j" ,(ssh-key "jb")
69+
,(ssh-key "jb2"))))))
70+
(service dhcp-client-service-type)
71+
(service postgresql-service-type
72+
(postgresql-configuration
73+
(postgresql postgresql-16)))
74+
(service tor-service-type)
75+
(service nftables-service-type)
76+
(service ntp-service-type)
77+
%hidden-service-turing
78+
(service nginx-service-type
79+
(nginx-configuration
80+
(server-blocks
81+
(list
82+
(nginx-server-configuration
83+
(listen '("443 ssl http2"))
84+
(server-name '("turing.box.pydis.wtf"))
85+
(ssl-certificate (letsencrypt-cert "turing.box.pydis.wtf"))
86+
(ssl-certificate-key (letsencrypt-key "turing.box.pydis.wtf"))
87+
(root "/var/www/turing.box.pydis.wtf"))))))
88+
; The below is added by the certbot role
89+
; (listen '("80" "[::]:80"))
90+
; (server-name '("turing.box.pydis.wtf"))
91+
; (root "/var/www/owlcorp.uk")
92+
; (locations
93+
; (list
94+
; (nginx-location-configuration
95+
; ; Certbot webroot serving
96+
; (uri "/.well-known")
97+
; (body (list "root /var/www; "))))))))))
98+
;
99+
(service certbot-service-type
100+
(certbot-configuration
101+
(email "ops@owlcorp.uk")
102+
; Do not add certbot configuration to nginx automatically
103+
; XXX: seems broken, report upstream?
104+
; (default-location #f)
105+
(webroot "/var/www")
106+
(certificates
107+
(list
108+
(certificate-configuration
109+
(domains '("turing.box.pydis.wtf"))
110+
(deploy-hook %certbot-deploy-hook))))))
111+
(service unattended-upgrade-service-type)
112+
(simple-service 'resolv-conf etc-service-type
113+
(list `("resolv.conf" ,(plain-file
114+
"resolv.conf"
115+
"nameserver 1.1.1.1 1.0.0.1\n")))))
116+
%base-services))
117+
118+
;; Operating system description
119+
(define %turing-os
120+
(operating-system
121+
(locale "en_GB.utf8")
122+
(timezone "UTC")
123+
(keyboard-layout (keyboard-layout "gb"))
124+
(bootloader (bootloader-configuration
125+
(bootloader grub-bootloader)
126+
(targets '("/dev/vda"))
127+
(keyboard-layout keyboard-layout)))
128+
(file-systems (cons* (file-system
129+
(mount-point "/")
130+
(device "/dev/vda2")
131+
(type "ext4"))
132+
%base-file-systems))
133+
(host-name "u-76")
134+
(users (cons* (user-account
135+
(name "cj")
136+
(comment "Chris")
137+
(group "users")
138+
(home-directory "/home/cj")
139+
(supplementary-groups '("wheel" "netdev" "audio" "video")))
140+
(user-account
141+
(name "jc")
142+
(comment "void")
143+
(group "users")
144+
(home-directory "/home/jc")
145+
(supplementary-groups '("wheel" "netdev" "audio" "video")))
146+
(user-account
147+
(name "j")
148+
(comment "J")
149+
(group "users")
150+
(home-directory "/home/j")
151+
(supplementary-groups '("wheel" "netdev" "audio" "video")))
152+
%base-user-accounts))
153+
(packages (cons* %base-packages))
154+
(sudoers-file (plain-file "sudoers" "root ALL=(ALL) ALL
155+
%wheel ALL=NOPASSWD: ALL
156+
"))
157+
(services (modify-services %services
158+
(guix-service-type config =>
159+
(guix-configuration
160+
(inherit config)
161+
(authorized-keys
162+
(append (list (guix-archive-key "jc")
163+
(guix-archive-key "lovelace"))
164+
%default-authorized-guix-keys))))))))
165+
166+
; local deployments:
167+
; SSHKEY=path/to/key USER=myuser guix deploy turing.scm
168+
; USER is usually implicitly declared somewhere
169+
(list (machine
170+
(operating-system %turing-os)
171+
(environment managed-host-environment-type)
172+
(configuration (machine-ssh-configuration
173+
(host-name "turing.box.chrisjl.dev")
174+
(build-locally? #f)
175+
(system "x86_64-linux")
176+
(host-key "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMvvi6P/G+rZ2qUZ+anluvFQwYM/WFZkERygd9X9+xqU")
177+
(user (getenv "USER"))
178+
(identity (getenv "SSHKEY"))))))

0 commit comments

Comments
 (0)