#!/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/.conf # # Things to change: IPv4/6 addresses, network interface # [Interface] # PrivateKey = ..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 -j MASQUERADE; ip6tables -A FORWARD -i %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o -j MASQUERADE # PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -t nat -D POSTROUTING -o -j MASQUERADE; ip6tables -D FORWARD -i %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o -j MASQUERADE # SaveConfig = false ######## # Script ######## set -e # Modify these per-server wg_iface="wg0" 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") " 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