summaryrefslogtreecommitdiff
path: root/playbooks.d/vpn-wireguard/playbook.bash
diff options
context:
space:
mode:
Diffstat (limited to 'playbooks.d/vpn-wireguard/playbook.bash')
-rw-r--r--playbooks.d/vpn-wireguard/playbook.bash119
1 files changed, 119 insertions, 0 deletions
diff --git a/playbooks.d/vpn-wireguard/playbook.bash b/playbooks.d/vpn-wireguard/playbook.bash
new file mode 100644
index 0000000..734761d
--- /dev/null
+++ b/playbooks.d/vpn-wireguard/playbook.bash
@@ -0,0 +1,119 @@
+#!/usr/bin/env bash
+
+# shellcheck disable=SC2034
+
+BASHTARD_PLAYBOOK_VARS[$BASHTARD_PLAYBOOK.endpoint]="required"
+BASHTARD_PLAYBOOK_VARS[$BASHTARD_PLAYBOOK.ipv4]="required"
+BASHTARD_PLAYBOOK_VARS[$BASHTARD_PLAYBOOK.ipv6]="required"
+
+playbook_add() {
+ local data
+ local interface
+
+ data="$(playbook_path "data")"
+ interface="$(config "$BASHTARD_PLAYBOOK.interface" "wg0")"
+
+ pkg install wireguard
+
+ # If there's no data directory yet, make it with a proper gitignore to ensure
+ # the private key is not included
+ if [[ ! -d "$data" ]]
+ then
+ mkdir -pv -- "$data" "$data/hooks" "$data/peers"
+ cat <<-EOF >> "$data/.gitignore"
+ privkey
+ EOF
+ fi
+
+ # Generate the private key for this machine
+ ( umask 077 && wg genkey > "$data/privkey" )
+
+ # Generate the peerfile for this machine
+ file_template "peer" \
+ endpoint="$(config "$BASHTARD_PLAYBOOK.endpoint")" \
+ ipv4="$(config "$BASHTARD_PLAYBOOK.ipv4")" \
+ ipv6="$(config "$BASHTARD_PLAYBOOK.ipv6")" \
+ keepalive="$(config "$BASHTARD_PLAYBOOK.keepalive" "0")" \
+ port="$(config "$BASHTARD_PLAYBOOK.port" "51820")" \
+ pubkey="$(wg pubkey < "$data/privkey")" \
+ > "$data/peers/${BASHTARD_PLATFORM[fqdn]}"
+
+ # Run the sync stage to make sure all the configuration files are written as
+ # desired
+ playbook_sync
+
+ # Enable the wireguard interface
+ info "$BASHTARD_PLAYBOOK" "Enabling wireguard interface $interface"
+ systemctl enable --now "wg-quick@$interface.service"
+}
+
+playbook_sync() {
+ local data
+ local wgconf
+ local interface
+ local hash
+
+ data="$(playbook_path "data")"
+ interface="$(config "$BASHTARD_PLAYBOOK.interface" "wg0")"
+ wgconf="$(config "fs.etcdir")/wireguard/$interface.conf"
+ hash="$(file_hash "$wgconf")"
+
+ # Create the wireguard config directory
+ mkdir -pv "$(config "fs.etcdir")/wireguard"
+
+ info "$BASHTARD_PLAYBOOK" "Generating wireguard configuration at $wgconf"
+
+ # Write the Interface section
+ file_template "interface" \
+ ipv4="$(config "$BASHTARD_PLAYBOOK.ipv4")" \
+ ipv6="$(config "$BASHTARD_PLAYBOOK.ipv6")" \
+ port="$(config "$BASHTARD_PLAYBOOK.port" "51820")" \
+ privkey="$(cat "$data/privkey")" \
+ > "$wgconf"
+
+ if [[ -f "$data/hooks/post-up" ]]
+ then
+ printf "PostUp = %s\n" "$data/hooks/post-up" >> "$wgconf"
+ fi
+
+ if [[ -f "$data/hooks/pre-down" ]]
+ then
+ printf "PreDown = %s\n" "$data/hooks/pre-down" >> "$wgconf"
+ fi
+
+ # Include peerfiles for all other machines
+ for path in "$data/peers"/*
+ do
+ local peer="$(basename "$path")"
+
+ # Skip the machine itself, as it needs not peer with itself
+ [[ "$peer" == "${BASHTARD_PLATFORM[fqdn]}" ]] && continue
+
+ # Append peerfile, but add a newline in there to make the
+ # resulting configuration file a little nicer
+ printf "\n" >> "$wgconf"
+ cat "$path" >> "$wgconf"
+ done
+
+ # Don't continue here if this was just part of the add invocation
+ [[ "$BASHTARD_COMMAND" == "add" ]] && return
+
+ # Nothing left to do if the Wireguard configs are the same
+ [[ "$hash" == "$(file_hash "$wgconf")" ]] && return
+
+ # Refresh the wireguard interface
+ # A simple reload seems to not discover newly added peers
+ info "$BASHTARD_PLAYBOOK" "Reloading wireguard interface $interface"
+ systemctl restart "wg-quick@$interface.service"
+}
+
+playbook_del() {
+ local interface
+
+ interface="$(config "$BASHTARD_PLAYBOOK.interface" "wg0")"
+
+ info "$BASHTARD_PLAYBOOK" "Disabling wireguard interface $interface"
+ systemctl disable --now "wg-quick@$interface.service"
+ rm -fv -- "$(config "fs.etcdir")/wireguard/$interface.conf"
+ pkg uninstall wireguard
+}