Last active
April 6, 2025 14:05
-
-
Save freespace/7967697f5e26c7732040a39e87ce0fea to your computer and use it in GitHub Desktop.
Simple script to add a wireguard client and show the client config as a QR code for ease of client configuration.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Script to add a wireguard client. You need qrencode installed. By default clients are allowed to try to | |
# access the internet, though you will need to configure iptable rules and enable IP forwarding. | |
CONF_DIR="/etc/wireguard/clients" | |
SERVER_PUBLIC_KEY="/etc/wireguard/wg0.publickey" | |
SERVER_CONF="/etc/wireguard/wg0.conf" | |
SUBNET="192.168.90" | |
FIRST_CLIENT_IP="100" | |
# https://www.dns0.eu/ | |
DNS_SERVERS="193.110.81.0, 185.253.5.0" | |
SERVER_ENDPOINT="<server-hostname-or-ip>:<port>" | |
DEVICE_NAME="$1" | |
function show_help { | |
printf "Usage: $0 <device name>\n" | |
printf "<device name> must only contain alpha-numeric characters and dash (-)\n" | |
exit 1 | |
} | |
function check_ok_or_exit { | |
if [ $? -ne 0 ]; then | |
printf "$1\n" | |
exit 2; | |
fi | |
} | |
if [ -z "${DEVICE_NAME}" ]; then | |
show_help | |
fi | |
# device name must be alphanum and dash (-) only | |
# https://unix.stackexchange.com/a/340485/191141 | |
if [[ ! "${DEVICE_NAME}" =~ ^([[:alnum:]]|-)+$ ]] || [[ "${DEVICE_NAME}" =~ ^[[:digit:]]+$ ]]; then | |
show_help | |
fi | |
NUM_CLIENTS="$(ls "${CONF_DIR}"/*.conf 2>/dev/null| wc -l)" | |
printf "Found ${NUM_CLIENTS} existing clients\n" | |
# note that b/c we start _from_ 100 we don't need to increment | |
NEW_IP="${SUBNET}.$(( ${FIRST_CLIENT_IP} + ${NUM_CLIENTS} ))" | |
# go into the client config dir and make sure we are creating files with | |
# appropriate permissions | |
pushd "${CONF_DIR}" | |
umask 077 | |
DEVICE_CONF="${DEVICE_NAME}.conf" | |
DEVICE_PRIVATE_KEY="${DEVICE_NAME}.privatekey" | |
DEVICE_PUBLIC_KEY="${DEVICE_NAME}.publickey" | |
if [ -e "${DEVICE_CONF}" ]; then | |
printf "Refusing to run: ${DEVICE_CONF} already exists\n" | |
exit 2 | |
fi | |
# generate keys | |
wg genkey > "${DEVICE_PRIVATE_KEY}" | |
check_ok_or_exit "Failed to generate private key" | |
wg pubkey < "${DEVICE_PRIVATE_KEY}" > "${DEVICE_PUBLIC_KEY}" | |
check_ok_or_exit "Failed to generate public key" | |
# generate config | |
cat << EOF > "${DEVICE_CONF}" | |
[Interface] | |
PrivateKey = $(cat "${DEVICE_PRIVATE_KEY}") | |
Address = ${NEW_IP}/24 | |
DNS = ${DNS_SERVERS} | |
[Peer] | |
PublicKey = $(cat "${SERVER_PUBLIC_KEY}") | |
AllowedIPs = ${SUBNET}.0/24, 0.0.0.0/0 | |
Endpoint = ${SERVER_ENDPOINT} | |
PersistentKeepalive = 25 | |
EOF | |
# render config as QR code | |
qrencode -t ansiutf8 < "${DEVICE_CONF}" | |
# add the client to peers we know about | |
SERVER_CONF_BACKUP="${SERVER_CONF}.$(date +%s)" | |
cp "${SERVER_CONF}" "${SERVER_CONF_BACKUP}" | |
printf "${SERVER_CONF} backed up to ${SERVER_CONF_BACKUP}\n" | |
cat << EOF >> "${SERVER_CONF}" | |
[Peer] | |
# ${DEVICE_NAME} | |
AllowedIPs = ${NEW_IP}/32 | |
PublicKey = $(cat "${DEVICE_PUBLIC_KEY}") | |
EOF | |
# restart the server | |
wg-quick down wg0 | |
check_ok_or_exit "Failed to shutdown wireguard server" | |
wg-quick up wg0 | |
check_ok_or_exit "Failed to start wireguard server" | |
# good bye | |
popd |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment