#!/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 }