aboutsummaryrefslogtreecommitdiff
path: root/config.org
diff options
context:
space:
mode:
authorwinter Sparkles2026-08-04 19:18:37 +0100
committerwinter Sparkles2026-08-04 19:18:37 +0100
commit3c37b1b00f9d345ad1d036c8ef6a04cf633d3f5f (patch)
tree1cc1c64170e6e53c5ccd7615906f94c237ebf80a /config.org
initial commit
Diffstat (limited to 'config.org')
-rw-r--r--config.org200
1 files changed, 200 insertions, 0 deletions
diff --git a/config.org b/config.org
new file mode 100644
index 0000000..c595a17
--- /dev/null
+++ b/config.org
@@ -0,0 +1,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