diff options
Diffstat (limited to 'playbooks.d/vpn-wireguard/playbook.bash')
-rw-r--r-- | playbooks.d/vpn-wireguard/playbook.bash | 119 |
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 +} |