#!/bin/bash # FILE: peer_del # DESCRIPTION: Del a peer # USAGE: del remote_ip querystring # ERRORS: # 3: Bad usage # 4: Missing config # 5: wg not found # 8: Invalid token # 6: Pubkey not in user peer list CONFIG_FILE='/etc/wgapi/config' SERVERS_FILE='/etc/wgapi/servers' if ! [ ${#} -eq 2 ]; then printf 'ERROR! Bad input: %s %s\n' "${0}" "${*}" >>"${LOGFILE}" exit 3 fi; if ! [ -x '/usr/bin/wg' ]; then printf 'ERROR! %s could not find /usr/bin/wg\n' "${0}" >>"${LOGFILE}" exit 5 fi; if ! [ -f "${CONFIG_FILE}" ]; then printf 'ERROR! %s could not find %s!\n' "${0}" "${CONFIG_FILE}" >>"${LOGFILE}" exit 4 fi source "${CONFIG_FILE}" if ! [ -f "${SERVERS_FILE}" ]; then printf 'ERROR! %s could not find %s!\n' "${0}" "${SERVERS_FILE}" >>"${LOGFILE}" exit 4 fi; if ! [ -f "${TOKENS_FILE}" ]; then printf 'ERROR! %s could not find %s!\n' "${0}" "${TOKENS_FILE}" >>"${LOGFILE}" exit 4 fi ip="${1}" qs="$(<<<"${2}" tr '&' '\n' | sed 's/?//')" # Parse pubkey pubkey="$(<<<"${qs#}" grep 'pubkey=' | sed 's/pubkey=//')" printf '%s requested to delete %s\n' "${ip}" "${pubkey}" >>"${LOGFILE}" # Check token token_fail(){ printf 'Rejecting %s request for new peer due to %s token\n' "${ip}" "${1}" >>"${LOGFILE}" printf 'Invalid token\n' | "${LIB_DIR}/http_res" 403 exit 8 } saved_token="$(grep "${ip}" "${TOKENS_FILE}" | cut -f2)" [ "${saved_token}" == "" ] && token_fail 'missing' <<<"${qs}" grep -qx "t=${saved_token}" || token_fail 'mismatched' printf '%s token was valid\n' "${ip}" >>"${LOGFILE}" # Get peer if ! peer="$("${LIB_DIR}/wg_peer_list" "${ip}" 'tsv' | grep "${pubkey}")"; then printf 'ERROR! Peer %s not found for user %s!\n' "${pubkey}" "${ip}" >>"${LOGFILE}" & printf 'Peer not found\n' | "${LIB_DIR}/http_res" 404 exit 6 fi domain="$(<<<"${peer}" cut -f1)" ipv4="$(<<<"${peer}" cut -f2)" ipv6="$(<<<"${peer}" cut -f3)" if ! printf 'Delete request was for %s %s %s\n' "${domain:?}" "${ipv4:?}" "${ipv6:?}" >>"${LOGFILE}"; then printf 'ERROR! Failed to collect peer data: %s %s %s\n' "${domain}" "${ipv4}" "${ipv6}" >>"${LOGFILE}" & printf 'Failed to collect peer data\n' | "${LIB_DIR}/http_res" 500 exit 6 fi hostname="$(<<<"${domain}" cut -d'.' -f1)" username="$(<<<"${domain}" cut -d'.' -f2)" # Wireguard # Run this function in parallel in the while loop below # https://stackoverflow.com/a/33058618 for_server_do() { [[ ${server_hostname:0:1} = \# ]] && return # Ignore comments server_hostname="${1}"; server_ipv4="${2}"; server_ipv6="${3}"; server_pubkey="${4}" server_endpoint="${5}"; server_admin="${6}"; server_secret="${7}" if [ "${server_hostname}" == "${LOCAL_SERVER}" ]; then if "${LIB_DIR}/wg_peer_del" "${pubkey}"; then printf 'Deleted %s from local wireguard server.\n' "${domain}" >>"${LOGFILE}" else printf 'ERROR! Failed to delete %s from local wireguard server!\n' "${domain}" >>"${LOGFILE}" # TODO: Send a 500 error # TODO: clear existing progress exit 15 fi # TODO Add federated peer #else # if "${LIB_DIR}/fed_peer_add" "${server_admin}" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128" "${server_secret}"; then # printf 'Deleted %s from remote wireguard server %s.\n' "${domain}" "${server_hostname}" >>"${LOGFILE}" # else # printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >>"${LOGFILE}" # # TODO: Send a 500 error # # TODO: clear existing progress # exit 16 # fi"${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}" "${server_secret}" fi }; while IFS=$'\t' read -r server_hostname server_ipv4 server_ipv6 server_pubkey server_endpoint server_admin server_secret do for_server_do "${server_hostname}" "${server_ipv4}" "${server_ipv6}" "${server_pubkey}" "${server_endpoint}" "${server_admin}" "${server_secret}" & # Uncomment if SERVERS_FILE is very big #[ $( jobs | wc -l ) -ge $( nproc ) ] && wait done <"${SERVERS_FILE}" & # Update nameserver if "${LIB_DIR}/ns_update_del" "${domain:?}" "${ipv4:?}" "${ipv6:?}" then printf 'Successfully deleted %s from DNS server.\n' "${domain}" >>"${LOGFILE}" else printf 'ERROR! Failed to delete %s %s %s from DNS server!\n' "${domain}" "${ipv4}" "${ipv6}" >>"${LOGFILE}" fi & # Create SSL cert if "${LIB_DIR}/ssl_peer_del" "${hostname:?}" "${username:?}" then printf 'Successfully deleted SSL certs for %s\n' "${domain}" >>"${LOGFILE}" else printf 'ERROR! Failed to delete certs for %s!\n' "${domain}" >>"${LOGFILE}" fi # Respond to user # Do it before updating nameserver and certs because # if wireguard worked, there's no going back. The admin # can clean up missing records and certs after checking the logs printf 'Deleted %s.%s.%s' "${hostname}" "${username}" "${TLD}" | "${LIB_DIR}/http_res" 202