From 30b7761bc1dac3f7683383f8c0d5a5bcd4c377ab Mon Sep 17 00:00:00 2001 From: Keith Irwin Date: Sat, 3 Dec 2022 17:57:42 -0700 Subject: [PATCH] Delete from federated wireguard server --- back/lib/admin/peer/del | 19 +++--- back/lib/admin/user/del | 19 +++--- back/lib/dashboard/peer/del | 19 +++--- back/lib/fed/peer/add | 4 +- back/lib/fed/peer/del | 119 +++++------------------------------- back/lib/fed_peer_add | 2 +- back/lib/fed_peer_del | 30 +++++++++ checklist.md | 1 + 8 files changed, 75 insertions(+), 138 deletions(-) create mode 100644 back/lib/fed_peer_del diff --git a/back/lib/admin/peer/del b/back/lib/admin/peer/del index 1ff2986..e656027 100755 --- a/back/lib/admin/peer/del +++ b/back/lib/admin/peer/del @@ -83,6 +83,7 @@ for_server_do() { 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 + # Local server if "${LIB_DIR}/wg_peer_del" "${pubkey}"; then printf 'Deleted %s from local wireguard server.\n' "${domain}" >&2 else @@ -90,16 +91,14 @@ for_server_do() { # TODO: clear existing progress "${LIB_DIR}/http_res" 500; exit 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}" >&2 - # else - # printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 - # # TODO: Send a 500 error - # # TODO: clear existing progress - # exit 16 - # fi"${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}" "${server_secret}" + else + # Federated server + if "${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}"; then + printf 'Deleted %s from remote wireguard server %s.\n' "${domain}" "${server_hostname}" >&2 + else + printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 + "${LIB_DIR}/http_res" 500; exit + fi 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}" & diff --git a/back/lib/admin/user/del b/back/lib/admin/user/del index 6589000..78ab5d6 100755 --- a/back/lib/admin/user/del +++ b/back/lib/admin/user/del @@ -74,6 +74,7 @@ for_server_do() { 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 + # Local server if "${LIB_DIR}/wg_peer_del" "${pubkey}"; then printf 'Deleted %s from local wireguard server.\n' "${domain}" >&2 else @@ -81,16 +82,14 @@ for_server_do() { # TODO: clear existing progress "${LIB_DIR}/http_res" 500; exit fi - # TODO Delete federated peer - #else - # if "${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128" "${server_secret}"; then - # printf 'Deleted %s from remote wireguard server %s.\n' "${domain}" "${server_hostname}" >&2 - # else - # printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 - # # TODO: Send a 500 error - # # TODO: clear existing progress - # exit 16 - # fi"${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}" "${server_secret}" + else + # Federated server + if "${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}"; then + printf 'Deleted %s from remote wireguard server %s.\n' "${domain}" "${server_hostname}" >&2 + else + printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 + "${LIB_DIR}/http_res" 500; exit + fi fi } diff --git a/back/lib/dashboard/peer/del b/back/lib/dashboard/peer/del index e89ee77..d24dc14 100755 --- a/back/lib/dashboard/peer/del +++ b/back/lib/dashboard/peer/del @@ -84,6 +84,7 @@ for_server_do() { 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 + # Local server if "${LIB_DIR}/wg_peer_del" "${pubkey}"; then printf 'Deleted %s from local wireguard server.\n' "${domain}" >&2 else @@ -91,16 +92,14 @@ for_server_do() { # TODO: clear existing progress "${LIB_DIR}/http_res" 500; exit 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}" >&2 - # else - # printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 - # # TODO: Send a 500 error - # # TODO: clear existing progress - # exit 16 - # fi"${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}" "${server_secret}" + else + # Federated server + if "${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}"; then + printf 'Deleted %s from remote wireguard server %s.\n' "${domain}" "${server_hostname}" >&2 + else + printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 + "${LIB_DIR}/http_res" 500; exit + fi 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}" & diff --git a/back/lib/fed/peer/add b/back/lib/fed/peer/add index a70bf12..0e5939e 100755 --- a/back/lib/fed/peer/add +++ b/back/lib/fed/peer/add @@ -30,9 +30,9 @@ fi # Add peer to wireguard if "${LIB_DIR}/wg_peer_add" "${pubkey}" "${server_psk}" "${allowedips}"; then - printf 'Added %s to local wireguard server.\n' "${pubkey}" >&2 + printf 'Added %s to wireguard.\n' "${pubkey}" >&2 else - printf 'ERROR! Failed to add %s to wireguard server!\n' "${pubkey}" >&2 + printf 'ERROR! Failed to add %s to wireguard!\n' "${pubkey}" >&2 "${LIB_DIR}/http_res" 500; exit fi "${LIB_DIR}/http_res" 200 diff --git a/back/lib/fed/peer/del b/back/lib/fed/peer/del index 10ec431..62f0206 100755 --- a/back/lib/fed/peer/del +++ b/back/lib/fed/peer/del @@ -2,7 +2,7 @@ # FILE: fed/peer/del # DESCRIPTION: Delete a peer from a federated server # USAGE: del $remote_ip $querystring -# QUERYSTRING: ?t=$token&pubkey=$pubkey +# QUERYSTRING: ?pubkey=$pubkey CONFIG_FILE='/etc/wgapi/config' SERVERS_FILE='/etc/wgapi/servers' @@ -15,113 +15,22 @@ fi & if ! [ -x '/usr/bin/wg' ]; then fi & if ! [ -f "${CONFIG_FILE}" ]; then printf 'ERROR! %s could not find %s!\n' "${0}" "${CONFIG_FILE}" >&2 "${LIB_DIR}/http_res" 500; exit -fi -source "${CONFIG_FILE}" -if ! [ -f "${SERVERS_FILE}" ]; then - printf 'ERROR! %s could not find %s!\n' "${0}" "${SERVERS_FILE}" >&2 - "${LIB_DIR}/http_res" 500; exit -fi & if ! [ -f "${TOKENS_FILE}" ]; then - printf 'ERROR! %s could not find %s!\n' "${0}" "${TOKENS_FILE}" >&2 - "${LIB_DIR}/http_res" 500; exit -fi +fi; source "${CONFIG_FILE}" ip="${1}" qs="$(<<<"${2}" tr '&' '\n' | sed 's/?//')" +pubkey="$(<<<"${qs}" grep -oP 'pubkey=(.*)' | sed 's/^pubkey//' | xargs)" -# Parse pubkey -pubkey="$(<<<"${qs#}" grep 'pubkey=' | sed 's/pubkey=//')" -printf '%s requested to delete %s\n' "${ip}" "${pubkey:?}" >&2 +# Check that requesting ip is in the servers file +if ! cat "${SERVERS_FILE}" | sed '/^#/d' | cut -f2,3 | grep -w "${ip}"; then + printf "ERROR! Federated server %s requested to create new peer but isn't in servers file!/n" "${ip}" >&2 + "${LIB_DIR}/http_res" 403; exit +fi -# Check token -token_fail(){ - printf 'Rejecting %s request to delete peer due to %s token\n' "${ip}" "${1}" >&2 - printf 'Invalid token\n' | "${LIB_DIR}/http_res" 403; exit -} -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}" >&2 - -# Get peer IP list -if ! wg_output="$(sudo /usr/bin/wg show "${TLD}" allowed-ips)"; then - printf 'ERROR! Wireguard failed!\n' >&2 +# Delete peer from wireguard +if "${LIB_DIR}/wg_peer_del" "${pubkey}"; then + printf 'Deleted %s from wireguard.\n' "${pubkey}" >&2 +else + printf 'ERROR! Failed to delete %s from wireguard!\n' "${pubkey}" >&2 "${LIB_DIR}/http_res" 500; exit fi - -# Filter out this user's -user_peers="$(grep "${ip%[.:]*}" <<<"${wg_output}" 2>/dev/null)" -if [ "${user_peers}" == "" ]; then - printf "ERROR! %s accessed the dashboard but isn't on the network!\n" "${ip}" >&2 - "${LIB_DIR}/http_res" 500; exit -fi - -# Get peer domains -if ! peer="$("${LIB_DIR}/ips_to_peers" tsv <<<"${user_peers}" | grep "${pubkey}")"; then - printf 'ERROR! Peer %s not found for user %s!\n' "${pubkey}" "${ip}" >&2 & - printf 'Peer not found\n' | "${LIB_DIR}/http_res" 404; exit -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:?}" >&2; then - printf 'ERROR! Failed to collect peer data: %s %s %s\n' "${domain}" "${ipv4}" "${ipv6}" >&2 & - "${LIB_DIR}/http_res" 500; exit -fi - -# Make sure user isn't deleting their own peer -if [ "${ip}" == "${ipv4}" ] || [ "${ip}" == "${ipv6}" ]; then - printf 'User requested to delete peer from itself: %s.\n' "${ip}" >&2 - printf 'You cannot delete a peer from itself!' | "${LIB_DIR}/http_res" 400; exit -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}" >&2 - else - printf 'ERROR! Failed to delete %s from local wireguard server!\n' "${domain}" >&2 - # TODO: clear existing progress - "${LIB_DIR}/http_res" 500; exit - 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}" >&2 - # else - # printf 'ERROR! Failed to delete %s from remote wireguard server %s!\n' "${domain}" "${server_hostname}" >&2 - # # 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}" >&2 - else printf 'ERROR! Failed to delete %s %s %s from DNS server!\n' "${domain}" "${ipv4}" "${ipv6}" >&2 -fi & - -# Create SSL cert -if "${LIB_DIR}/ssl_peer_del" "${hostname:?}" "${username:?}" - then printf 'Successfully deleted SSL certs for %s\n' "${domain}" >&2 - else printf 'ERROR! Failed to delete certs for %s!\n' "${domain}" >&2 -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 \ No newline at end of file +"${LIB_DIR}/http_res" 200 \ No newline at end of file diff --git a/back/lib/fed_peer_add b/back/lib/fed_peer_add index 12583c4..2ffebd2 100755 --- a/back/lib/fed_peer_add +++ b/back/lib/fed_peer_add @@ -27,6 +27,6 @@ allowedips="${4}" if res="$(curl --silent --request POST "wg-test-fed.${server}.${TLD}?pubkey=${pubkey}&psk=${psk}&ips=${allowedips}")"; then printf 'Sent peer %s to federated server %s\n' "${pubkey}" "${server}" >&2 else - printf 'ERROR: Failed to send peer to federated server %s: %s\n' "${server}" "${res}" "${res}" >&2 + printf 'ERROR: Failed to send peer to federated server %s: %s\n' "${server}" "${res}" >&2 exit 6 fi \ No newline at end of file diff --git a/back/lib/fed_peer_del b/back/lib/fed_peer_del new file mode 100644 index 0000000..4317927 --- /dev/null +++ b/back/lib/fed_peer_del @@ -0,0 +1,30 @@ +#!/bin/bash +# FILE: fed_peer_del +# DESCRIPTION: Sends details to a federated server about a peer to be deleted +# USAGE: fed_peer_del server pubkey +# ERRORS: +# 3: Bad usage +# 4: Config file not found +# 5: wg binary not found +# 6: curl command failed + +CONFIG_FILE='/etc/wgapi/config' +if ! [ ${#} -eq 4 ]; then + printf '%s Bad usage: %s\n' "${0}" "${*}" >&2 + exit 3 +fi & if [ -f "${CONFIG_FILE}" ]; then + printf 'ERROR: %s could not find config at %s!\n' "${0}" "${CONFIG_FILE}" >&2 + exit 4 +fi & if [ -x /usr/bin/wg ]; then + printf 'ERROR: /usr/bin/wg not found\n' >&2 + exit 5 +fi; source "${CONFIG_FILE}" +server="${1}" +pubkey="${2}" + +if res="$(curl --silent --request DELETE "wg-test-fed.${server}.${TLD}?pubkey=${pubkey}")"; then + printf 'Sent peer %s to federated server %s\n' "${pubkey}" "${server}" >&2 +else + printf 'ERROR: Failed to send peer to federated server %s: %s\n' "${server}" "${res}" >&2 + exit 6 +fi \ No newline at end of file diff --git a/checklist.md b/checklist.md index c933a4c..ae9cde9 100644 --- a/checklist.md +++ b/checklist.md @@ -22,6 +22,7 @@ [X] Remove bash errors [X] Move loging to STDERR [ ] Federated servers +[ ] Remove extraneous checks [ ] shellcheck [ ] Deploy on GF4 [ ] Prepare for IPv4 exhaustion