wagon/back/lib/peer_add

150 lines
5.8 KiB
Plaintext
Raw Normal View History

2022-09-06 20:57:41 -06:00
#!/bin/bash
# FILE: peer_add
2022-09-06 20:57:41 -06:00
# DESCRIPTION: Add a new peer
2022-09-10 16:12:08 -06:00
# USAGE: add remote_ip querystring
2022-09-06 20:57:41 -06:00
# ERRORS:
# 3: bad args/usage
# 4: vars file not found
# 5: Wireguard not installed
# 6: Hostname in use
# 7: Hostname too short
# 8: Invalid token
# 9: Token file not found
# 10: Failed to get peer data from wg
2022-09-08 14:39:59 -06:00
# 11: Failed to generate new IPs
2022-09-06 20:57:41 -06:00
# 12: Servers file doesn't exist
# 15: Failed to add user to local wireguard
# 16: Failed to add user to federated server
2022-09-08 21:15:30 -06:00
# 17: User not found
2022-09-06 20:57:41 -06:00
CONFIG_FILE='/etc/wgapi/config'
SERVERS_FILE='/etc/wgapi/servers'
2022-09-10 16:12:08 -06:00
if ! [ ${#} -eq 2 ]; then
printf 'ERROR! Bad input: %s %s\n' "${0}" "${*}" >>"${LOGFILE}"
exit 3
2022-09-13 12:07:05 -06:00
fi & if ! [ -x '/usr/bin/wg' ]; then
2022-09-10 16:12:08 -06:00
printf 'ERROR! %s could not find /usr/bin/wg\n' "${0}" >>"${LOGFILE}"
exit 5
2022-09-13 12:07:05 -06:00
fi & if ! [ -f "${CONFIG_FILE}" ]; then
2022-09-10 16:12:08 -06:00
printf 'ERROR! %s could not find %s!\n' "${0}" "${CONFIG_FILE}" >>"${LOGFILE}"
exit 4
fi
2022-09-06 20:57:41 -06:00
source "${CONFIG_FILE}"
2022-09-10 16:12:08 -06:00
if ! [ -f "${SERVERS_FILE}" ]; then
printf 'ERROR! %s could not find %s!\n' "${0}" "${SERVERS_FILE}" >>"${LOGFILE}"
exit 12
2022-09-13 12:07:05 -06:00
fi & if ! [ -f "${TOKENS_FILE}" ]; then
2022-09-10 16:12:08 -06:00
printf 'ERROR! %s could not find %s!\n' "${0}" "${TOKENS_FILE}" >>"${LOGFILE}"
exit 9
fi
2022-09-08 14:04:01 -06:00
ip="${1}"
2022-09-08 21:15:30 -06:00
qs="$(<<<"${2}" tr '&' '\n' | sed 's/?//')"
2022-09-06 20:57:41 -06:00
# Check hostname
2022-09-09 21:56:25 -06:00
hostname="$(<<<"${qs}" grep -oP 'name=(.*)' | sed 's/^name//' | xargs | tr -dc 'a-z0-9' | head -c10)"
2022-09-08 21:15:30 -06:00
printf '%s requested new peer with hostname %s\n' "${ip}" "${hostname}" >>"${LOGFILE}"
2022-09-10 14:44:10 -06:00
if ! [[ ${#hostname} -ge 3 ]]; then
2022-09-08 21:15:30 -06:00
printf 'Rejecting hostname %s because it is too short.\n' "${hostname}" >>"${LOGFILE}"
2022-09-08 14:04:01 -06:00
printf 'Hostname too short\n' | "${LIB_DIR}/http_res" 400
2022-09-06 20:57:41 -06:00
exit 7
2022-09-10 14:44:10 -06:00
fi
2022-09-06 20:57:41 -06:00
2022-09-08 14:04:01 -06:00
# Check token
token_fail(){
2022-09-08 21:15:30 -06:00
printf 'Rejecting %s request for new peer due to %s token\n' "${ip}" "${1}" >>"${LOGFILE}"
2022-09-08 14:04:01 -06:00
printf 'Invalid token\n' | "${LIB_DIR}/http_res" 403
exit 8
2022-09-11 17:01:50 -06:00
}
2022-09-08 21:15:30 -06:00
saved_token="$(grep "${ip}" "${TOKENS_FILE}" | cut -f2)"
2022-09-11 17:01:50 -06:00
[ "${saved_token}" == "" ] && token_fail 'missing' &
2022-09-10 14:29:37 -06:00
<<<"${qs}" grep -qx "t=${saved_token}" || token_fail 'mismatched'
2022-09-09 22:19:57 -06:00
printf '%s token was valid\n' "${ip}" >>"${LOGFILE}"
2022-09-08 14:04:01 -06:00
# Check user
2022-09-13 11:19:05 -06:00
username="$("${LIB_DIR}/ns_lookup_rdns" "${ip}" | cut -d'.' -f2)" || (
printf 'User not found for %s\n' "${ip}" >>"${LOGFILE}"
2022-09-09 21:56:25 -06:00
printf 'User not found' | "${LIB_DIR}/http_res" 403
2022-09-09 20:04:53 -06:00
exit 17
)
2022-09-10 14:29:37 -06:00
printf '%s identified as %s\n' "${ip}" "${username}" >>"${LOGFILE}"
2022-09-08 14:04:01 -06:00
domain="${hostname}.${username}.${TLD}"
2022-09-06 20:57:41 -06:00
# Check if new peer already exists
2022-09-10 14:51:22 -06:00
if "${LIB_DIR}/ns_lookup_send" "${domain}" >/dev/null; then
2022-09-08 21:15:30 -06:00
printf '%s.%s.%s already exists!\n' "${hostname}" "${username}" "${TLD}" >>"${LOGFILE}"
printf 'Hostname %s already exists!\n' "${hostname}" | "${LIB_DIR}/http_res" 409
2022-09-06 20:57:41 -06:00
exit 6
2022-09-10 14:44:10 -06:00
fi
# Create new domain
2022-09-09 22:19:57 -06:00
domain="${hostname:?}.${username:?}.${TLD:?}"
2022-09-09 22:28:48 -06:00
printf 'New domain will be %s\n' "${domain}" >>"${LOGFILE}"
2022-09-06 20:57:41 -06:00
2022-09-08 14:04:01 -06:00
# Create new IPs
2022-09-13 12:07:05 -06:00
if ! peers="$("${LIB_DIR}/wg_peer_list" "${ip}" tsv)"; then
printf 'ERROR! Failed to retrieve peers for %s!\n' "${ip}" >>"${LOGFILE}"
exit 10
fi
2022-09-09 21:56:25 -06:00
hostnames="$(<<<"${peers}" awk '{print $1}' | cut -d'.' -f1)"
ipv4s="$(<<<"${peers}" awk '{print $2}')"
ipv6s="$(<<<"${peers}" awk '{print $3}')"
2022-09-13 12:07:05 -06:00
usernumber="$(<<<"${ipv4s}" head -n1 | cut -d'.' -f3)"
2022-09-09 22:06:48 -06:00
# Increment hostnumber from 1 until an unused one is found
used_hostnumbers="$(<<<"${ipv4s}" cut -d'.' -f4 | sort | uniq)"
2022-09-10 14:29:37 -06:00
hostnumber=1; while <<<"${used_hostnumbers}" grep -q "${hostnumber}"
2022-09-09 21:29:59 -06:00
do ((hostnumber++))
2022-09-06 20:57:41 -06:00
done
ipv4="${IPV4_NET%.*.*}.${usernumber}.${hostnumber}"
ipv6="${IPV6_NET%:*:*}:${usernumber}:${hostnumber}"
2022-09-10 16:12:08 -06:00
if ! printf 'IP addresses for %s created: %s %s\n' "${domain:?}" "${ipv4:?}" "${ipv6:?}" \
>>"${LOGFILE}"; then
2022-09-09 22:28:48 -06:00
printf 'ERROR! Failed to create IP addresses for %s!' "${domain}" >>"${LOGFILE}"
exit 11
2022-09-10 16:12:08 -06:00
fi
2022-09-06 20:57:41 -06:00
# Create wg config
privkey="$(/usr/bin/wg genkey)"
2022-09-08 21:15:30 -06:00
pubkey="$(echo "${privkey}" | /usr/bin/wg pubkey)"
2022-09-06 20:57:41 -06:00
address="${ipv4}/${IPV4_NET##*/},${ipv6}/${IPV6_NET##*/}"
2022-09-11 15:38:26 -06:00
# 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
# Do the wireguard and tell the user
server_blocks=''
while IFS=$'\t' read -r server_hostname server_ipv4 server_ipv6 server_pubkey server_endpoint server_admin server_secret; do
[[ ${server_hostname:0:1} = \# ]] && continue
2022-09-06 20:57:41 -06:00
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}" ]; then
2022-09-06 20:57:41 -06:00
# Add new user to local server
if "${LIB_DIR}/wg_peer_add" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128"; then
printf 'Added %s to local wireguard server.\n' "${domain}" >>"${LOGFILE}"
else
printf 'ERROR! Failed to add %s to local wireguard server!\n' "${domain}" >>"${LOGFILE}"
# TODO: clear existing progress
exit 15
fi
# TODO: Send new user config to federated server
#else
# if "${LIB_DIR}/fed_peer_add" "${server_admin}" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128" "${server_secret}"; then
# printf 'Sent %s to remote wireguard server %s.\n' "${domain}" "${server_hostname}" >>"${LOGFILE}"
#else
# printf 'ERROR! Failed to send %s to remote wireguard server %s!\n' "${domain}" "${server_hostname}" >>"${LOGFILE}"
# # TODO: clear existing progress
# exit 16
#fi
2022-09-06 20:57:41 -06:00
fi
done <"${SERVERS_FILE}"
2022-09-11 18:48:31 -06:00
wg_config="[Interface] # ${hostname}.${username}.${TLD}\nPrivateKey=${privkey:?}\nAddress=${address:?}\n${WG_DNS}\n${server_blocks:?}"
<<<"${wg_config}" "${LIB_DIR}/http_res" 202