Setup Wireguard Server in one shot on Debian/Ubuntu

This is short article consist of bash script for creating WireGuard server with listed clients in sigle shot. Before running this script make sure:

  • Set your server's public IP.
  • Update list of clients you need to generate.
  • Create bash file such as '', set execute permissions & run the script.
Your server will be rebooted at the end of script execution.

export serverIP="<PUBLIC_IP_OF_YOUR_SERVER>" 
# List of clietns you want to create
declare -a clients=(
"pi" on

    wg genkey | tee keys/${client}_private_key | wg pubkey > keys/${client}_public_key

for c in "${clients[@]}" 
    ckey="$(cat keys/${c}_public_key)"         
[Peer] # ${c}
PublicKey = ${ckey}
AllowedIPs = 10.200.200.${index}/32

echo "$peers"    

for c in "${clients[@]}" 
    cpkey="$(cat keys/${c}_private_key)"
    echo "
Address = 10.200.200.${index}/32
PrivateKey = ${cpkey}
DNS = 

PublicKey = $(cat 'keys/server_public_key')
Endpoint = ${serverIP}:51820
AllowedIPs =
PersistentKeepalive = 21" >  clients/${c}.conf  

qrencode -o clients/${c}.png -t png < clients/${c}.conf    

# Start Script execution  
rm -rf keys clients 
mkdir keys
mkdir clients 

sudo apt update -y   
sudo apt upgrade -y 
sudo apt install wireguard linux-headers-$(uname -r) -y  
sudo apt install qrencode -y
sudo apt install iptables-persistent -y
sudo apt install unbound unbound-host -y

# Generate keys
keyGen "server"
for c in "${clients[@]}" 
 keyGen $c 

# Generate server config
echo " 
PrivateKey = $(cat keys/server_private_key)
Address =
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; ip6tables -A FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -A POSTROUTING -o ens3 -j MASQUERADE; iptables -t nat -A POSTROUTING -s -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; ip6tables -D FORWARD -i wg0 -j ACCEPT; ip6tables -t nat -D POSTROUTING -o ens3 -j MASQUERADE; iptables -t nat -D POSTROUTING -s -o eth0 -j MASQUERADE
SaveConfig = true
" |  tee clients/wg0.conf 
cat clients/wg0.conf | sudo tee /etc/wireguard/wg0.conf 

#Generate clients configs

# Firewall 

#Track VPN connection
sudo iptables -A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
#VPN traffic on the listening port
sudo iptables -A INPUT -p udp -m udp --dport 51820 -m conntrack --ctstate NEW -j ACCEPT
#TCP and UDP recursive DNS traffic
sudo iptables -A INPUT -s -p tcp -m tcp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
sudo iptables -A INPUT -s -p udp -m udp --dport 53 -m conntrack --ctstate NEW -j ACCEPT
#Allow forwarding of packets that stay in the VPN tunnel
sudo iptables -A FORWARD -i wg0 -o wg0 -m conntrack --ctstate NEW -j ACCEPT

# enable IPv4 forwarding
sudo sed -i 's/\#net.ipv4.ip_forward=1/net.ipv4.ip_forward=1/g' /etc/sysctl.conf

# download list of DNS root servers
sudo curl -o /var/lib/unbound/root.hints

# create Unbound config file
echo "
    num-threads: 4
    # enable logs
    verbosity: 1
    # list of root DNS servers
    root-hints: \"/var/lib/unbound/root.hints\"
    # use the root server's key for DNSSEC
    auto-trust-anchor-file: \"/var/lib/unbound/root.key\"
    # respond to DNS requests on all interfaces
    max-udp-size: 3072
    # IPs authorised to access the DNS Server
    access-control:                 refuse
    access-control:                 allow
    access-control:             allow
    # not allowed to be returned for public Internet  names
    #hide DNS Server info
    hide-identity: yes
    hide-version: yes
    # limit DNS fraud and use DNSSEC
    harden-glue: yes
    harden-dnssec-stripped: yes
    harden-referral-path: yes
    # add an unwanted reply threshold to clean the cache and avoid, when possible, DNS poisoning
    unwanted-reply-threshold: 10000000
    # have the validator print validation failures to the log
    val-log-level: 1
    # minimum lifetime of cache entries in seconds
    cache-min-ttl: 1800
    # maximum lifetime of cached entries in seconds
    cache-max-ttl: 14400
    prefetch: yes
    prefetch-key: yes

" | sudo tee /etc/unbound/unbound.conf 

# give root ownership of the Unbound config
sudo chown -R unbound:unbound /var/lib/unbound

echo " $(hostname)" | sudo tee -a /etc/hosts

# services
sudo systemctl enable wg-quick@wg0.service
sudo systemctl enable netfilter-persistent  
sudo netfilter-persistent save

# disable systemd-resolved
sudo systemctl stop systemd-resolved &&
sudo systemctl disable systemd-resolved

# enable Unbound in place of systemd-resovled
sudo systemctl enable unbound-resolvconf &&
sudo systemctl enable unbound

sudo reboot

Now your server is running with Wireguard, you can download clients configuration & QR Codes and configure devices.