~bitfehler/bitfehler-ns

d890847f7e4607eafc47e4c8de452f868adacf4d — Conrad Hoffmann 5 months ago
Initial commit
A  => .makeimg.modes +22 -0
@@ 1,22 @@
644 files/etc/apk/repositories
644 files/etc/conf.d/sshd.makeimg.patch
600 files/etc/doas.d/doas.conf
644 files/etc/hostname.makeimg.template
644 files/etc/inittab.makeimg.patch
644 files/etc/knot-resolver/kresd.conf
644 files/etc/knot/knot.conf.makeimg.template
644 files/etc/motd.makeimg.template
644 files/etc/network/interfaces.makeimg.template
644 files/etc/ssh/sshd_config.makeimg.patch
600 files/etc/wireguard/wg0.conf.makeimg.template
644 files/home/conrad/.bash_profile
644 files/home/conrad/.bashrc
644 files/home/conrad/.inputrc
644 files/home/conrad/.ssh/authorized_keys
644 files/root/.ssh/authorized_keys
600 files/root/mdb.makeimg.template
660 files/var/lib/knot/anemos.io.zone.makeimg.template
660 files/var/lib/knot/bitfehler.com.zone.makeimg.template
660 files/var/lib/knot/bitfehler.net.zone.makeimg.template
660 files/var/lib/knot/bitfehler.org.zone.makeimg.template
640 files/var/lib/knot/keys/keys/92af24eece7f8570f712dac98f2f80911266452c.pem.makeimg.template

A  => IMGBUILD +153 -0
@@ 1,153 @@
# The name of this image. Mostly cosmetic, e.g. for output file naming.
imgname=bfy

# Build an Alpine Linux image
target=alpine

# The image format to generate. See also the man page for options.
# Generate raw image with msdos partition table and a single partition
#format="raw 4G msdos ext4"
# Generate xz-compressed tarball
#format="tar xz"
# Generate a directory
#format="dir"
# Custom: the IMGBUILD has to implement setup() and cleanup()
#format="custom"
format="custom"

# Specify config items to be copied over from the host building the image.
#
# Add 'keyring' to install the host's `/etc/apk/keys` on the image. Note that
# apk will always copy the keys used to bootstrap the sytem.
# Add 'mirrorlist' to install the host's `/etc/apk/repositories` file.
# Otherwise the repositories file must be installed manually via files or in
# the provision script.
#
# Default is to not use anything from the host.
# hostconf=""
hostconf=""

# The packages to install
packages="
	alpine-base
	bash
	coreutils
	curl
	doas
	e2fsprogs
	ifupdown-ng
	knot
	knot-resolver
	lmdb-tools
	linux-virt
	openssh
	syslinux
	tzdata
	util-linux
	wireguard-tools
	zstd
"

setup() {
	# Repartition, in case the disk das been reset to a vendor image
	parted -s -- /dev/vda mklabel msdos \
		mkpart primary 2048s 256MiB \
		mkpart primary 256MiB -1s \
		set 1 boot on
	partprobe /dev/vda
	# wait for hotplug events to settle...
	sleep 1 && mdev -sf
	uuidr=$(uuidgen)
	uuidb=$(uuidgen)
	mkfs.ext2 -q -F -U "$uuidb" /dev/vda1 
	mkfs.ext4 -q -F -U "$uuidr" /dev/vda2 
	mount /dev/vda2 "${imgroot}"
	mkdir "${imgroot}/boot"
	mount /dev/vda1 "${imgroot}/boot"
	mkdir "${imgroot}/etc"
	opts=$(findmnt -no OPTIONS /dev/vda2)
	printf "UUID=%s\t/\t%s\t%s\t0 1\n" "${uuidr}" "ext4" "${opts}" > "${imgroot}/etc/fstab"
	# Keep b
	opts=$(findmnt -no OPTIONS /dev/vda1)
	printf "UUID=%s\t/boot\t%s\t%s\t0 2\n" "${uuidb}" "ext2" "${opts},noauto" >> "${imgroot}/etc/fstab"
}

cleanup() {
	umount "${imgroot}/boot"
	umount "${imgroot}"
}

# The provisioning function. It is executed in the context of the new image.
# Files have been copied, patches have been applied, templates have been
# rendered (see the folders in this directory and the makeimg man page).
provision() {
	ln -sf "/etc/zoneinfo/UTC" /etc/localtime
	echo 'root:$6$HeNIeePBsBYda6jt$ete/lsPvVjmR.S8R1Bu/PEMZFMSP5eD.Nc0YNkKPADKdmw2FIuDqnyLo39vm079VZER1ErYObophKXJJv.b7j1' | chpasswd -e

	adduser -g conrad -s /bin/bash -D conrad
	addgroup conrad wheel
	echo 'conrad:$6$3KiaTcELvHqntx8E$uEqAGdUQzTwrVR7/319QgJsbCmZSwjLPF2yUOw2FqWWuoYzs/o8pXXfjzqo/cyfXfLowCmzPsaC7gviYrlGhI/' | chpasswd -e
	# This is needed because the files copied here are owned by root
	chown -R conrad:conrad /home/conrad

	# Set up Knot MDB
	mdb_load /var/lib/knot/keys < /root/mdb
	rm /root/mdb
	chown -R knot:knot /var/lib/knot/

	# Set up bootloader.
	uuid=$(lsblk -rno UUID /dev/vda2)
	sed -e "s|^root=|root=/dev/disk/by-uuid/${uuid}|" -i /etc/update-extlinux.conf
	# This would enable the serial port:
	#sed -e 's|^default_kernel_opts=quiet|default_kernel_opts="quiet console=tty0 console=ttyS0,115200"|' -i /etc/update-extlinux.conf
	#sed -e "s|^serial_port=|serial_port=0|" -i /etc/update-extlinux.conf
	dd bs=440 count=1 conv=notrunc if=/usr/share/syslinux/mbr.bin of="${BLKDEV}"
	extlinux --install /boot
	update-extlinux -v
}

# Performed last as services may have been installed via custom files/commands
#
# ALPINE: for Alpine (open-rc) services, the special syntax
# `<SERVICE>:<RUNLEVEL>` is supported. If the runlevel part is omitted, the
# default runlevel will be used.
services="
	devfs:sysinit
	dmesg:sysinit
	mdev:sysinit
	hwdrivers:sysinit
	modules:boot
	hwclock:boot
	sysctl:boot
	bootmisc:boot
	networking:boot
	hostname:boot
	seedrng:boot
	syslog:boot
	loadkmap:boot
	acpid
	crond
	knotd
	kresd
	sshd
"

# Custom stuff
case "$BF_HOST" in
x)
	hostname="x"
	host_ipv4="81.171.24.121"
	host_ipv6="2001:1af8:4700:a129:a::23"
	host_ipv6_gw="2001:1af8:4700:a129::1"
	;;
y)
	hostname="y"
	host_ipv4="185.17.144.15"
	host_ipv6="2a00:c98:2200:af09:a::23"
	host_ipv6_gw="2a00:c98:2200:af09::1"
	;;
*)
	printf "BF_HOST must be 'x' or 'y' (is '%s')!\n" "$BF_HOST"
	exit 1
	;;
esac

A  => Makefile +49 -0
@@ 1,49 @@
# This Makefile does not _build_ the IMGBUILD, it provides the targets to
# deploy this IMGBUILD to my VPS using Anemos.

# There is two almost identical hosts, x.bitfehler.net and y.bitfehler.net
# This must be set to determine which one to deploy ('x' or 'y').
ifndef BF_HOST
$(error BF_HOST is not set)
endif

# Use this after re-imaging so my ssh config won't interfere
IP_x=81.171.24.121
IP_y=185.17.144.15
INIT_SSH_OPTS=-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
INIT_SSH_TO=root@$(IP_$(BF_HOST))

default: payload.tar.gz

# This file is sourced by Anemos and will set the required env var.
anemos.env:
	test "$(BF_HOST)" = "x" || test "$(BF_HOST)" = "y"
	echo "BF_HOST=$(BF_HOST)" > $@

# Create the Anemos payload: a zipped tarball of the IMGBUILD including the
# revealed secrets.
payload.tar.gz: anemos.env
	makeimg -R anemos-secrets
	tar czf $@ IMGBUILD anemos.env files anemos-secrets keys repositories
	rm -rf anemos-secrets anemos.env

# Used after reprovisioning the server with a Leaseweb Debian image
init: payload.tar.gz
	scp $(INIT_SSH_OPTS) payload.tar.gz anemos_init.conf $(INIT_SSH_TO):
	rm payload.tar.gz
	ssh $(INIT_SSH_OPTS) $(INIT_SSH_TO) env DEBIAN_FRONTEND=noninteractive apt-get -q -y install zstd kexec-tools
	ssh $(INIT_SSH_OPTS) $(INIT_SSH_TO) wget https://git.sr.ht/~bitfehler/anemos-cli/blob/master/anemos
	ssh $(INIT_SSH_OPTS) $(INIT_SSH_TO) chmod +x anemos
	ssh $(INIT_SSH_OPTS) $(INIT_SSH_TO) ./anemos -c anemos_init.conf

# Used for a regular redeploy (i.e. server already running Alpine, ssh set up)
deploy: payload.tar.gz
	scp payload.tar.gz anemos.conf $(BF_HOST):
	rm payload.tar.gz
	# Replace this with an installed version at some point
	ssh $(BF_HOST) wget https://git.sr.ht/~bitfehler/anemos-cli/blob/master/anemos
	ssh $(BF_HOST) chmod +x anemos
	ssh $(BF_HOST) doas mount /boot
	ssh $(BF_HOST) doas ./anemos -c anemos.conf

.PHONY: default init anemos.env payload.tar.gz

A  => README.md +75 -0
@@ 1,75 @@
# bitfehler.net DNS infrastructure

This repository contains the full code (minus the secrets) used to deploy
`x.bitfehler.net` and `y.bitfehler.net`, the authoritative name servers for
bitfehler.net, anemos.io, and a few other zones.

All aspects of the systems are described in code in the form of a
[makeimg][makeimg] _IMGBUILD_. [Anemos][anemos] is used for deployment.
Besides the obvious utility of this repository its main purpose is to serve as
a demo for these projects.

[makeimg]: https://sr.ht/~bitfehler/makeimg
[anemos]: https://sr.ht/~bitfehler/anemos

## How it is being used

A server is redeployed by running e.g. `make BF_HOST=y deploy`. This assumes it
is already running the system as described in this repo.

If one of the servers has to be remotely re-imaged (e.g. because something
broke beyond repair) or a new server is brought in, using the `init` target
instead of `deploy` can achieve the same thing off of a stock Leaseweb Debian
image (they do not offer Alpine).

## How it works

In rough terms, this is what happens:

* `makeimg` is used to reveal all used secrets - these secrets are only
  accessible on my laptop and need to be shipped somehow.
* A tarball is prepared containing the entire _IMGBUILD_ (i.e. the `IMGBUILD`
  file plus additional input files), an Anemos env file, and the secrets
* The tarball and an appropriate Anemos config are sent to the server
* Anemos is "installed" on the server (downloaded, as there are no packages
  yet)
* Anemos is executed on the server

The execution of Anemos will lead to the following events:

* Anemos prepares a special initramfs, based on the Anemos base image but
  including the prepared tarball (the payload in Anemos terms)
* Anemos reboots the server into the prepared initramfs
* The initramfs executes `makeimg`, bootstrapping a system exactly as described
  in the _IMGBUILD_
* The server is rebooted one more time, booting into the newly deployed system

## What is notable about this?

### Entire system defined in code

The system description includes low-level details like disk partitioning, file
systems, and boot loader setup. These things can be changed because the deploy
is performed by an initramfs.

### Secrets

In this case, the secrets are resolved on the workstation triggering the deploy
and then transferred to the server with the _IMGBUILD_. In larger environments
that feature network-based secrets management systems, this step could be
performed on the host itself.

### Network usage

A deployment requires relatively little bandwidth for the client triggering it.
Only the _IMGBUILD_ definition has to transferred to the server. All the
packages are then pulled from the server, which presumably has a decent
connection.

### Shit can blow up 

It might be obvious, but still worth pointing out: this method of deployment
provides ample opportunity to render a system unbootable. You should not
attempt this on systems unless you have some means to restore an unbootable
system, e.g. physical access, recovery systems, or vendor-supplied remote
re-imaging.

A  => anemos.conf +63 -0
@@ 1,63 @@
#!/hint/sh
#
# Anemos config to use after the server was re-imaged with a Leasweb Debian

# Kernel and base initramfs
#
# The URL is fetched with curl(1). Can be e.g. "http://", "file://", etc.
ANEMOS_INITRAMFS_URL="https://anemos.io/initramfs/master/initramfs-anemos"
ANEMOS_KERNEL_URL="https://anemos.io/initramfs/master/vmlinuz-anemos"

# Network configuration for the initramfs
#
# Must be a valid Alpine network configuration, see
# https://wiki.alpinelinux.org/wiki/Configure_Networking#Interface_Configuration
# Debian-style (interfaces.d/*, etc) is not supported.
# Default if not specified: dhcp on eth0
#ANEMOS_NETWORK_URL="file:///etc/network/interfaces"

# The payload describing the deployment.
#
# Currently only .tar.gz is supported. Can contain either an IMGBUILD or a
# custom script/executable called `deploy` along with other files needed.
# See e.g. https://git.sr.ht/~bitfehler/anemos-demo-payload
ANEMOS_PAYLOAD_URL="file:///home/conrad/payload.tar.gz"

# How to execute the initramfs. Must be either "destructive" or "kexec".
# Destructive means overwriting the system's kernel and initramfs, then
# performing a regular reboot. For kexec, see kexec(8).
#
# NOTE: Alpine does not support kexec unless you have taken specific measures
# to enable it.
ANEMOS_EXEC="destructive"

# If ANEMOS_EXEC is set to "destructive":
#
# Autodetection is planned, but for now the kernel and initramfs to be
# overwritten have to be specified.
#
# This _should_ work for Arch Linux:
#ANEMOS_OVERWRITE_KERNEL="/boot/vmlinuz-virt"
#ANEMOS_OVERWRITE_INITRAMFS="/boot/initramfs-virt"
#
# This _should_ work on a reasonably standard Debian:
#ANEMOS_OVERWRITE_KERNEL="$(cat /proc/cmdline | tr ' ' '\n' | grep BOOT_IMAGE= | cut -c 12-)"
#ANEMOS_OVERWRITE_INITRAMFS="$(echo "${ANEMOS_OVERWRITE_KERNEL}" | sed -e s/vmlinuz/initrd.img/)"
#
# And this _should_ work on a reasonably standard Alpine:
ANEMOS_OVERWRITE_KERNEL="/boot/$(cat /proc/cmdline | tr ' ' '\n' | grep BOOT_IMAGE= | cut -c 12-)"
ANEMOS_OVERWRITE_INITRAMFS="$(echo "${ANEMOS_OVERWRITE_KERNEL}" | sed -e s/vmlinuz/initramfs/)"

# If ANEMOS_EXEC is set to "kexec":
#
# Autodetection is planned, but for now the reboot command has to be specified.
#
# Arch/Debian:
ANEMOS_KEXEC_REBOOT_CMD="systemctl kexec"
#
# Alpine:
#ANEMOS_KEXEC_REBOOT_CMD="rc shutdown && kexec -e"
#
# The default is to use "--reuse-cmdline" but for advanced use cases this can
# be overridden, e.g. with "--append=" or "--command-line="
#ANEMOS_KEXEC_LOAD_ARGS="--append='console=ttyS0,115200'"

A  => anemos_init.conf +63 -0
@@ 1,63 @@
#!/hint/sh
#
# Anemos config to use after the server was re-imaged with a Leasweb Debian

# Kernel and base initramfs
#
# The URL is fetched with curl(1). Can be e.g. "http://", "file://", etc.
ANEMOS_INITRAMFS_URL="https://anemos.io/initramfs/master/initramfs-anemos"
ANEMOS_KERNEL_URL="https://anemos.io/initramfs/master/vmlinuz-anemos"

# Network configuration for the initramfs
#
# Must be a valid Alpine network configuration, see
# https://wiki.alpinelinux.org/wiki/Configure_Networking#Interface_Configuration
# Debian-style (interfaces.d/*, etc) is not supported.
# Default if not specified: dhcp on eth0
#ANEMOS_NETWORK_URL="file:///etc/network/interfaces"

# The payload describing the deployment.
#
# Currently only .tar.gz is supported. Can contain either an IMGBUILD or a
# custom script/executable called `deploy` along with other files needed.
# See e.g. https://git.sr.ht/~bitfehler/anemos-demo-payload
ANEMOS_PAYLOAD_URL="file:///root/payload.tar.gz"

# How to execute the initramfs. Must be either "destructive" or "kexec".
# Destructive means overwriting the system's kernel and initramfs, then
# performing a regular reboot. For kexec, see kexec(8).
#
# NOTE: Alpine does not support kexec unless you have taken specific measures
# to enable it.
ANEMOS_EXEC="kexec"

# If ANEMOS_EXEC is set to "destructive":
#
# Autodetection is planned, but for now the kernel and initramfs to be
# overwritten have to be specified.
#
# This _should_ work for Arch Linux:
#ANEMOS_OVERWRITE_KERNEL="/boot/vmlinuz-virt"
#ANEMOS_OVERWRITE_INITRAMFS="/boot/initramfs-virt"
#
# This _should_ work on a reasonably standard Debian:
#ANEMOS_OVERWRITE_KERNEL="$(cat /proc/cmdline | tr ' ' '\n' | grep BOOT_IMAGE= | cut -c 12-)"
#ANEMOS_OVERWRITE_INITRAMFS="$(echo "${ANEMOS_OVERWRITE_KERNEL}" | sed -e s/vmlinuz/initrd.img/)"
#
# And this _should_ work on a reasonably standard Alpine:
#ANEMOS_OVERWRITE_KERNEL="$(cat /proc/cmdline | tr ' ' '\n' | grep BOOT_IMAGE= | cut -c 12-)"
#ANEMOS_OVERWRITE_INITRAMFS="$(echo "${ANEMOS_OVERWRITE_KERNEL}" | sed -e s/vmlinuz/initramfs/)"

# If ANEMOS_EXEC is set to "kexec":
#
# Autodetection is planned, but for now the reboot command has to be specified.
#
# Arch/Debian:
ANEMOS_KEXEC_REBOOT_CMD="systemctl kexec"
#
# Alpine:
#ANEMOS_KEXEC_REBOOT_CMD="rc shutdown && kexec -e"
#
# The default is to use "--reuse-cmdline" but for advanced use cases this can
# be overridden, e.g. with "--append=" or "--command-line="
#ANEMOS_KEXEC_LOAD_ARGS="--append='console=ttyS0,115200'"

A  => files/etc/apk/repositories +2 -0
@@ 1,2 @@
http://dl-cdn.alpinelinux.org/alpine/v3.17/main
http://dl-cdn.alpinelinux.org/alpine/v3.17/community

A  => files/etc/conf.d/sshd.makeimg.patch +11 -0
@@ 1,11 @@
--- sshd.orig	2023-04-05 22:13:23.438079225 +0200
+++ sshd.new	2023-04-05 22:14:10.514127969 +0200
@@ -13,7 +13,7 @@
 #
 # Example: "ed25519 rsa".
 #
-#key_types_to_generate=""
+key_types_to_generate="ed25519"
 
 # The number of bits to use for a generated ECDSA SSH host key.
 # Defaults to 256 bits if not set.

A  => files/etc/doas.d/doas.conf +2 -0
@@ 1,2 @@
permit nopass :wheel
permit nopass root

A  => files/etc/hostname.makeimg.template +1 -0
@@ 1,1 @@
${hostname}

A  => files/etc/inittab.makeimg.patch +11 -0
@@ 1,11 @@
--- inittab.orig	2022-09-05 21:53:04.021100286 +0200
+++ inittab	2022-09-05 21:52:46.877847668 +0200
@@ -13,7 +13,7 @@
 tty6::respawn:/sbin/getty 38400 tty6
 
 # Put a getty on the serial port
-#ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100
+ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100
 
 # Stuff to do for the 3-finger salute
 ::ctrlaltdel:/sbin/reboot

A  => files/etc/knot-resolver/kresd.conf +17 -0
@@ 1,17 @@
-- SPDX-License-Identifier: CC0-1.0
-- vim:syntax=lua:set ts=4 sw=4:
-- Refer to manual: https://knot-resolver.readthedocs.org/en/stable/

-- Network interface configuration
-- Only listen on the internal VPN address
net.listen('10.8.1.1', 53, { kind = 'dns', freebind = true })

-- Load useful modules
modules = {
	'hints > iterate',  -- Allow loading /etc/hosts or custom root hints
	'stats',            -- Track internal statistics
	'predict',          -- Prefetch expiring/frequent records
}

-- Cache size
cache.size = 100 * MB

A  => files/etc/knot/knot.conf.makeimg.template +34 -0
@@ 1,34 @@
# Knot DNS configuration file for bitfehler.net.
# See knot.conf(5) or refer to the server documentation.

server:
    user: knot:knot
    listen: [ ${host_ipv4}@53, ${host_ipv6}@53 ]

log:
  - target: /var/log/knotd.log
    any: info

policy:
  - id: manual
    manual: on
    single-type-signing: on

mod-stats:
  - id: default
    edns-presence: on
    query-type: on

template:
  - id: default
    storage: "/var/lib/knot"
    file: "%s.zone"
    module: mod-stats/default

zone:
  - domain: bitfehler.net
  - domain: bitfehler.org
  - domain: bitfehler.com
  - domain: anemos.io
    dnssec-signing: on
    dnssec-policy: manual

A  => files/etc/motd.makeimg.template +4 -0
@@ 1,4 @@
Welcome to bitfehler!

Build date: $(date -Idate)
Build state: $(makeimg -S build_state)

A  => files/etc/network/interfaces.makeimg.template +22 -0
@@ 1,22 @@
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
iface eth0 inet6 static
        address ${host_ipv6}/64
        gateway ${host_ipv6_gw}
        pre-up echo 0 > /proc/sys/net/ipv6/conf/eth0/accept_ra

auto wg0
iface wg0 inet static
	requires eth0
	use wireguard
	address 10.8.1.1/24
	pre-up echo 1 > /proc/sys/net/ipv4/ip_forward
	post-up iptables -A FORWARD -o eth0 -i wg0 -m conntrack --ctstate NEW -j ACCEPT
	post-up iptables -A FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
	post-up iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
	pre-down iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
	pre-down iptables -D FORWARD -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
	pre-down iptables -D FORWARD -o eth0 -i wg0 -m conntrack --ctstate NEW -j ACCEPT

A  => files/etc/ssh/sshd_config.makeimg.patch +29 -0
@@ 1,29 @@
--- sshd_config.orig	2023-04-05 22:21:22.637752112 +0200
+++ sshd_config.new	2023-04-05 22:23:00.584183987 +0200
@@ -10,7 +10,7 @@
 # possible, but leave them commented.  Uncommented options override the
 # default value.
 
-#Port 22
+Port 23022
 #AddressFamily any
 #ListenAddress 0.0.0.0
 #ListenAddress ::
@@ -29,7 +29,7 @@
 # Authentication:
 
 #LoginGraceTime 2m
-#PermitRootLogin prohibit-password
+PermitRootLogin no
 #StrictModes yes
 #MaxAuthTries 6
 #MaxSessions 10
@@ -54,7 +54,7 @@
 #IgnoreRhosts yes
 
 # To disable tunneled clear text passwords, change to no here!
-#PasswordAuthentication yes
+PasswordAuthentication no
 #PermitEmptyPasswords no
 
 # Change to no to disable s/key passwords

A  => files/etc/wireguard/wg0.conf.makeimg.template +11 -0
@@ 1,11 @@
[Interface]
ListenPort = 51820
PrivateKey = $(makeimg -S +wg_server_key)

[Peer]
PublicKey = 62s+XKUXqbZFGlbmpEWia5NdaXNU4XvXBdi4sUmmnyo=
AllowedIPs = 10.8.1.2/32

[Peer]
PublicKey = YY+5eg9nm0Eg3jRA3ePNjsviQ3kSuN8Qzhbr1qYrlUA=
AllowedIPs = 10.8.1.3/32

A  => files/home/conrad/.bash_profile +5 -0
@@ 1,5 @@
#
# ~/.bash_profile
#

[[ -f ~/.bashrc ]] && . ~/.bashrc

A  => files/home/conrad/.bashrc +21 -0
@@ 1,21 @@
#
# ~/.bashrc
#

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

export HISTCONTROL="ignoreboth:erasedups"
export HISTSIZE=10000
export HISTFILESIZE=200000
shopt -s histappend
export PROMPT_COMMAND="history -a;  $PROMPT_COMMAND"

alias ls='ls --color=auto'
alias gcd='cd "$(git rev-parse --show-toplevel)"'
alias crl='curl -Ss -D - -o /dev/null'

PS1="\[\e[0;32m\]\u\[\e[0m\]@\[\e[0;32m\]\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \$(if [[ \$? == 0 ]]; then echo \"\[\033[0;32m\]\"; else echo \"\[\033[0;31m\]\"; fi)\\$\[\033[00m\]\[\e[1;37m\]\[\e[0m\] "

export PATH="$PATH:/home/conrad/.local/bin"
export EDITOR=vi

A  => files/home/conrad/.inputrc +4 -0
@@ 1,4 @@
"\e[Z": menu-complete
"\e[A": history-search-backward
"\e[B": history-search-forward
"\C-e": forward-search-history

A  => files/home/conrad/.ssh/authorized_keys +1 -0
@@ 1,1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0G3N+8UOKOhCmFt9n4K3/T2OqsV1ucapPe1Qkdl04P

A  => files/root/.ssh/authorized_keys +1 -0
@@ 1,1 @@
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0G3N+8UOKOhCmFt9n4K3/T2OqsV1ucapPe1Qkdl04P

A  => files/root/mdb.makeimg.template +1 -0
@@ 1,1 @@
$(makeimg -S +knot_mdb)

A  => files/var/lib/knot/anemos.io.zone.makeimg.template +13 -0
@@ 1,13 @@
\$TTL 86400
@   IN SOA x.bitfehler.net. hostmaster (
    $(makeimg -S dns_zone_serial)   ; serial
    14400        ; refresh
    1800         ; retry
    604800       ; expire
    86400 )      ; minimum
anemos.io.          	86400	SOA	x.bitfehler.net. hostmaster.anemos.io. 2023000047 14400 1800 604800 86400
anemos.io.          	300	A	213.239.215.47
anemos.io.          	14400	NS	x.bitfehler.net.
anemos.io.          	14400	NS	y.bitfehler.net.
anemos.io.          	300	AAAA	2a01:4f8:a0:84cb:b64:0:178:178
anemos.io.          	14400	CAA	0 issue "letsencrypt.org" 

A  => files/var/lib/knot/bitfehler.com.zone.makeimg.template +16 -0
@@ 1,16 @@
\$TTL 86400
@   IN SOA x.bitfehler.net. hostmaster (
    $(makeimg -S dns_zone_serial)   ; serial
    14400        ; refresh
    1800         ; retry
    604800       ; expire
    86400 )      ; minimum
@                    300    IN A      213.239.215.47
@                    300    IN AAAA   2a01:4f8:a0:84cb:b64:0:178:178
@                    14400  IN CAA    0 issue "letsencrypt.org"
@                    14400  IN NS     x.bitfehler.com.
@                    14400  IN NS     y.bitfehler.com.
x                    14400  IN A      81.171.24.121
x                    14400  IN AAAA   2001:1af8:4700:a129:a::23
y                    14400  IN A      185.17.144.15
y                    14400  IN AAAA   2a00:c98:2200:af09:a::23

A  => files/var/lib/knot/bitfehler.net.zone.makeimg.template +28 -0
@@ 1,28 @@
\$TTL 86400
@   IN SOA x.bitfehler.net. hostmaster (
    $(makeimg -S dns_zone_serial)   ; serial
    14400        ; refresh
    1800         ; retry
    604800       ; expire
    86400 )      ; minimum
@                    14400  IN A      213.239.215.47
@                    14400  IN AAAA   2a01:4f8:a0:84cb:b64:0:178:178
@                    14400  IN CAA    0 issue "letsencrypt.org"
@                    14400  IN MX     10 mx.bitfehler.net.
@                    14400  IN NS     x.bitfehler.net.
@                    14400  IN NS     y.bitfehler.net.
@                    14400  IN TXT    "v=spf1 mx ip4:138.201.162.180/32 ip4:213.239.215.46/32 ip6:2a01:4f8:251:94f:0:74:180:0/112 ip6:2a01:4f8:a0:84cb:b64:0:180:0/112 -all"
_dmarc               14400  IN TXT    "v=DMARC1; p=quarantine; ruf=mailto:dmarc-feedback@bitfehler.net"
default._domainkey   14400  IN TXT    "v=DKIM1; k=rsa; s=email; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnKRYE4BAB84MFdDmlSK6IiocLGrGH38Tg5kZgyhPi1Nl7eGgxKq0o/uqF0l2RwW/Xh5jdpwSI45kYGXGmU/akVAE9EiKz2mDkjyZp5msiAQXdiRE6pu1sdzi3/gRjMCLM8MezE3A1V/FojVK3121JuEh3yRS1udHGlNVICsiwyZ9v40WAMVOj3gHDAAcX0QhXEQiH2+2yrT7FO+sP9UJTaPNgODvnk4en08VXbawp6igquqJcWyLgHBAm98lcgRnOSY9Jg4c9z9vxGRW5VjMwgyafvfgrMu9cV5gE+aL20iuoUxdsK1Qo9e8J36dudu7pFHC53nCIBc0JTDC8z/3QIDAQAB"
_mta-sts             14400  IN TXT    "v=STSv1; id=202204260001;"
mta-sts              14400  IN A      213.239.215.47
mta-sts              14400  IN AAAA   2a01:4f8:a0:84cb:b64:0:178:178
mx                   14400  IN A      213.239.215.46
mx                   14400  IN AAAA   2a01:4f8:a0:84cb:b64:0:180:180
apk                  14400  IN CNAME  bitfehler.net.
ntfy                 14400  IN CNAME  bitfehler.net.
www                  14400  IN A      213.239.215.47
x                    14400  IN A      81.171.24.121
x                    14400  IN AAAA   2001:1af8:4700:a129:a::23
y                    14400  IN A      185.17.144.15
y                    14400  IN AAAA   2a00:c98:2200:af09:a::23

A  => files/var/lib/knot/bitfehler.org.zone.makeimg.template +16 -0
@@ 1,16 @@
\$TTL 86400
@   IN SOA x.bitfehler.net. hostmaster (
    $(makeimg -S dns_zone_serial)   ; serial
    14400        ; refresh
    1800         ; retry
    604800       ; expire
    86400 )      ; minimum
@                    300    IN A      213.239.215.47
@                    300    IN AAAA   2a01:4f8:a0:84cb:b64:0:178:178
@                    14400  IN CAA    0 issue "letsencrypt.org"
@                    14400  IN NS     x.bitfehler.org.
@                    14400  IN NS     y.bitfehler.org.
x                    14400  IN A      81.171.24.121
x                    14400  IN AAAA   2001:1af8:4700:a129:a::23
y                    14400  IN A      185.17.144.15
y                    14400  IN AAAA   2a00:c98:2200:af09:a::23

A  => files/var/lib/knot/keys/keys/92af24eece7f8570f712dac98f2f80911266452c.pem.makeimg.template +1 -0
@@ 1,1 @@
$(makeimg -S +knot_key_92af24e)

A  => keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub +9 -0
@@ 1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1yHJxQgsHQREclQu4Ohe
qxTxd1tHcNnvnQTu/UrTky8wWvgXT+jpveroeWWnzmsYlDI93eLI2ORakxb3gA2O
Q0Ry4ws8vhaxLQGC74uQR5+/yYrLuTKydFzuPaS1dK19qJPXB8GMdmFOijnXX4SA
jixuHLe1WW7kZVtjL7nufvpXkWBGjsfrvskdNA/5MfxAeBbqPgaq0QMEfxMAn6/R
L5kNepi/Vr4S39Xvf2DzWkTLEK8pcnjNkt9/aafhWqFVW7m3HCAII6h/qlQNQKSo
GuH34Q8GsFG30izUENV9avY7hSLq7nggsvknlNBZtFUcmGoQrtx3FmyYsIC8/R+B
ywIDAQAB
-----END PUBLIC KEY-----

A  => keys/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub +9 -0
@@ 1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwlzMkl7b5PBdfMzGdCT0
cGloRr5xGgVmsdq5EtJvFkFAiN8Ac9MCFy/vAFmS8/7ZaGOXoCDWbYVLTLOO2qtX
yHRl+7fJVh2N6qrDDFPmdgCi8NaE+3rITWXGrrQ1spJ0B6HIzTDNEjRKnD4xyg4j
g01FMcJTU6E+V2JBY45CKN9dWr1JDM/nei/Pf0byBJlMp/mSSfjodykmz4Oe13xB
Ca1WTwgFykKYthoLGYrmo+LKIGpMoeEbY1kuUe04UiDe47l6Oggwnl+8XD1MeRWY
sWgj8sF4dTcSfCMavK4zHRFFQbGp/YFJ/Ww6U9lA3Vq0wyEI6MCMQnoSMFwrbgZw
wwIDAQAB
-----END PUBLIC KEY-----

A  => keys/alpine-devel@lists.alpinelinux.org-6165ee59.rsa.pub +14 -0
@@ 1,14 @@
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAutQkua2CAig4VFSJ7v54
ALyu/J1WB3oni7qwCZD3veURw7HxpNAj9hR+S5N/pNeZgubQvJWyaPuQDm7PTs1+
tFGiYNfAsiibX6Rv0wci3M+z2XEVAeR9Vzg6v4qoofDyoTbovn2LztaNEjTkB+oK
tlvpNhg1zhou0jDVYFniEXvzjckxswHVb8cT0OMTKHALyLPrPOJzVtM9C1ew2Nnc
3848xLiApMu3NBk0JqfcS3Bo5Y2b1FRVBvdt+2gFoKZix1MnZdAEZ8xQzL/a0YS5
Hd0wj5+EEKHfOd3A75uPa/WQmA+o0cBFfrzm69QDcSJSwGpzWrD1ScH3AK8nWvoj
v7e9gukK/9yl1b4fQQ00vttwJPSgm9EnfPHLAtgXkRloI27H6/PuLoNvSAMQwuCD
hQRlyGLPBETKkHeodfLoULjhDi1K2gKJTMhtbnUcAA7nEphkMhPWkBpgFdrH+5z4
Lxy+3ek0cqcI7K68EtrffU8jtUj9LFTUC8dERaIBs7NgQ/LfDbDfGh9g6qVj1hZl
k9aaIPTm/xsi8v3u+0qaq7KzIBc9s59JOoA8TlpOaYdVgSQhHHLBaahOuAigH+VI
isbC9vmqsThF2QdDtQt37keuqoda2E6sL7PUvIyVXDRfwX7uMDjlzTxHTymvq2Ck
htBqojBnThmjJQFgZXocHG8CAwEAAQ==
-----END PUBLIC KEY-----

A  => repositories +1 -0
@@ 1,1 @@
files/etc/apk/repositories
\ No newline at end of file

A  => secrets/+knot_key_92af24e +1 -0
@@ 1,1 @@
pass show bitfehler/dns/keys/92af24eece7f8570f712dac98f2f80911266452c.pem

A  => secrets/+knot_mdb +1 -0
@@ 1,1 @@
pass show bitfehler/dns/mdb

A  => secrets/+wg_server_key +1 -0
@@ 1,1 @@
pass show bitfehler/wireguard/server.key

A  => secrets/build_state +3 -0
@@ 1,3 @@
# Not really a secret, but needs to be run before the IMGBUILD
# is packed up into a tarball for deployment
echo "$(git rev-list HEAD --count)-$(git rev-parse --short HEAD)"

A  => secrets/dns_zone_serial +6 -0
@@ 1,6 @@
# Not really a secret, but needs to be run before the IMGBUILD
# is packed up into a tarball for deployment
serial_date=$(git log --format="%cd" --date="format:%Y%m%d" -1 -- files/var/lib/knot)
commit_date=$(git log --format="%cd" --date="format:%Y-%m-%d" -1 -- files/var/lib/knot)
count=$(git log --after="$commit_date 00:00" --oneline -- files/var/lib/knot | wc -l)
printf "%s%02d" "$serial_date" "$count"