#!/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 # 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 # 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" # 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 } function wg::validate_client () { local my_client=$1 if [[ $my_client =~ ^[[:alnum:]][-_[:alnum:]]{1,30}[[:alnum:]]$ ]] ; then return 0; else return 1; fi } function wg::getoptions () { local OPTIND while getopts "c:d:e:h" opt ; do case "${opt}" in h ) # display help and exit help exit ;; c ) # client/config name client=${OPTARG,,} 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,,} ;; 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)) }