diff --git a/back/lib/peer_add b/back/lib/peer_add index b87b02c..795da33 100755 --- a/back/lib/peer_add +++ b/back/lib/peer_add @@ -54,7 +54,7 @@ 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' @@ -104,9 +104,13 @@ privkey="$(/usr/bin/wg genkey)" pubkey="$(echo "${privkey}" | /usr/bin/wg pubkey)" address="${ipv4}/${IPV4_NET##*/},${ipv6}/${IPV6_NET##*/}" server_blocks='' -# TODO: Do this loop in parallel -while IFS=$'\t' read -r server_hostname server_ipv4 server_ipv6 server_pubkey server_endpoint server_admin server_secret; do + +# Run this function in parallel in the while loop below +# https://stackoverflow.com/a/33058618 +for_server_do() { [[ ${server_hostname:0:1} = \# ]] && continue # Ignore comments + server_hostname="${1}"; server_ipv4="${2}"; server_ipv6="${3}"; server_pubkey="${4}" + server_endpoint="${5}"; server_admin="${6}"; server_secret="${7}" server_psk="$(/usr/bin/wg genpsk)" server_blocks="${server_blocks}\n[Peer] # ${server_hostname}.${TLD}\nPublicKey=${server_pubkey}\nPresharedKey=${server_psk}\nAllowedIPs=${server_ipv4}/32,${server_ipv6}/128\nEndpoint=${server_endpoint}\n" if [ "${server_hostname}" == "${LOCAL_SERVER}" ] @@ -130,6 +134,24 @@ while IFS=$'\t' read -r server_hostname server_ipv4 server_ipv6 server_pubkey se # exit 16 #fi fi +} + +# Update nameserver +if "${LIB_DIR}/ns_update_add" "${domain}" "${ipv4}" "${ipv6}" + then printf 'Successfully added %s to DNS server.\n' "${domain}" >>"${LOGFILE}" + else printf 'ERROR! Failed to add %s %s %s to DNS server!\n' "${domain}" "${ipv4}" "${ipv6}" >>"${LOGFILE}" +fi & + +# Create SSL cert +if "${LIB_DIR}/ssl_peer_add" "${hostname}" "${username}" "IP:${ipv4},IP:${ipv6}" + then printf 'Successfully signed SSL certs for %s\n' "${domain}" >>"${LOGFILE}" + else printf 'ERROR! Failed to create certs for %s with IPS: %s %s!\n' "${domain}" "${ipv4}" "${ipv6}" >>"${LOGFILE}" +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}" wg_config="[Interface] # ${hostname}.${username}.${TLD}\nPrivateKey=${privkey}\nAddress=${address}\n${WG_DNS}\n${server_blocks}" @@ -137,16 +159,4 @@ wg_config="[Interface] # ${hostname}.${username}.${TLD}\nPrivateKey=${privkey}\n # 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 -<<<"${wg_config}" "${LIB_DIR}/http_res" 202 - -# Update nameserver -if "${LIB_DIR}/ns_update_add" "${domain}" "${ipv4}" "${ipv6}" - then printf 'Successfully added %s to DNS server.\n' "${domain}" >>"${LOGFILE}" - else printf 'ERROR! Failed to add %s %s %s to DNS server!\n' "${domain}" "${ipv4}" "${ipv6}" >>"${LOGFILE}" -fi - -# Create SSL cert -if "${LIB_DIR}/ssl_peer_add" "${hostname}" "${username}" "IP:${ipv4},IP:${ipv6}" - then printf 'Successfully signed SSL certs for %s\n' "${domain}" >>"${LOGFILE}" - else printf 'ERROR! Failed to create certs for %s with IPS: %s %s!\n' "${domain}" "${ipv4}" "${ipv6}" >>"${LOGFILE}" -fi +<<<"${wg_config}" "${LIB_DIR}/http_res" 202 \ No newline at end of file diff --git a/back/lib/peer_del b/back/lib/peer_del index 3cf81a1..7a1c3e1 100755 --- a/back/lib/peer_del +++ b/back/lib/peer_del @@ -49,60 +49,66 @@ 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 '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)" +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 '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)" +hostname="$(<<<"${domain}" cut -d'.' -f1)" & username="$(<<<"${domain}" cut -d'.' -f2)" # Wireguard -# TODO: Do this loop in parallel -while IFS=$'\t' read -r server_hostname server_ipv4 server_ipv6 server_pubkey server_endpoint server_admin server_secret; do +# Run this function in parallel in the while loop below +# https://stackoverflow.com/a/33058618 +for_server_do() { [[ ${server_hostname:0:1} = \# ]] && continue # 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 printf 'Deleting %s from local wireguard server... ' "${domain}" >>"${LOGFILE}" if "${LIB_DIR}/wg_peer_del" "${pubkey}"; then printf 'success.\n' >>"${LOGFILE}" else printf 'failed!\n' >>"${LOGFILE}" + # TODO: Send a 500 error # TODO: clear existing progress exit 15 - fi + fi else printf 'Deleting %s from remote wireguard server %s... ' "${domain}" "${server_hostname}" >>"${LOGFILE}" # TODO Add federated peer #if "${LIB_DIR}/fed_peer_add" "${server_admin}" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128" "${server_secret}"; then printf 'success.\n' >>"${LOGFILE}" #else # printf 'failed!\n' >>"${LOGFILE}" + # # TODO: Send a 500 error # # TODO: clear existing progress # exit 16 #fi"${LIB_DIR}/fed_peer_del" "${server_admin}" "${pubkey}" "${server_secret}" fi -done <"${SERVERS_FILE}" - -# 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 +}; 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 +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 \ No newline at end of file diff --git a/back/lib/wg_peer_list b/back/lib/wg_peer_list index 8a5c796..6ffb808 100755 --- a/back/lib/wg_peer_list +++ b/back/lib/wg_peer_list @@ -11,35 +11,46 @@ # 8: wg found no peers CONFIG_FILE='/etc/wgapi/config' -[ -f "${CONFIG_FILE}" ] || ( +if [ -f "${CONFIG_FILE}" ]; then printf 'ERROR! %s Config file not found' "${0}" >>"${LOGFILE}" - exit 6; ) -[ ${#} -eq 2 ] || ( + exit 6 +fi & if [ ${#} -eq 2 ]; then printf 'ERROR! Bad usage: %s %s' "$0" "$*" >>"${LOGFILE}" - exit 3; ) -[ -x /usr/bin/wg ] || ( + exit 3 +fi & if [ -x /usr/bin/wg ]; then printf 'ERROR! %s /usr/bin/wg not found' "${0}" >>"${LOGFILE}" - exit 5; ) - + exit 5 +fi source "${CONFIG_FILE}" -wg_output="$(sudo /usr/bin/wg show "${TLD}" allowed-ips)" || ( + +# Get peer IP list +if ! wg_output="$(sudo /usr/bin/wg show "${TLD}" allowed-ips)"; then printf 'ERROR! Wireguard failed!\n' >>"${LOGFILE}" - exit 5; ) + exit 5 +fi + +# Filter out this user's user_peers="$(grep "${1%[.:]*}" <<<"${wg_output}" 2>/dev/null)" -[ "${user_peers}" == "" ] && ( +if [ "${user_peers}" == "" ]; then printf "ERROR! %s accessed the dashboard but isn't on the network!\n" "${1}" >>"${LOGFILE}" - exit 8; ) -while IFS= read -r line; do # TODO: Do these dns lookups in parallel - pubkey="$(<<<"${line}" cut -d ' ' -f1)" - ips="$(<<<"${line}" cut -d ' ' -f2 | tr ' ' '\n')" - ipv4="$(<<<"${ips}" grep '\.')" - ipv6="$(<<<"${ips}" grep ':')" - ipv4="${ipv4%%/*}" - ipv6="${ipv6%%/*}" - domain="$("${LIB_DIR}/ns_lookup_rdns" "${ipv4}" | xargs)" || exit 4 + exit 8 +fi + +# Loop through each peer in parallel and do an rDNS lookup for the hostnames +do_lookup(){ + pubkey="$(<<<"${1}" cut -d ' ' -f1)" & ips="$(<<<"${1}" cut -d ' ' -f2 | tr ' ' '\n')" + ipv4="$(<<<"${ips}" grep '\.')" & ipv6="$(<<<"${ips}" grep ':')" + ipv4="${ipv4%%/*}" & ipv6="${ipv6%%/*}" + if ! domain="$("${LIB_DIR}/ns_lookup_rdns" "${ipv4}" | xargs)" + then exit 4 + fi case "${2}" in 'json') printf '{"domain":"%s","ipv4":"%s","ipv6":"%s","pubkey":"%s"},' \ "${domain}" "${ipv4}" "${ipv6}" "${pubkey}";; 'tsv') printf '%s\t%s\t%s\t%s\n' "${domain}" "${ipv4}" "${ipv6}" "${pubkey}";; esac -done <<<"${user_peers}" | sed 's/\n//g' | sed 's/,$//' # Remove trailing comma and newline \ No newline at end of file +}; while IFS= read -r line + do do_lookup "${line}" "${2}" & + [ $( jobs | wc -l ) -ge $( nproc ) ] && wait +done <<<"${user_peers}" \ + | sed 's/\n//g' | sed 's/,$//' # Remove trailing comma and newline \ No newline at end of file