Skip to content

Instantly share code, notes, and snippets.

@pR0Ps
Last active March 28, 2024 10:01
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save pR0Ps/eba07c962447139a33e538afbb7b2749 to your computer and use it in GitHub Desktop.
Save pR0Ps/eba07c962447139a33e538afbb7b2749 to your computer and use it in GitHub Desktop.
Script to generate wireguard configs for clients to allow them to connect to the local wireguard server
#!/bin/bash
#######
# Setup
#######
### Enable IPv4/6 forwarding:
# # In /etc/sysctl.d/30-ipforward.conf :
# net.ipv4.ip_forward=1
# net.ipv6.conf.default.forwarding=1
# net.ipv6.conf.all.forwarding=1
### Generate server keypair:
# servername=$(hostname)
# wg_iface="wg0"
# mkdir -p /etc/wireguard/keys
# touch "/etc/wireguard/keys/$servername.$wg_iface.key"
# chmod 600 "/etc/wireguard/keys/$servername.$wg_iface.key"
# wg genkey | tee "/etc/wireguard/keys/$servername.$wg_iface.key" | wg pubkey "/etc/wireguard/keys/$servername.$wg_iface.pub"
### Server config
# # In /etc/wireguard/<wgiface>.conf
# # Things to change: IPv4/6 addresses, network interface
# [Interface]
# PrivateKey = <read from /etc/wireguard/keys/<servername>.<wgiface>.key>
# Address = xxx.xxx.xxx.1/24, xxxx:xxxx:xxxx::1/128
# ListenPort = 51820
# PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -t nat -A POSTROUTING -o <netiface> -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o <netiface> -j MASQUERADE
# PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o <netiface> -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o <netiface> -j MASQUERADE
# SaveConfig = false
########
# Script
########
set -e
# Modify these per-server
wg_iface="wg0"
servername="<servername>"
config_file="/etc/wireguard/$wg_iface.conf"
server_pub_file="/etc/wireguard/keys/$servername.$wg_iface.pub"
server_domain="example.org"
server_port="51820"
ipv4_prefix="10.0.0."
ipv4_mask="32"
ipv6_prefix="xxxx:xxxx:xxxx::"
ipv6_mask="128"
dns_servers="192.168.1.1"
# Require root to change wg-related settings
if ! [ "$(id -u)" = "0" ]; then
echo "ERROR: root is required to configure WireGuard clients"
exit 1
fi
# Help and basic error checking
if [ $# -ne 2 ] || [ $# -gt 1 -a "$1" == "--help" ]; then
echo "Usage:"
echo "$(basename "$0") <client number> <device name>"
exit 1
fi
# Pull server pubkey from file
server_pub=$(< "$server_pub_file")
# Params
client_number="$1"
name="$2"
# Generate and store keypair
priv=$(wg genkey)
pub=$(echo "$priv" | wg pubkey)
# Create IPv4/6 addresses based on client ID
client_ipv4="$ipv4_prefix$client_number/$ipv4_mask"
client_ipv6="$ipv6_prefix$client_number/$ipv6_mask"
# Can't add duplicate IPs
if grep -q "$client_ipv4" "$config_file" || grep -q "$client_ipv6" "$config_file"; then
echo "ERROR: This client number has already been used in the config file"
exit 1
fi
# Add peer to config file (blank line is on purpose)
cat >> $config_file <<-EOM
[Peer]
# $name
PublicKey = $pub
AllowedIPs = $client_ipv4, $client_ipv6
EOM
# Make client config
client_config=$(cat <<-EOM
[Interface]
PrivateKey = $priv
Address = $client_ipv4, $client_ipv6
DNS = $dns_servers
[Peer]
PublicKey = $server_pub
AllowedIPs = 0.0.0.0/0, ::/0
Endpoint = $server_domain:$server_port
PersistentKeepalive = 25
EOM
)
# Output client configuration
echo "########## START CONFIG ##########"
echo "$client_config"
echo "########### END CONFIG ###########"
if command -v qrencode > /dev/null; then
echo "$client_config" | qrencode -t ansiutf8
else
echo "Install 'qrencode' to also generate a QR code of the above config"
fi
# Restart service
echo ""
read -p "Restart 'wg-quick@$wg_iface' ? [y]: " confirm
if [ $confirm == "y" ]; then
systemctl restart "wg-quick@$wg_iface"
else
echo "WARNING: 'wg-quick@$wg_iface' will need to be restarted before the new client can connect"
fi
@kingbash90
Copy link

Hello, so it doesn't matter how many clients are trying to connects this script will handle all config files.
Sorry for my english

@pR0Ps
Copy link
Author

pR0Ps commented Feb 13, 2024

@kingbash90: Yes, with some restrictions. The script takes a <client number> as a parameter. You need to use a different client number from 0 to 254 for every client and it will handle setting everything up for you.

If you use the same client number for multiple clients then everything will still work, but those clients won't be able to connect at the same time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment