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
|
#+title: Server configuration
#+author: winter Sparkles
#+property: header-args :mkdirp yes :padline no
This is a work-in-progress recreation of our server's configuration in the form
of a literate Org file, plus a makefile that installs it for you.
To use it, you can run =make && doas make install= on an existing Alpine system
that has (GNU) Emacs installed, or, you can run =make distrib.tar.xz= on some
other system with Emacs, then move the file =distrib.tar.xz= to an Alpine
system, unpack it over there, and run =doas make install=, which doesn't require
Emacs to be available on the target system.
* Package management
** apk repositories
We're using the default CDN mirror (change this if you want a different one):
#+begin_src plain :noweb-ref apk-mirror
http://dl-cdn.alpinelinux.org/alpine
#+end_src
The standard main and community repos for the latest stable release:
#+begin_src conf :tangle sys/etc/apk/repositories :noweb yes
<<apk-mirror>>/latest-stable/main
<<apk-mirror>>/latest-stable/community
#+end_src
Plus, extra ones for community and testing on the edge branch, to allow
installing more software and newer versions of certain packages:
#+begin_src conf :tangle sys/etc/apk/repositories :noweb yes
@community-edge <<apk-mirror>>/edge/community
@testing <<apk-mirror>>/edge/testing
#+end_src
* System utilities
** cron daemon
We're just using the busybox cron daemon, it gets the job done.
#+begin_src shell :tangle scripts/enable-services
rc-update add crond
#+end_src
By default, the system comes with a crontab that executes scripts under
=/etc/periodic/<interval>= every so often.
* Networking
** tinc VPN
TODO
** DNS
#+begin_src conf :tangle sys/etc/resolvconf.conf :exports none
resolv_conf=/etc/resolv.conf
#+end_src
We run a local DNS server, which uses unbound, therefore install and enable
unbound:
#+begin_src conf :tangle sys/etc/apk/world
unbound
unbound-doc
#+end_src
#+begin_src shell :tangle scripts/enable-services :tangle-mode o755 :shebang #!/bin/sh
rc-update add unbound
#+end_src
Point the system resolver at the unbound server (in resolvconf.conf):
#+begin_src conf :tangle sys/etc/resolvconf.conf
name_servers=127.0.0.1
#+end_src
*** Authoritative zone for internal VPN addresses
Since we use [[*tinc VPN][tinc mesh VPN]], all of our machines have internal IP addresses, and
it's nice have them be resolvable by their hostnames.
So there is this zonefile:
#+begin_src zone :tangle sys/etc/unbound/zones/infra.zone
$ORIGIN infra.xn--80andq.net.
$TTL 3600
@ IN SOA celestine.infra.xn--80andq.net. contact.xn--80andq.net. 2026072202 10800 3600 604800 3600
amber.infra.xn--80andq.net. IN AAAA fd8c:4ea1:9a24:1::4
amber.infra.xn--80andq.net. IN A 10.101.1.4
neptunite.infra.xn--80andq.net. IN AAAA fd8c:4ea1:9a24:1::5
neptunite.infra.xn--80andq.net. IN A 10.101.1.5
selenite.infra.xn--80andq.net. IN AAAA fd8c:4ea1:9a24:1::2
selenite.infra.xn--80andq.net. IN A 10.101.1.2
celestine.infra.xn--80andq.net. IN AAAA fd8c:4ea1:9a24:1::1
celestine.infra.xn--80andq.net. IN A 10.101.1.1
ametrine.infra.xn--80andq.net. IN AAAA fd8c:4ea1:9a24:1::3
ametrine.infra.xn--80andq.net. IN A 10.101.1.3
#+end_src
unbound also needs to be told about it:
#+begin_src conf :tangle sys/etc/unbound/unbound.conf.d/authority.conf
auth-zone:
name: infra.xn--80andq.net.
zonefile: /etc/unbound/zones/infra.zone
#+end_src
Finally, resolvconf can be told about it as a 'search domain' so it's possible
to just write the short hostnames:
#+begin_src conf :tangle sys/etc/resolvconf.conf
search_domains=infra.xn--80andq.net
#+end_src
*** More miscellaneous unbound config snippets
**** Be accessible on the appropriate interfaces
Again, this is necessary because we want unbound to be visible to other devices
in the tinc network.
#+begin_src conf :tangle sys/etc/unbound/unbound.conf.d/interfaces.conf
server:
interface: winternet
interface: lo
access-control: 10.101.0.0/16 allow
access-control: 127.0.0.1 allow
#+end_src
**** Recursively resolve upstream zones
Here we're using the 9.9.9.9 public recursive DNS server.
#+begin_src conf :tangle sys/etc/unbound/unbound.conf.d/upstream.conf
forward-zone:
name: "."
forward-addr: 9.9.9.9
#+end_src
**** Rehike
TODO: move this section to the actual section for rehike, whenever we write that
#+begin_src conf :tangle sys/etc/unbound/unbound.conf.d/youtube.conf
server:
local-zone: "youtube.com." redirect
local-data: "youtube.com. A 10.101.1.1"
#+end_src
** TLS certificates
*** Let's Encrypt
Obviously we can't put the full and entire configuration here because it might
let you impersonate us. But! Here are some parts:
We're using certbot because we're lazy, and also the PowerDNS plugin for it so
that we can use it with [[https://servfail.network/][servfail]]:
#+begin_src conf :tangle sys/etc/apk/world
certbot
certbot-dns-pdns@testing
#+end_src
Then, after getting certificates for the first time (consult certbot docs on how
to do that), this script in =/etc/periodic/weekly= makes sure they're renewed as
needed, and informs us when it does so using [[*sendmail-fancy][sendmail-fancy]]:
#+begin_src shell :tangle sys/etc/periodic/weekly/certbot-renew.sh :tangle-mode o755
#!/bin/bash
{
printf "it's that time of the week again...\n\n"
certbot renew
} | sendmail-fancy crond@celestine winter "certbot renew output"
#+end_src
** Email
We use [[https://www.opensmtpd.org/][OpenSMTPD]] as an email server, since it's easy to configure. Plus the
dkimsign filter for it, to allow signing outbound emails with our DKIM key.
#+begin_src conf :tangle sys/etc/apk/world
opensmtpd
opensmtpd-doc
opensmtpd-filter-dkimsign
opensmtpd-filter-dkimsign-doc
#+end_src
TODO: smtpd config and dovecot config
*** sendmail-fancy
Super simple shell script that makes it easier to send emails programmatically:
#+begin_src shell :tangle sys/usr/local/bin/sendmail-fancy
#!/bin/bash
if [ $# -ne 3 ]; then
echo "usage: $0 <sender> <recipient> <subject>" 1>&2
exit 1
fi
{
echo "Subject: $3"
echo "To: $2"
echo "From: $1"
echo "Date: $(date -R)"
echo
cat
} | sendmail -t
#+end_src
|