Created
February 6, 2020 22:36
-
-
Save MicroDroid/e8dda8a28e4e7ff481f422b66eadd045 to your computer and use it in GitHub Desktop.
Generate WireGuard peer config
This file contains 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 | |
umask 077 | |
# version of https://stackoverflow.com/a/43196141/2164304 | |
generate_ip() { | |
LAST_IP=`grep -F "AllowedIPs" $LOCAL_PEER_CONFIG | cut -d '=' '-f2-' | cut -d '/' -f1 | xargs -n1 | sort -nrt . -k 3,3 -k 4,4 | head -n1` | |
IP_HEX=$(printf '%.2X%.2X%.2X%.2X\n' `echo $LAST_IP | sed -e 's/\./ /g'`) | |
NEXT_IP_HEX=$(printf %.8X `echo $(( 0x$IP_HEX + 1 ))`) | |
NEXT_IP=$(printf '%d.%d.%d.%d\n' `echo $NEXT_IP_HEX | sed -r 's/(..)/0x\1 /g'`) | |
echo "$NEXT_IP" | |
} | |
HELP="Usage: | |
mkwg [args] client-name | |
-h / --help: Show this thing | |
-c / --config [/etc/wireguard/wg0.conf]: Specify local peer configuration | |
-p / --publickey [read from /etc/wireguard/publickey]: Specify local peer public key | |
-o / --output [./<client-name>]: Specify directory to output config | |
-w / --write [false]: Write to local peer config | |
" | |
# CLI args | |
REMOTE_PEER_NAME="" | |
OUTPUT_DIR="" | |
LOCAL_PEER_CONFIG="/etc/wireguard/wg0.conf" | |
WRITE_LOCAL_PEER_CONFIG=0 | |
# Things to figure out | |
LOCAL_PEER_PUBLIC_IP="" | |
LOCAL_PEER_PUBLIC_KEY="" | |
LOCAL_PEER_PORT="" | |
REMOTE_PEER_WIREGUARD_IP="" | |
# Parse CLI args | |
POSITIONAL=() | |
while [[ $# -gt 0 ]] | |
do | |
key="$1" | |
case $key in | |
-c|--config) | |
LOCAL_PEER_CONFIG="$2" | |
shift # past argument | |
shift # past value | |
;; | |
-h|--help) | |
echo "$HELP" | |
exit | |
;; | |
-p|--publickey) | |
LOCAL_PEER_PUBLIC_KEY="$2" | |
shift # past argument | |
shift # past value | |
;; | |
-o|--output) | |
OUTPUT_DIR="$2" | |
shift # past argument | |
shift # past value | |
;; | |
-w|--write) | |
WRITE_LOCAL_PEER_CONFIG=1 | |
shift # past argument | |
shift # past value | |
;; | |
*) # unknown option | |
POSITIONAL+=("$1") # save it in an array for later | |
shift # past argument | |
;; | |
esac | |
done | |
set -- "${POSITIONAL[@]}" # restore positional parameters | |
REMOTE_PEER_NAME="$POSITIONAL" | |
# Verify input & skim down some data | |
if [ -z "$REMOTE_PEER_NAME" ]; then | |
>&2 echo "$HELP" | |
exit 1 | |
fi | |
if [ -z "$OUTPUT_DIR" ]; then | |
OUTPUT_DIR="./$REMOTE_PEER_NAME" | |
fi | |
if [ ! -r "$LOCAL_PEER_CONFIG" ]; then | |
>&2 echo "Local peer's configuration cannot be read at '$LOCAL_PEER_CONFIG'" | |
exit 1 | |
fi | |
LOCAL_PEER_PUBLIC_IP=`curl -s https://ipinfo.io/ip` | |
if [ -z "$LOCAL_PEER_PUBLIC_IP" ]; then | |
>&2 echo "Local peer's public IP could not be fetched" | |
exit 1 | |
fi | |
LOCAL_PEER_PORT=`grep -m1 -F "ListenPort" "$LOCAL_PEER_CONFIG" | cut -d '=' '-f2-' | xargs` | |
if [ -z "$LOCAL_PEER_PUBLIC_KEY" ]; then | |
if [ ! -r "/etc/wireguard/publickey" ]; then | |
>&2 echo "Local peer public key could not be read at /etc/wireguard/publickey" | |
exit 1 | |
fi | |
LOCAL_PEER_PUBLIC_KEY=`cat /etc/wireguard/publickey` | |
# Just makin' sure | |
if [ -z "$LOCAL_PEER_PUBLIC_KEY" ]; then | |
>&2 echo "Local peer public key could not be found at /etc/wireguard/publickey" | |
exit 1 | |
fi | |
fi | |
if [[ "$WRITE_LOCAL_PEER_CONFIG" -eq "1" && ! -w "$LOCAL_PEER_CONFIG" ]]; then | |
>&2 echo "Local peer configuration is not writable" | |
exit 1 | |
fi | |
REMOTE_PEER_WIREGUARD_IP=`generate_ip` | |
# Actual work heheheheh | |
if [ -d "$OUTPUT_DIR" ]; then | |
>&2 echo "Directory '$OUTPUT_DIR' exists." | |
exit 1 | |
fi | |
# Create a directory for the client | |
mkdir "$OUTPUT_DIR" | |
# Generate pub/priv keys, and a preshared key | |
wg genkey | tee "$OUTPUT_DIR/privatekey" | wg pubkey > "$OUTPUT_DIR/publickey" | |
wg genkey > "$OUTPUT_DIR/preshared" | |
# Write configuration | |
cat <<EOT >> "$OUTPUT_DIR/config.conf" | |
[Interface] | |
Address = $REMOTE_PEER_WIREGUARD_IP/32 | |
DNS = 1.1.1.1,1.0.0.1 | |
MTU=1280 | |
PrivateKey = `cat "$OUTPUT_DIR/privatekey"` | |
[Peer] | |
PublicKey = $LOCAL_PEER_PUBLIC_KEY | |
PresharedKey = `cat "$OUTPUT_DIR/preshared"` | |
AllowedIPs = 0.0.0.0/0, ::/0 | |
Endpoint = $LOCAL_PEER_PUBLIC_IP:$LOCAL_PEER_PORT | |
EOT | |
# Set permissions | |
chmod 700 "$OUTPUT_DIR" | |
chmod 600 "$OUTPUT_DIR/privatekey" | |
chmod 600 "$OUTPUT_DIR/publickey" | |
chmod 600 "$OUTPUT_DIR/preshared" | |
REMOTE_PEER_CONFIG=" | |
[Peer] | |
PublicKey = `cat "$OUTPUT_DIR/publickey"` | |
PresharedKey = `cat "$OUTPUT_DIR/preshared"` | |
AllowedIPs = $REMOTE_PEER_WIREGUARD_IP/32 | |
" | |
if [ "$WRITE_LOCAL_PEER_CONFIG" -eq "1" ]; then | |
echo -e "\n\n$REMOTE_PEER_CONFIG" >> $LOCAL_PEER_CONFIG | |
else | |
echo -e "Copy the following configuration to local peer's config (like /etc/wireguard/wg0.conf):\n" | |
echo "$REMOTE_PEER_CONFIG" | |
fi | |
if [ -x "$(command -v qrencode)" ]; then | |
echo -e "QR code of new peer's config:\n" | |
qrencode -t ansi "$REMOTE_PEER_CONFIG" | |
echo -e "\nRemote peer's configuration is also available at $OUTPUT_DIR/config.conf" | |
else | |
echo -e "QR code could not be generated because 'qrencode' is not installed." | |
echo -e "Copy remote peer's configuration from $OUTPUT_DIR/config.conf" | |
fi | |
echo ">> Configuration finished. Make sure to restart WireGuard." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment