2023-03-10 17:16:08 -08:00
|
|
|
#!/bin/bash
|
|
|
|
#
|
|
|
|
# vpn-stack
|
|
|
|
# A set of bash scripts for installing and managing a WireGuard VPN server.
|
|
|
|
# https://git.stack-source.com/msb/vpn-stack
|
|
|
|
# Copyright (c) 2022 Matthew Saunders Brown <matthewsaundersbrown@gmail.com>
|
|
|
|
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
|
|
|
|
|
|
|
|
# any script that includes this conf file will force user to be root
|
|
|
|
if [ "$USER" != "root" ]; then
|
|
|
|
exec sudo -u root $0 $@
|
|
|
|
fi
|
|
|
|
|
|
|
|
# constants
|
|
|
|
|
2024-07-24 14:00:18 -07:00
|
|
|
# Set Endpoint. Hard code value here, or leave blank for automatic configuration below
|
|
|
|
endpoint=
|
|
|
|
|
|
|
|
# Check if endpoint is hard coded above, configure automatically if not.
|
|
|
|
if [[ -z $endpoint ]]; then
|
|
|
|
fqdn=`hostname -f`
|
|
|
|
primaryip=`ip route get 1.1.1.1| head -n 1 | cut -d ' ' -f 7`
|
|
|
|
reversedns=`dig -x $primaryip +short | sed 's|.$||'`
|
|
|
|
# If forward & reverse DNS are configured and match use the FQDN, otherwise use primary IP.
|
|
|
|
if [[ $fqdn = $reversedns ]]; then
|
|
|
|
endpoint=$fqdn
|
|
|
|
else
|
|
|
|
endpoint=$primaryip
|
|
|
|
fi
|
|
|
|
fi
|
|
|
|
|
|
|
|
# DNS. 3 options:
|
|
|
|
# - none: do not change client DNS settings
|
|
|
|
# - stubby: DNS Privacy
|
|
|
|
# - dnsmasq: DNS Privacy with Ad Blocking
|
|
|
|
# Default listed here, can be overriden via wg-client-add.sh
|
|
|
|
dnsconfig=dnsmasq
|
|
|
|
|
|
|
|
# IPs to route through the VPN. By default all traffic is routed through VPN. Alternatively you can specify a comma separated list of IPs/networks.
|
|
|
|
AllowedIPs=0.0.0.0/0
|
|
|
|
# AllowedIPs="10.96.0.0/16, 1.1.1.1, 1.0.0.1"
|
|
|
|
|
2023-03-10 17:16:08 -08:00
|
|
|
# functions
|
|
|
|
|
|
|
|
# crude but good enough domain name format validation
|
|
|
|
function wg::validate_domain () {
|
|
|
|
local my_domain=$1
|
|
|
|
if [[ $my_domain =~ ^(([a-zA-Z0-9](-?[a-zA-Z0-9])*)\.)+[a-zA-Z]{2,}$ ]] ; then
|
|
|
|
return 0
|
|
|
|
else
|
|
|
|
return 1
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2024-07-24 14:00:18 -07:00
|
|
|
function wg::validate_client () {
|
|
|
|
local my_client=$1
|
|
|
|
if [[ $my_client =~ ^[[:alnum:]][-_[:alnum:]]{1,30}[[:alnum:]]$ ]] ; then
|
|
|
|
return 0;
|
|
|
|
else
|
|
|
|
return 1;
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2023-03-13 13:13:13 -07:00
|
|
|
function wg::getoptions () {
|
2023-03-10 17:16:08 -08:00
|
|
|
local OPTIND
|
2024-07-24 14:00:18 -07:00
|
|
|
while getopts "c:d:e:h" opt ; do
|
2023-03-10 17:16:08 -08:00
|
|
|
case "${opt}" in
|
|
|
|
h ) # display help and exit
|
|
|
|
help
|
|
|
|
exit
|
|
|
|
;;
|
2023-03-13 13:13:13 -07:00
|
|
|
c ) # client/config name
|
|
|
|
client=${OPTARG,,}
|
2024-07-24 14:00:18 -07:00
|
|
|
if ! wg::validate_client $client; then
|
|
|
|
echo "ERROR: '$client' is not a valid client config name."
|
|
|
|
echo "Client config name must begin & end with a letter or number,"
|
|
|
|
echo "can only contain letters numbers dashes and underscores,"
|
|
|
|
echo "and must be 3 to 32 characters in length."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
d ) # DNS config
|
|
|
|
dnsconfig=${OPTARG,,}
|
2023-03-10 17:16:08 -08:00
|
|
|
;;
|
|
|
|
e ) # email address
|
|
|
|
email=${OPTARG,,}
|
|
|
|
if [[ $email =~ "@" ]] ; then
|
|
|
|
mbox=${email%@*}
|
|
|
|
domain=${email##*@}
|
|
|
|
if [ -z $mbox ] ; then
|
|
|
|
echo "ERROR: No local part in $email."
|
|
|
|
exit 1
|
|
|
|
elif [ -z $domain ] ; then
|
|
|
|
echo "ERROR: No domain in $email."
|
|
|
|
exit 1
|
|
|
|
elif ! wg::validate_domain $domain; then
|
|
|
|
echo "ERROR: $domain is not a valid domain name."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
else
|
|
|
|
echo "ERROR: $email is not a valid email."
|
|
|
|
exit 1
|
|
|
|
fi
|
|
|
|
;;
|
|
|
|
\? )
|
|
|
|
echo "Invalid option: $OPTARG"
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
: )
|
|
|
|
echo "Invalid option: $OPTARG requires an argument"
|
|
|
|
exit 1
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
done
|
|
|
|
shift $((OPTIND-1))
|
|
|
|
}
|
|
|
|
|