#!/usr/bin/env bash ## script to generate client wireguard configs as qr codes # requires package `qrencode` from the repos # does not handle cases such as multiple wireguard interfaces; modify as needed # exit if a command fails set -o errexit # exit if required variables are not set set -o nounset # return the exit status of the final command before a failure set -o pipefail # check for dependencies script_commands="drill iptables qrencode sudo wg" missing_counter=0 for needed_command in ${script_commands}; do if ! hash "${needed_command}" >/dev/null 2>&1; then printf "Command not found in PATH: %s\n" "${needed_command}" >&2 ((missing_counter++)) fi done if ((missing_counter > 0)); then printf "Minimum %d commands are missing in PATH, aborting.\n" "${missing_counter}" >&2 exit 1 fi # make sure the correct number of arguments are passed; if not, output syntax and exit if [ "$#" -ne 3 ]; then echo -e "\nUsage: $0 \n" exit 1 fi # set the private subnets to be used (please change these to fit your needs) subnet_v4="10.25.0" mask_v4="24" # set wireguard server public ip address (using drill to make chef happy, despite lacking the +short argument) server="$(drill -4 myip.opendns.com @resolver1.opendns.com | awk '{if(NF > 0 && substr($1,1,1) != ";") print $NF }')" # set server port port="$(sudo wg | grep "listening port" | awk '{print $3}')" # set wireguard tunnel interface name interface="wg0" # set peer name in uci config peer_name="wgpeer" # determine the routes to add if [ "$1" = "access" ]; then route_v4="0.0.0.0/0" elif [ "$1" = "site" ]; then route_v4="${subnet_v4}.0/${mask_v4}" else echo "Connection type must be either access or site." exit 1 fi # assign arguments to variables client="$2" ip_addr="$3" # set imagebuilder directory cert_dir="${HOME}/wireguard/${client}" # set logfile location log_file="${cert_dir}/certgen.log" # delete any old builds if they exist if [ -d "${cert_dir}" ]; then echo -e "\nRemoving old wireguard keys..." >> "${log_file}" 2>&1 rm -rf "${cert_dir}" fi # create base directory for account mkdir -p "${cert_dir}" # display log location echo -e "\nLogging all output to ${log_file}\n" # prepend timestamp to logfile echo -e "\nCertificate generation began at $(date +%Y/%m/%d-%H:%M)." >> "${log_file}" 2>&1 # wrap the script into a function for logging purposes { # generate public and private keys for the client umask 077 wg genkey | tee "${cert_dir}"/privatekey | wg pubkey > "${cert_dir}"/publickey # generate preshared key for the client preshared_key="$(wg genpsk)" # set variables for keys client_public_key="$(cat "${cert_dir}"/publickey)" client_private_key="$(cat "${cert_dir}"/privatekey)" server_public_key="$(cat /etc/wireguard/publickey)" # add peer to wireguard server configuration echo -e "\n### Begin server config ###" cat < "${cert_dir}"/wireguard.key cat <&1 | tee -a "${log_file}" >/dev/null # append timestamp to logfile echo -e "\nFinished generating Wireguard certs.\n\nCertificate generation finished at $(date +%Y/%m/%d-%H:%M).\n" >> "${log_file}" # display client config as qr code echo -e "\n$(cat "${cert_dir}"/qrcode.conf)\n"