wagon/back/srv/dashboard/add

134 lines
5.0 KiB
Plaintext
Raw Normal View History

2022-09-06 20:57:41 -06:00
#!/bin/bash
# FILE: wgapi:back/api/dashboard/add
# DESCRIPTION: Add a new peer
# USAGE: add ip querystring
# 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
# 11: Failed to create new IPs
# 12: Servers file doesn't exist
# 15: Failed to add user to local wireguard
# 16: Failed to add user to federated server
CONFIG_FILE='/etc/wgapi/config'
SERVERS_FILE='/etc/wgapi/servers'
[ ${#} -eq 2 ] || exit 3
[ -f "${CONFIG_FILE}" ] || exit 4
[ -f "${TOKENS_FILE}" ] || exit 9
[ -f "${SERVERS_FILE}" ] || exit 12
source "${CONFIG_FILE}"
2022-09-08 14:04:01 -06:00
ip="${1}"
2022-09-06 20:57:41 -06:00
# Check hostname
hostname="$(printf ${2}\n | jq -r '.name' | xargs | tr -dc '[a-z0-9]' | head -c10)"
2022-09-08 14:04:01 -06:00
printf "${ip} requested new peer with hostname ${hostname}\n" >>"${LOGFILE}"
2022-09-06 20:57:41 -06:00
[[ ${#hostname} -ge 3 ]] || (
2022-09-08 14:04:01 -06:00
printf "Rejecting hostname ${hostname} because it's too short.\n" >>"${LOGFILE}"
printf 'Hostname too short\n' | "${LIB_DIR}/http_res" 400
2022-09-06 20:57:41 -06:00
exit 7
)
2022-09-08 14:04:01 -06:00
# Check token
token_fail(){
printf "Rejecting ${ip} request for new peer due to ${1} token\n" >>"${LOGFILE}"
printf 'Invalid token\n' | "${LIB_DIR}/http_res" 403
exit 8
}
saved_token=$(grep "${1}" "${TOKENS_FILE}" | cut -f2)
[ "${saved_token}" == "" ] && token_fail 'missing'
<<<"${username}" grep "t=${saved_token}" || token_fail 'mismatched'
# Check user
2022-09-06 20:57:41 -06:00
username="$(${LIB_DIR}/ns_lookup_rdns ${REMOTE_ADDR} | cut -d'.' -f2)"
[ $? -ne 0 ] && (
2022-09-08 14:04:01 -06:00
printf "\n" >>"${LOGFILE}"
2022-09-06 20:57:41 -06:00
printf 'User not found' | "${LIB)DIR}/http_res" 403
exit 403
2022-09-08 14:04:01 -06:00
) || printf "${ip} identified as ${username} ${hostname}\n" >>"${LOGFILE}"
domain="${hostname}.${username}.${TLD}"
2022-09-06 20:57:41 -06:00
# Check if new peer already exists
printf "${hostnames}" | grep "${hostname}" && (
2022-09-08 14:04:01 -06:00
printf "${hostname}.${username}.${TLD} already exists, sending 409...\n" >>"${LOGFILE}"
printf "Hostname ${hostname} already exists!\n" | "${LIB_DIR}/http_res" 409
2022-09-06 20:57:41 -06:00
exit 6
)
# Collect/parse existing peer data
2022-09-08 14:04:01 -06:00
# Create new IPs
2022-09-06 20:57:41 -06:00
peers="$(sudo ${LIB_DIR}/wg_peer_list ${1} tsv)"
[ ${?} -ne 0 ] && exit 10
hostnames="$(printf "${peers}" | awk '{print $0}' | cut -d'.' -f1)"
ipv4s="$(printf "${peers}" | awk '{print $1}')"
ipv6s="$(printf "${peers}" | awk '{print $2}')"
usernumber="$(printf ${ipv4s} head -n1 | cut -d'.' -f3)"
used_ips="$(printf ${ipv4s} | cut -d'.' -f3)\n$(printf ${ipv6s} | cut -d'.' -f3)"
used_hostnumbers="$(printf ${used_ipvs} | sort | uniq)"
hostnumber=1
while printf "${used_hostnumbers}" | grep "${hostnumber}"
do hostnumber++
done
ipv4="${IPV4_NET%.*.*}.${usernumber}.${hostnumber}"
ipv6="${IPV6_NET%:*:*}:${usernumber}:${hostnumber}"
2022-09-08 14:04:01 -06:00
printf "IP addresses for ${domain} created:\t${ipv4} ${ipv6} \n" >>"${LOGFILE}"
2022-09-06 20:57:41 -06:00
# TODO: Check it or exit 11
# Create wg config
#TODO Check for /usr/bin/wg binary
privkey="$(/usr/bin/wg genkey)"
pubkey="$(echo $privkey | /usr/bin/wg pubkey)"
address="${ipv4}/${IPV4_NET##*/},${ipv6}/${IPV6_NET##*/}"
server_blocks=''
2022-09-08 14:04:01 -06:00
while read -r -a arr; do
server_hostname="${arr[0]}"
server_ipv4="${arr[1]}"
server_ipv6="${arr[2]}"
server_pubkey="${arr[3]}"
server_endpoint="${arr[4]}"
server_admin="${arr[5]}"
server_secret="${arr[6]}"
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}" ]
# Add new user to local server
2022-09-08 14:04:01 -06:00
then printf "Adding ${domain} to local server..." >>"${LOGFILE}"
#"${LIB_DIR}/wg_peer_add" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128"
true
[ ${?} -ne 0 ] && (
printf 'Failed to add new peer ${ipv4} to local server!' >>"${LOGFILE}"
# TODO: clear existing progress and exit 15
)
2022-09-06 20:57:41 -06:00
# Send new user config to federated server
2022-09-08 14:04:01 -06:00
else printf "Sending ${domain} to remote server ${server_hostname}..." >>"${LOGFILE}"
#"${LIB_DIR}/fed_add" "${server_admin}" "${pubkey}" "${server_psk}" "${ipv4}/32,${ipv6}/128" "${server_secret}"
true
[ ${?} -ne 0 ] && (
printf 'Failed to add new peer ${ipv4} to federated server ${server_hostname}!' >>"${LOGFILE}"
# TODO: clear existing progress and exit 16
)
2022-09-06 20:57:41 -06:00
fi
done <${SERVERS_FILE}
wg_config="[Interface] # ${hostname}.${username}.${TLD}\nPrivateKey=${privkey}\nAddress=${address}\n${WG_DNS}\n${server_blocks}"
# Respond to user
2022-09-08 14:04:01 -06:00
# 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
2022-09-06 20:57:41 -06:00
printf "${wg_config}" | "${LIB_DIR}/http_res"
# Update nameserver
2022-09-08 14:04:01 -06:00
#"${LIB_DIR}/ns_update_add" "${domain}" "${ipv4}" "${ipv6}"
true
[ ${?} -ne 0 ] && printf "Failed to add ${domain} ${ipv4} ${ipv6} to DNS server!" >>"${LOGFILE}"
2022-09-06 20:57:41 -06:00
# Create SSL cert
2022-09-08 14:04:01 -06:00
#sudo "${LIB_DIR}/ssl_peer_add" "${hostname}" "${username}" "IP:${ipv4},IP:${ipv6}"
true
[ ${?} -ne 0 ] && printf "Failed to create certs for ${domain} with IPS: ${ipv4} ${ipv6}!" >>"${LOGFILE}"