aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore11
-rw-r--r--Makefile16
-rw-r--r--README.org8
-rwxr-xr-xbatch-export11
-rwxr-xr-xbatch-tangle10
-rw-r--r--config.org200
-rwxr-xr-xrun-install-scripts4
7 files changed, 260 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9372290
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,11 @@
+# tangled config files
+sys/
+
+# tangled scripts
+scripts/
+
+# distrib bundle
+*.tar.xz
+
+# exported pages
+*.html
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..0ed3e43
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,16 @@
+all: tangle
+
+distrib.tar.xz: tangle
+ tar -c . | xz > $@
+
+tangle: config.org
+ ./batch-tangle $^
+
+config.html: config.org
+ ./batch-export $^
+
+install: tangle
+ cp -aiuv sys/* /
+ ./run-install-scripts
+
+.PHONY: all tangle
diff --git a/README.org b/README.org
new file mode 100644
index 0000000..3f226ad
--- /dev/null
+++ b/README.org
@@ -0,0 +1,8 @@
+#+title: Literate server config
+#+author: winter Sparkles
+
+In this repository is a work-in-progress recreation of our main server
+celestine's system and package configuration, using a 'literate' Org-Babel file.
+
+See [[file:config.org]], or run =make config.html= and open config.html in your
+browser.
diff --git a/batch-export b/batch-export
new file mode 100755
index 0000000..8a617c9
--- /dev/null
+++ b/batch-export
@@ -0,0 +1,11 @@
+#!/bin/sh
+# Export files with Org mode
+#
+emacs -q --batch --eval "
+ (progn
+ (require 'ox-html)
+ (setq org-html-htmlize-output-type 'css)
+ (dolist (file command-line-args-left)
+ (with-current-buffer (find-file-noselect file)
+ (org-html-export-to-html))))
+ " "$@"
diff --git a/batch-tangle b/batch-tangle
new file mode 100755
index 0000000..93129da
--- /dev/null
+++ b/batch-tangle
@@ -0,0 +1,10 @@
+#!/bin/sh
+# Tangle files with Org mode
+#
+emacs -Q --batch --eval "
+ (progn
+ (require 'ob-tangle)
+ (dolist (file command-line-args-left)
+ (with-current-buffer (find-file-noselect file)
+ (org-babel-tangle))))
+ " "$@"
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
diff --git a/run-install-scripts b/run-install-scripts
new file mode 100755
index 0000000..7e6b9e1
--- /dev/null
+++ b/run-install-scripts
@@ -0,0 +1,4 @@
+#!/bin/sh
+for f in scripts/*; do
+ "$f"
+done