Skip to content

Instantly share code, notes, and snippets.

@chrisswanda
Last active August 12, 2025 06:59
Show Gist options
  • Save chrisswanda/88ade75fc463dcf964c6411d1e9b20f4 to your computer and use it in GitHub Desktop.
Save chrisswanda/88ade75fc463dcf964c6411d1e9b20f4 to your computer and use it in GitHub Desktop.
Stupid simple setting up WireGuard - Server and multiple peers
Install WireGuard via whatever package manager you use. For me, I use apt.
$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt-get update
$ sudo apt-get install wireguard
MacOS
$ brew install wireguard-tools
Generate key your key pairs. The key pairs are just that, key pairs. They can be
generated on any device, as long as you keep the private key on the source and
place the public on the destination.
$ wg genkey | tee privatekey | wg pubkey > publickey
example privatekey - mNb7OIIXTdgW4khM7OFlzJ+UPs7lmcWHV7xjPgakMkQ=
example publickey - 0qRWfQ2ihXSgzUbmHXQ70xOxDd7sZlgjqGSPA9PFuHg=
One can also generate a preshared key to add an additional layer of symmetric-key cryptography to be mixed into the already existing public-key cryptography, for post-quantum resistance.
# wg genpsk > preshared
Take the above private key, and place it in the server. And conversely, put the
public key on the peer. Generate a second key pair, and do the opposite, put the
public on the server and the private on the peer. Put the preshared key in the client config if you choose to use it.
On the server, create a conf file - /etc/wireguard/wg0.conf (These are examples,
so use whatever IP ranges and CIDR blocks that will work for your network.
################################
[Interface]
Address = 10.0.0.1/24
DNS = 1.1.1.1
PrivateKey = [ServerPrivateKey]
ListenPort = 51820
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o enp9s0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o enp9s0 -j MASQUERADE
[Peer]
#Peer #1
PublicKey = [Peer#1PublicKey]
AllowedIPs = 10.0.0.3/32
[Peer]
#Peer #2
PublicKey = [Peer#2PublicKey]
AllowedIPs = 10.0.0.10/32
[Peer]
#Peer #3
PublicKey = [Peer#3PublicKey]
AllowedIPs = 10.0.0.2/32
[Peer]
#Peer #4
PublicKey = [Peer#4PublicKey]
AllowedIPs = 10.0.0.11/32
##################################
On each client, define a /etc/wireguard/mobile_user.conf -
###################################
[Interface]
Address = 10.0.0.3/24
PrivateKey = [PrivateKeyPeer#1]
[Peer]
PublicKey = [ServerPublicKey]
PresharedKey = [PresharedKey]
Endpoint = some.domain.com:51820
AllowedIPs = 0.0.0.0/0, ::/0
# if you want to do split tunnel, add your allowed IPs
# for example if your home network is 192.168.1.0/24
# AllowedIPs = 192.168.1.0/24
# This is for if you're behind a NAT and
# want the connection to be kept alive.
PersistentKeepalive = 25
########################################
sudo wg show
#########################################
peer: Peer #1
endpoint: 192.168.2.1:50074
allowed ips: 10.0.0.2/32
latest handshake: 4 minutes, 16 seconds ago
transfer: 57.58 KiB received, 113.32 KiB sent
peer: Peer #2
endpoint: 99.203.28.43:36770
allowed ips: 10.0.0.10/32
latest handshake: 5 minutes, 30 seconds ago
transfer: 92.98 KiB received, 495.89 KiB sent
##################################################
Start/stop interface
wg-quick up wg0
wg-quick down wg0
Start/stop service
$ sudo systemctl stop [email protected]
$ sudo systemctl start [email protected]
Instead of having to modify the file for every client you want to add to the
server you could also use the wg tool instead:
# add peer
wg set wg0 peer <client_pubkey> allowed-ips 10.0.0.x/32
# verify connection
wg
# save to config
wg-quick save wg0
######### EDIT ##############
I was setting up a relative with a Wireguard config, and figured I might as well use qrencode to do it since I have it installed on my local machine.
qrencode -t ansiutf8 < /etc/wireguard/mobile_user.conf
█████████████████████████████████████████████████████████████████████████████
█████████████████████████████████████████████████████████████████████████████
████ ▄▄▄▄▄ █▄▀████▀▀█ ▄▀▀▀▄▄ ▄▄▄▄▄▀ █ ██▀█ ▄▀▀██▄ ▄ ▀█▀▄█ ▄▄ ▀▄▄▄█ ▄▄▄▄▄ ████
████ █ █ █ ▀▀█▀█▄▄▄ █▀██▄ ▄▀ ▀ ▄▀▄█▄▄ ▄█▀▀█▄▄ ▄█ ▄ █ ▄█▄█▀█ █ █ ████
████ █▄▄▄█ █▄▄█▄ ▀█ ▀▄█████ ▀ ▄▄▀▄ █ ▄▄▄ █▄▄▀▀▀▀▀▀██▄ █▄ ▀ ▀ █▄█ █▄▄▄█ ████
████▄▄▄▄▄▄▄█▄█ █▄▀▄▀ █▄█▄█ ▀ ▀▄▀ ▀ ▀ █▄█ █▄█ █▄█▄█▄▀ █▄▀ █▄▀ █▄▀▄█▄▄▄▄▄▄▄████
████▄▄ ▀▀▄▀ ▄ ██▄ █▀▄▄▀█▄▀ ▄▀▄▀██ ▄ ▄ ▀ █ ██▀ █▀▄▀▄▄ ▀ ▄ █ █▀▄▄ ▀ ████
████▀▄ ▀█▀▄▀█ █ ▀██▄█ █▀▄█▀ ▄▄█▄▀ ▀▄█ ▀▀ ▀▄▀▄▀██▄ ▀██▀▄▀█▀█ █ ▄█ ▄██▀████
█████ ▄▄▀ ▄ ██▀█▀▄ ▄▄█ ▀ ▄ █ ▀██ ▀▄█ █ ▄▄█▄█ ▀▀ ███ █▀▄▀▄ █ ▄█ ▄█▀ █ ▀█ ████
████▀█ ▄ ▄▀▄▀ ▄████▄▄█▄█ █▀█▀ ▀▀█▄█ ▄▀ ▄█▀█▄▀ █▀▄ █▀▄▀ ▄█▄█ ██ █▄▀▀ ▀ ████
████ ▀█ ▄▀▄█▄▄▀ ▀█ ▄█▄█ █▄ █ ▄ ▄ ▀▀█▄▀ ▀▄█ █ ▀ ▀▀ █▀██▄█▄▀ ▄█▄█ ▀▄▄▀▄████
████▄ ▄█ ▀▄▀▄▄▄ █▀ ▄▀█▀▀▄▀█ █▀▄▄▀ ▄█▀ ██ █▀ ▄ ▄▀███▀██▀▀ █▀▄▄ ▄█ █▄█ █████
████▀ ▄ ▄▀▄▄▀▀ ▄ ███▀▀▀█ ▀▄▄█▄▀█▀█▀█ ▄█ ▄█▄█▄█▄█▀▀█▄▀▄█ █ ▀▀▄██ █ ▀▀▄▄ ▄████
████▀▄ ▄█▀▄▀██ █▀ ▄ ▀█▄ ▀▄ █▀ ▄▀▀█ ▄ ▄ ▀▀▀▄▀▀ ▄▄▄▄▀▀▄▀▄████▄█▄ ▄▀▀█▄█ ████
█████ ▀▄▄▀▄ ▄█▄▀█▀ ▀ ██ ▄█ ▄█ ▀▄█▀▄▄ ▀███▄█▀ ██ ▄█ ▄ ▀▀▄▄█▀▀ ██▄▀ █▀▀█████
████ ▀▄█ ▄▀▄ ▀▄ ▀ █▀▄▀█ █ █▀ ██ █ ▄ █▄▄██▀▄▀▀ ▄▀█▄ █▄▄▀ ▀▀▄▀▀██▀ ██▀▀████
█████▄▄█▄█▄▀█▀▀▄▄ ▀▄▀ ▄▀▄▄██▀▀▀▀██▄█▄▄▀ ▄█▄▄█▄▄ █ ▀█▄▀█▀▀▄███▄ ▄ ▀ ▀ ████
█████ ▄ ▀▄▄ ▄▀█▄▄▄█▀█▄▄▄ ▀▀█▄▀█▄█▄█ ▄█▀▄█▀▄█ ██▀▄ ▄ ▄▄▄▀▀███▀█▄█ ▄▀██▀█████
████▄███ ▄▄▄ ▀▄▄▄▄▀▀▄▀▀██▀ █▄ ▀█▀█ ▄▄▄ ▀▀▄▀ █ ▄▀▄ █▀▄▄▀ ▀▄▄▄ ▄▄▄ ▄▄ █████
████▄ █▀ █▄█ █▀▄ ▀▄ ▄ ▄ ▀█▄█▀█ ▀▀█ █▄█ ▀█▀ ▄████▀▄█ ▄▀▄ ██▄▄▄ █▄█ ▀▄▄▄████
████ ▄▄ ▄▄▄▄█ █ ▀▀█▄▄▄ █▄ ▄ █▀▀▀ ██▀▄▄▄▀██▀ ▄▄ ▄▀██▄▄▄ ▄▀ █████
████▀█▀▀▄ ▄▀▀▄ ▄▀ ▀▀ ▀▄ █▀▄█ ▀ █▀▄▀▄▀▀█▄▀ ▄▄▀▀ ▀▀██ ▀▄▄▀▄▀▀▄ ▄▀███▄ ▄▄████
█████▀ ▀ ▄ █▀▀ ██ ▄▀▀▀▀▄█▀█▀ █ ▀█▄ ▀█▄ █▀███ █▄ ▄▀▀▄██▄▄ ▄▄█▀▄ ▄ ████
███████▄ ▄▄▄ ▀▄▄ ▀ ████▄ ▀█▀▀▀█▄▀ ▀ ▄█ ▀ ▄█▀▄ █▀▀▀▄▄▀▀ ▄█▄ ██▀ ▀ █████
██████ ▄▄▄▀ █▀ ▀▀ ▄ ▀ █ ▀ ███ ▄▄ ▄▀ ███▄▀ ▄ ▄▀ ▄███▄█▄▀▀▄█ ▄▀ ▀████
████ ▄█▀▀▀▄▀▀ ▀█ ▀▄ █ █▀▄▄▄█▀▄ ▀ █▄▄█▄ ▄▄▀█ ▀ █▀▄▀ ██▀▄█▀▀█ ▄▀▄█▄ █▄ ████
████▀███▀▀▄▀ ▀ █ ▄▀▄█ █▀██▀▀▄▀██ ▀▀▄▀█ ▀ ▀ ▄ ▀ ▀▄█▀█▄█ ▄▀ █▀▄ ██▄█▀▀▀ ████
████▄ ▄▄▄▀▄▀▄ █▄ █▀ ▄▀▄ █▄▄▀ ▄▀█▄▀█▀▀ █▀ █ █▄▄ ▀▀ █▄▄▀█ █▀ ▀ ▀▀▄ ▄ ▄█████
████ ▄▀█ █▄▀▄▀▄ ▄▄▄▀▄▄▀ █▀ ▄█▀▄█▄▄█ ▄▀▄ █▀█▀▀█▀█▀█ ▀ ▀▀▄█▀▄▄ ▄▄█▀ █▄█ ████
████▀ █ ▀█▄▄█▄▀▄ █▄▄ █▀█▄█ ▀█▄▄▀▀█ ▄▀▀▄▄▄▄▀█▄▄▀█ ▀█▄ ▄ ▀█▄▀█▄█▀▄▄ ▄█▀████
████ ▄ ▄ ▄█▀▀▀▄ ███ █▄▄█ █▄▀██▀▄████▄█▄██▄█▀▀▄ █▄▀ █▀▄█▀█ ▄█▄█▀ ▀██▄▀████
████ █▄█▄▄▄▄ ▄▄███▀▄▄█ ▄▀▄▄█ ▄█ ▀▄▄▀▄█▀▀█▀▄▄▄█▀█▀ ▀ █▀ ▄▀▀ ▀ █▀ ▄ ▄ ▄ ████
████▄██▄▄█▄▄ ▄▄ █▀▄█▄█ ██ ▄▀█████▀▀ ▄▄▄ ▄▀▄█▀▀ ▀█▀▀▄█▄ ▄▄ █ █▄▀ ▄▄▄ ▄▄█▄████
████ ▄▄▄▄▄ ██ █▄▄▀▄ █▀▀▄▄█▄ ▄▄▀ ▀▀██ █▄█ ▀██ ▄▀▄█▀ ████▀▄██▄█▀█▄ █▄█ ▀▄▀████
████ █ █ █▀▀▄█ ▄▄█ █ ▄▄█▄ ██▄▄▀▀█▄▄▄ █▄▄▀█▄█▄▄▄ ▀ ▀ ▀▀▄█▀▄ ▀ ▄▄ █▄▀▄████
████ █▄▄▄█ █ ▄█ ▄▀ █ █▀▄▀▄█ ▀▀▀▀██ █▄ █▀▀ █ ▀▄▀▄▀█▀ ▄█▀▀ █▀▄▄ ▀▄▄ █▀ ▀█▀████
████▄▄▄▄▄▄▄█▄███▄▄██▄▄▄▄▄█▄█▄█▄▄█▄▄▄▄█▄█▄▄█▄▄▄█▄▄█▄███▄█▄████▄█▄██▄█▄█▄██████
█████████████████████████████████████████████████████████████████████████████
████████████████████████████████████████████████████████████████████████████
@jamacoe
Copy link

jamacoe commented Mar 11, 2023

I'm new to WireGuard and this is just a fantastic help. Thanks.

@genieai-vikas
Copy link

@chrisswanda Can a single configuration file be used by multiple users, say, five users sharing the same configuration file? The use case is as follows: I am using the GitHub Action matrix, where the GitHub Action machine may have any IP address, making it difficult to whitelist those IPs in my database. Therefore, I am using a VPN, but providing a separate configuration file for each machine is challenging. Instead, can I create a single configuration file for all GitHub machines to use?

@chrisswanda
Copy link
Author

I would never reuse credentials; it is not a good operational practice. How is providing a separate configuration file challenging, versus if one of your credentials get compromised, and now you have to rotate out your single config on multiple machines versus changing a compromised credential on one machine? Merely curious. If you have to chop down a tree in 6 hours, spend 5 hours sharpening your axe.

But yes, you could use the same config on multiple machines. You are only using public/private key pairs.

@genieai-vikas
Copy link

@chrisswanda It's challenging and very complicated. Here is how
I have used the sharding technique in my BE and UI Tests and run my test parallelly. So GitHub action on the fly create job(machine).

On the contrary, it would be easy for me to rotate the GitHub config file if I am using one config. Instead of 20 config files for GitHub action

@chrisswanda
Copy link
Author

If you are running that many machines, you might want to look into something else, but that is another conversation.

But, if merely changing out a config file works and you are comfortable with using one credential, then it should work. It is merely a public/private keypair.

@thirupathicys
Copy link

Hi Chriss,
How to configure the wireguard VPN server in the load balancing scenario with multiple vpn servers in active-active mode ?. Wireguard peers should communicate between each other through multiple vpn server placed behind the udp load balancer?

@tabatinga0xffff
Copy link

In 10.0.0.x/32 is the x literally x? Or should I substitute it with a number?

@Dave9111
Copy link

Dave9111 commented Oct 18, 2023 via email

@chrisswanda
Copy link
Author

In 10.0.0.x/32 is the x literally x? Or should I substitute it with a number?

@tabatinga0x00 x would be whatever number you wish between 2 and 254.

@Dave9111
Copy link

Dave9111 commented Oct 18, 2023 via email

@Roy-Orbison
Copy link

From the Arch Wiki, use

wg genkey | (umask 077 && tee privatekey) | wg pubkey > publickey

So the private key is created not readable to others.

@dhackney
Copy link

dhackney commented Jan 3, 2025

This is a great concise setup guide. Thanks for posting and maintaining it.

For those new to WireGuard and/or networking, some additional comments in the config files may be helpful:

#*******************************************
#
# server config

[Interface]
# This is the server config file, so the [Interface] is on the server

# PrivateKey is the server private key generated during setup
PrivateKey = copy-and-paste-the-server-private-key-here 

# Address is the server's VPN IP address and subnet range; /24 is 254 available addresses
Address = 172.16.2.1/24

#ListenPort is the server UDP port; for cloud implementations, open this port in the server's security group
ListenPort = 51820

#DNS is the server's DNS resolvers; the 1.1.1.1 and 1.0.0.1 DNS resolvers are hosted by Cloudflare
DNS = 1.1.1.1, 1.0.0.1

# PostUp and PostDown commands for iptables
# The next two commands open and close the required iptables routing rules on the server
# When the server's WireGuard network interface is up, the PostUp command is executed
# When the server's WireGuard network interface is down, the PostDown command is executed
# >>> Important <<< ensure that your server's network interface name is correct in the next two commands
PostUp   = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o copy-and-paste-the-server-network-interface-name-here -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o copy-and-paste-the-server-network-interface-name-here -j MASQUERADE




# >>> Important <<< each client needs a [Peer] section with a unique AllowedIP VPN IP address

[Peer]
# Peer/client #1
# This is the server config file, so the [peer] is the client, e.g., your laptop

# PublicKey is the public key of the client; on some clients, this is automatically generated by the client WireGuard app
PublicKey = copy-and-paste-the-client-public-key-here

# AllowedIPs is the client VPN IP address; /32 is one specific IP address
# >>> Important <<< each client needs a unique AllowedIP VPN IP address, e.g., 172.16.2.2/32, 172.16.2.3/32, 172.16.2.4/32, etc.
AllowedIPs = 172.16.2.2/32



[Peer]
# Peer/client #2
# This is the server config file, so the [peer] is the client, e.g., your laptop

# PublicKey is the public key of the client; on some clients, this is automatically generated by the client WireGuard app
PublicKey = copy-and-paste-the-client-public-key-here

# AllowedIPs is the client VPN IP address; /32 is one specific IP address
# >>> Important <<< each client needs a unique AllowedIP VPN IP address, e.g., 172.16.2.2/32, 172.16.2.3/32, 172.16.2.4/32, etc.
AllowedIPs = 172.16.2.3/32




#*******************************************
#
# client config

[Interface]
# This is the client config file, so the [Interface] is on the client, e.g., your laptop

#Address is the client VPN IP address; /32 is one specific IP address
# >>> Important <<< each client needs a unique VPN IP address, e.g., 172.16.2.2/32, 172.16.2.3/32, 172.16.2.4/32, etc.
Address = 172.16.2.2/32

# PrivateKey is the client private key; on some clients, this is automatically generated by the client WireGuard app
PrivateKey = '>>>DO NOT<<<' overwrite the client app automatically generated client private key here; if there is no automatically generated client private key, copy-and-paste-the-client-private-key-here



[Peer]
# This is the client config file, so the [Peer] is the server

# PublicKey is the server's public key generated during the server WireGuard setup process
PublicKey = copy-and-paste-the-server-public-key-here

# Endpoint is the server's public IP address
Endpoint = copy-and-paste-the-server-public-IP-address-here:51820

# AllowedIPs: controls which network traffic enters and leaves the client 
# AllowedIPs: acts as a routing table when sending and an Access Control List (ACL) when receiving
# AllowedIPs: for client-to-Internet-VPN scenario, use: 0.0.0.0/0, ::/0
# AllowedIPs: 0.0.0.0/0, ::/0 allows traffic from any source to any target
# AllowedIPs: 0.0.0.0/0, ::/0 allows traffic to and from the entire internet
# AllowedIPs: for client-to-server(s)-VPN scenario, use: server.IP.address, server(s).subnet.CIDR 
# AllowedIPs: client-to-server(s)-VPN scenario example: 172.16.2.1/32, 10.2.1.0/16
# AllowedIPs: 172.16.2.1/32, 10.2.1.0/16 allows traffic to and from a WireGuard server at 172.16.2.1 and any server/device in the 10.2.1.0/16 subnet
# AllowedIPs: /16 is 65,534 available IP addresses
AllowedIPs = 0.0.0.0/0, ::/0

# PersistentKeepalive is for a Network Address Translation (NAT) scenario; it keeps the client connection to the server alive
PersistentKeepalive = 25


@spaskol
Copy link

spaskol commented Jan 24, 2025

Thank you very much for this git! I used it for my git. If you don't allow I will remove it. https://github.com/spaskol/dobarbobar/blob/master/06-wireguard-setup.md

@spaskol
Copy link

spaskol commented Jan 24, 2025

This is a great concise setup guide. Thanks for posting and maintaining it.

For those new to WireGuard and/or networking, some additional comments in the config files may be helpful:

Can I include some of your config in my git? https://github.com/spaskol/dobarbobar/blob/master/06-wireguard-setup.md I will quote you

@dhackney
Copy link

Can I include some of your config in my git? https://github.com/spaskol/dobarbobar/blob/master/06-wireguard-setup.md I will quote you

You are welcome to use it

@timinski
Copy link

Your write-up is terrific, thank you!

Would you have a version available for nftables versioned systems? Thanks for such if you do!

@johnaaronrose
Copy link

I'm using Ubuntu 24.04 and following instructions at Install Wireguard on 24.04 I want multiple clients. So I've created a conf file for each client with different Address e.g.

[Interface]
PrivateKey = ***   # Client-Private-Key
Address = 10.8.0.2/24
DNS = 8.8.8.8

[Peer]
PublicKey = ***     # Server-Public-Key
AllowedIPs = 0.0.0.0/0
Endpoint = roseserver.mywire.org:51820
PersistentKeepalive = 15

My wg0.conf file has different AllowedIPs for each client:

[Interface]
Address = 10.8.0.1/24
SaveConfig = true
PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on eth0
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = ***

[Peer]
PublicKey = ***
AllowedIPs = 10.8.0.2/32

[Peer]
PublicKey = ***
AllowedIPs = 10.8.0.3/32

The wg-quick@wg0 service starts Ok and shows Status except that it displays:

Aug 06 13:51:43 raspberrypi systemd[1]: Finished [email protected] - WireGuard via wg-quick(8) for wg0"

Also, the wg0.conf file is changed with one of the Allowed IPs being removed!

I have tried to find a channel for WireGuards issues without success. Any ideas please?

@spaskol
Copy link

spaskol commented Aug 7, 2025

I'm using Ubuntu 24.04 and following instructions at Install Wireguard on 24.04 I want multiple clients. So I've created a conf file for each client with different Address e.g.

[Interface]
PrivateKey = ***   # Client-Private-Key
Address = 10.8.0.2/24
DNS = 8.8.8.8

[Peer]
PublicKey = ***     # Server-Public-Key
AllowedIPs = 0.0.0.0/0
Endpoint = roseserver.mywire.org:51820
PersistentKeepalive = 15

My wg0.conf file has different AllowedIPs for each client:

[Interface] Address = 10.8.0.1/24 SaveConfig = true PostUp = ufw route allow in on wg0 out on eth0 PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE PreDown = ufw route delete allow in on wg0 out on eth0 PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE ListenPort = 51820 PrivateKey = ***

[Peer] PublicKey = *** AllowedIPs = 10.8.0.2/32

[Peer] PublicKey = *** AllowedIPs = 10.8.0.3/32

The wg-quick@wg0 service starts Ok and shows Status except that it displays:

Aug 06 13:51:43 raspberrypi systemd[1]: Finished [email protected] - WireGuard via wg-quick(8) for wg0"

Also, the wg0.conf file is changed with one of the Allowed IPs being removed!

I have tried to find a channel for WireGuards issues without success. Any ideas please?

Could you check your output of 'sudo wg'? The status of the service seems to be OK to me. You should check if your keys are correct.

@johnaaronrose
Copy link

sudo wg confirms problem:
interface: wg0
public key: ***
private key: (hidden)
listening port: 51820

peer: ***
allowed ips: (none)

peer: *
allowed ips: 10.8.0.2/32

I'll look into the keys again.

@GildedHonour
Copy link

GildedHonour commented Aug 7, 2025

@johnaaronrose

[Interface]
Address = 10.8.0.1/24
SaveConfig = true
PostUp = ufw route allow in on wg0 out on eth0
PostUp = iptables -t nat -I POSTROUTING -o eth0 -j MASQUERADE
PreDown = ufw route delete allow in on wg0 out on eth0
PreDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
ListenPort = 51820
PrivateKey = ***

the 2nd PostUp will overwrite the 1st one. Not? The same for PostDown.

@johnaaronrose
Copy link

I've just generated the first client private key again (after deleting the client keys & conf in /etc/wireguard/) but even though I disable & stop the wg0 service (confirmed by ifconfig not having wg0 on its interfaces), starting wg0 again shows:
root@raspberrypi:/etc/wireguard# sudo wg show wg0
interface: wg0
public key: 1p55Z0/9gejgonpMZlG0GrPLpu/elHCEeymcHrzdRiQ=
private key: (hidden)
listening port: 51820

peer: ***
allowed ips: (none)

peer: ***
allowed ips: 10.8.0.2/32

Where does this memory of the previous 2 clients come from?
I think I'll have to remove the wireguard package on the server and start again. What a pain!

@johnaaronrose
Copy link

Even after purging the wireguard package still getting the 2 interfaces on the show command!

@chrisswanda
Copy link
Author

Have you stopped the Wireguard service? Is it still running?

sudo systemctl status [email protected]

@johnaaronrose
Copy link

I did stop it:
Aug 11 11:36:27 raspberrypi systemd[1]: Stopping [email protected] - WireGuard >
Aug 11 11:36:27 raspberrypi wg-quick[500702]: [#] ufw route delete allow in on wg0>
Aug 11 11:36:28 raspberrypi wg-quick[500709]: Rule deleted
Aug 11 11:36:28 raspberrypi wg-quick[500709]: Rule deleted (v6)
Aug 11 11:36:28 raspberrypi wg-quick[500702]: [#] iptables -t nat -D POSTROUTING ->
Aug 11 11:36:28 raspberrypi wg-quick[500778]: [#] wg showconf wg0
Aug 11 11:36:28 raspberrypi wg-quick[500702]: [#] ip link delete dev wg0
Aug 11 11:36:28 raspberrypi systemd[1]: [email protected]: Deactivated successf>
Aug 11 11:36:28 raspberrypi systemd[1]: Stopped [email protected] - WireGuard v>
Aug 11 11:36:28 raspberrypi systemd[1]: [email protected]: Consumed 1.156s CPU

@chrisswanda
Copy link
Author

It's hard to say with what provided....

what do you get when you run a sudo wg showconf wg0

when wireguard is running, what interface is it showing? sudo wg |grep interface

What does journalctl show?

Just trying to get a grasp on what might be going on. Wireguard is just a standard service, nothing too complex or strange.

@johnaaronrose
Copy link

Here are results:
root@raspberrypi:/etc/wireguard# sudo wg showconf wg0
[Interface]
ListenPort = 51820
PrivateKey = ***

[Peer]
PublicKey =***
AllowedIPs = 10.8.0.2/32

root@raspberrypi:/etc/wireguard# sudo wg |grep interface
interface: wg0

The journalctl output is 2.5MB, so haven't attached it: I don't see any problems in it to do with wireguard.
So now wg0,conf etc seem to be correct. Can't figure out why the problem occurred and then got corrected. Now I will generate the 2nd client's keys and conf and amend the wg0.conf file accordingly.

@chrisswanda
Copy link
Author

Right on.

@johnaaronrose
Copy link

Chris,
Thanks for the help. The wireguard service now starts OK. I just tried it on my phone usin the public wifi in a supermarket. There's a repetition of the following lines:
08-11 16:52:12.460 6749 6749 I InputTransport: Create ARC handle: 0xb400007c87454320 08-11 16:52:12.466 6749 6749 I wm_on_top_resumed_gained_called: [203408990,com.wireguard.android.activity.LogViewerActivity,topStateChangedWhenResumed] 08-11 16:52:12.838 6749 6749 I wm_on_stop_called: [68814221,com.wireguard.android.activity.SettingsActivity,STOP_ACTIVITY_ITEM] 08-11 16:52:12.839 6749 6749 V PhoneWindow: DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@255cf9d, this = DecorView@13afd86[SettingsActivity] 08-11 16:52:15.243 6749 6749 I menu_item_selected: [0,Export log file] 08-11 16:52:18.114 6749 6749 I wm_on_top_resumed_lost_called: [203408990,com.wireguard.android.activity.LogViewerActivity,topStateChangedWhenResumed] 08-11 16:52:18.115 6749 6749 I wm_on_paused_called: [203408990,com.wireguard.android.activity.LogViewerActivity,performPause] 08-11 16:52:18.136 6749 6749 I wm_on_restart_called: [68814221,com.wireguard.android.activity.SettingsActivity,performRestartActivity] 08-11 16:52:18.138 6749 6749 I wm_on_start_called: [68814221,com.wireguard.android.activity.SettingsActivity,handleStartActivity] 08-11 16:52:18.138 6749 6749 V PhoneWindow: DecorView setVisiblity: visibility = 0, Parent = android.view.ViewRootImpl@255cf9d, this = DecorView@13afd86[SettingsActivity] 08-11 16:52:18.138 6749 6749 I wm_on_resume_called: [68814221,com.wireguard.android.activity.SettingsActivity,RESUME_ACTIVITY] 08-11 16:52:18.138 6749 6749 I wm_on_top_resumed_gained_called: [68814221,com.wireguard.android.activity.SettingsActivity,topWhenResuming] 08-11 16:52:18.138 6749 6749 V PhoneWindow: DecorView setVisiblity: visibility = 0, Parent = android.view.ViewRootImpl@255cf9d, this = DecorView@13afd86[SettingsActivity] 08-11 16:52:18.517 6749 6749 I wm_on_stop_called: [203408990,com.wireguard.android.activity.LogViewerActivity,LIFECYCLER_STOP_ACTIVITY] 08-11 16:52:18.518 6749 6749 V PhoneWindow: DecorView setVisiblity: visibility = 4, Parent = android.view.ViewRootImpl@f81e623, this = DecorView@a933b4[LogViewerActivity] 08-11 16:52:18.519 6749 6749 I wm_on_destroy_called: [203408990,com.wireguard.android.activity.LogViewerActivity,performDestroy] 08-11 16:52:18.528 6749 6749 I InputTransport: Destroy ARC handle: 0xb400007c87454320 08-11 16:52:20.795 6749 6749 I wm_on_top_resumed_lost_called: [68814221,com.wireguard.android.activity.SettingsActivity,topStateChangedWhenResumed] 08-11 16:52:20.796 6749 6749 I wm_on_paused_called: [68814221,com.wireguard.android.activity.SettingsActivity,performPause] 08-11 16:52:20.825 6749 6749 I wm_on_create_called: [42336915,com.wireguard.android.activity.LogViewerActivity,performCreate] 08-11 16:52:20.828 6749 6749 I wm_on_start_called: [42336915,com.wireguard.android.activity.LogViewerActivity,handleStartActivity] 08-11 16:52:20.828 6749 6749 I wm_on_resume_called: [42336915,com.wireguard.android.activity.LogViewerActivity,RESUME_ACTIVITY]

Does that mean that wireguard is running Ok?
Interestingly, there is no log file created in /var/log for wireguard.

@chrisswanda
Copy link
Author

Do you have any services running on your local network to test? Or why are you implementing Wireguard to begin with?

The best thing to do, is connect to the macro network with your device (since this appears to be an Android device) and check what your IP address while on the macro network. Or if you have services running on your local network, see if you can connect to them.

You can verify when connected to Wireguard by checking the output of sudo wg show. It'll show the peers and their connection status/data transfer.

@johnaaronrose
Copy link

The reason that I'm implementing WireGuard is mainly to do financial stuff when using a public network. It would also be useful to use BBC iPlayer when out of UK. "sudo wg show", when using phone signal on my phone at home, gives:
manager@raspberrypi:~$ sudo wg show
interface: wg0
public key: ***
private key: (hidden)
listening port: 51820

peer: ***
allowed ips: 10.8.0.2/32

peer: ***
allowed ips: 10.8.0.3/32

So it appears that WireGuard 's service is running Ok on my Raspberry Pi.

However, WireGuard's application log shows repeatedly, with appropriate client conf file being used by WireGuard client on my Android phone:
08-12 07:30:27.732 6749 6822 D WireGuard/GoBackend/rose: peer(1p55…dRiQ) - Handshake did not complete after 5 seconds, retrying (try 2)
08-12 07:30:27.732 6749 6822 D WireGuard/GoBackend/rose: peer(1p55…dRiQ) - Sending handshake initiation
08-12 07:30:32.891 6749 6821 D WireGuard/GoBackend/rose: peer(1p55…dRiQ) - Sending handshake initiation
08-12 07:30:38.163 6749 6822 D WireGuard/GoBackend/rose: peer(1p55…dRiQ) - Sending handshake initiation

I don't test WireGuard with my phone connected to my home wifi as I think that that's not a true test and I also think that it wouldn't work (just like my access to my web server's website, also on my Raspberry Pi, doesn't work at home, perhaps due to my ISP preventing it).

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