LFCE 89 ๐ง WireGuard โ Configuration and Peers
WireGuard configuration is stored in a file that the wg-quick tool reads to create the interface, assign the addresses, set the routes, and run the pre/post scripts. The previous chapter covered the protocol concepts; this chapter covers the file format, the peer definitions, the AllowedIPs semantics that serve as both routing table and access control, and the hub-and-spoke pattern that scales a single server to many clients. The LFCE exam expects the candidate to configure network traffic tunneling, and wg-quick is the standard tool for persistent configuration.
The configuration file is divided into an [Interface] section and one or more [Peer] sections. The [Interface] section contains the private key, the address, the listening port, and the optional PostUp/PostDown scripts. The [Peer] section contains the peer’s public key, the AllowedIPs, the optional endpoint, and the optional PersistentKeepalive. The wg-quick up wg0 command reads /etc/wireguard/wg0.conf, creates the interface, and applies the configuration . The wg-quick down wg0 command removes the interface and runs the PostDown scripts.
Key point: The AllowedIPs in a peer section is both the routing table and the access control list. On the sending side, a packet whose destination matches the peer’s allowed IPs is encrypted and sent to that peer. On the receiving side, a packet from that peer is accepted only if its source address matches the peer’s allowed IPs. A peer that should receive all traffic has AllowedIPs = 0.0.0.0/0, and a peer that should receive only a specific subnet has the subnet in the list .
Why the configuration file requires careful peer definitions
The server-side problem.
A WireGuard server has one [Interface] section and one [Peer] section per client. Each client’s AllowedIPs is the client’s tunnel address, typically a /32, and the server’s [Interface] address is the gateway for the tunnel subnet. The server must enable IP forwarding and add the PostUp rules that forward the traffic between the tunnel and the physical interface, or the clients can reach the server but not the network behind it . The client’s configuration points to the server’s public key and endpoint, and its AllowedIPs is either the tunnel subnet for a split tunnel or 0.0.0.0/0 for a full tunnel .
The hub-and-spoke problem.
A WireGuard network can be a full mesh, where every peer has every other peer’s public key and endpoint, or a hub-and-spoke, where every client connects to a central server and the server forwards the traffic between the clients. The full mesh is configuration-intensive because every new peer must be added to every existing peer. The hub-and-spoke is simpler because the clients only know the server, and the server knows all the clients . The server needs the iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT rule to allow the client-to-client traffic, or a network namespace to isolate the mesh .
The peer-roaming problem.
A client with a dynamic IP address does not have a fixed endpoint in the server’s configuration. The server’s [Peer] section for that client has no Endpoint line, and the client’s [Interface] section has no ListenPort or a fixed port. The client initiates the handshake to the server, and the server learns the client’s endpoint from the source address of the handshake packet . The PersistentKeepalive = 25 on the client keeps the NAT mapping alive, and the server updates the endpoint when the client’s address changes.
a. The server configuration
The server configuration defines the tunnel address, the listening port, the private key, and the peer entries for each client. The PostUp and PostDown scripts configure the forwarding and NAT rules.
# /etc/wireguard/wg0.conf (server)
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-private-key>
# Forward traffic from the tunnel to the physical interface
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
# Client 1
PublicKey = <client1-public-key>
AllowedIPs = 10.0.0.2/32
[Peer]
# Client 2
PublicKey = <client2-public-key>
AllowedIPs = 10.0.0.3/32
The Address = 10.0.0.1/24 is the server’s tunnel address and the gateway for the clients. The PostUp scripts add the forwarding rules and the NAT rule that masquerades the tunnel traffic as the server’s physical address . The %i is expanded to the interface name (wg0). The two [Peer] sections define the clients, each with its public key and its tunnel address as the AllowedIPs. The server does not need an Endpoint for the clients, because the clients initiate the connection.
b. The client configuration
The client configuration defines the client’s tunnel address, its private key, and the server peer with the endpoint and the allowed IPs.
# /etc/wireguard/wg0.conf (client)
[Interface]
Address = 10.0.0.2/32
PrivateKey = <client-private-key>
DNS = 10.0.0.1
[Peer]
PublicKey = <server-public-key>
Endpoint = 203.0.113.5:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
The Address = 10.0.0.2/32 is the client’s tunnel address. The DNS = 10.0.0.1 tells wg-quick to use the server as the DNS resolver, which is optional. The [Peer] section points to the server’s public key and endpoint. The AllowedIPs = 10.0.0.0/24 is a split tunnel: only the traffic to the tunnel subnet goes through the VPN . For a full tunnel, the AllowedIPs is 0.0.0.0/0, ::/0, which routes all the traffic through the VPN. The PersistentKeepalive = 25 keeps the NAT mapping alive when the client is behind a NAT .
c. The hub-and-spoke and site-to-site patterns
A hub-and-spoke network uses a central server to connect the clients. The clients have the server’s public key and endpoint, and the server has each client’s public key and tunnel address. The client-to-client traffic goes through the server, and the server needs the forwarding rule to allow it.
# Server: allow client-to-client traffic
PostUp = iptables -A FORWARD -i %i -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -o %i -j ACCEPT
The -i %i -o %i rule allows the traffic that enters and leaves the same interface, which is the client-to-client traffic . Without it, the server forwards the client traffic to the physical network but not to the other clients.
A site-to-site tunnel connects two networks, such as an office LAN and a cloud VPC. The gateway on each side has a [Peer] section for the other gateway, and the AllowedIPs includes the remote subnet.
# Office gateway peer for the cloud
[Peer]
PublicKey = <cloud-gateway-public-key>
Endpoint = cloud.example.com:51820
AllowedIPs = 10.0.0.0/24, 192.168.50.0/24
The AllowedIPs includes both the tunnel subnet and the remote LAN subnet, which tells the gateway to route the traffic for both through the tunnel . The cloud gateway’s AllowedIPs for the office peer includes the office LAN subnet, so the return traffic is routed correctly.
Complete Example Session
# ============================================
# PART 1: GENERATE THE SERVER KEYS
# ============================================
umask 077
wg genkey | tee /etc/wireguard/server-private.key | wg pubkey > /etc/wireguard/server-public.key
# ============================================
# PART 2: GENERATE THE CLIENT KEYS
# ============================================
wg genkey | tee /etc/wireguard/client1-private.key | wg pubkey > /etc/wireguard/client1-public.key
# ============================================
# PART 3: CREATE THE SERVER CONFIGURATION
# ============================================
sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = $(cat /etc/wireguard/server-private.key)
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -A FORWARD -o %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT
PostDown = iptables -D FORWARD -o %i -j ACCEPT
PostDown = iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
PublicKey = $(cat /etc/wireguard/client1-public.key)
AllowedIPs = 10.0.0.2/32
EOF
# ============================================
# PART 4: ENABLE IP FORWARDING
# ============================================
sudo sysctl -w net.ipv4.ip_forward=1
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
# ============================================
# PART 5: START THE SERVER
# ============================================
sudo wg-quick up wg0
sudo wg show
# Output shows the interface and the peer
# ============================================
# PART 6: CREATE THE CLIENT CONFIGURATION
# ============================================
sudo tee /etc/wireguard/wg0.conf > /dev/null <<EOF
[Interface]
Address = 10.0.0.2/32
PrivateKey = $(cat /etc/wireguard/client1-private.key)
DNS = 10.0.0.1
[Peer]
PublicKey = $(cat /etc/wireguard/server-public.key)
Endpoint = 203.0.113.5:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
EOF
# ============================================
# PART 7: START THE CLIENT
# ============================================
sudo wg-quick up wg0
sudo wg show
# Output shows the peer with the latest handshake
# ============================================
# PART 8: TEST THE TUNNEL
# ============================================
ping -c 2 10.0.0.1
# The tunnel is up
# ============================================
# PART 9: ADD A SECOND CLIENT
# ============================================
# On the server, add the second peer to the configuration
# Then reload the configuration
sudo wg set wg0 peer $(cat /etc/wireguard/client2-public.key) allowed-ips 10.0.0.3/32
# ============================================
# PART 10: CLEAN UP
# ============================================
sudo wg-quick down wg0
The ten parts demonstrate the complete WireGuard configuration: key generation, the server configuration, the forwarding enablement, the server start, the client configuration, the client start, the tunnel test, the second client, and the cleanup. The critical configuration is the AllowedIPs on each peer: the server allows the client’s tunnel address, and the client allows the server’s tunnel subnet.
Quick Reference
Configuration File Sections
| Section | Options |
|---|---|
[Interface] | Address, ListenPort, PrivateKey, PostUp, PostDown, DNS, MTU |
[Peer] | PublicKey, AllowedIPs, Endpoint, PersistentKeepalive, PresharedKey |
Key Commands
| Command | Purpose |
|---|---|
wg genkey | Generate a private key |
wg pubkey | Derive the public key |
wg-quick up wg0 | Create and start the interface |
wg-quick down wg0 | Stop and remove the interface |
wg show | Show the interface and peer status |
wg set | Modify the running interface |
AllowedIPs Patterns
| Pattern | Use Case |
|---|---|
10.0.0.2/32 | Server side: one client |
10.0.0.0/24 | Client side: split tunnel to the VPN subnet |
0.0.0.0/0, ::/0 | Client side: full tunnel |
10.0.0.0/24, 192.168.50.0/24 | Site-to-site: VPN subnet and remote LAN |
Hub-and-Spoke Rules
| Rule | Purpose |
|---|---|
iptables -A FORWARD -i %i -j ACCEPT | Forward from the tunnel |
iptables -A FORWARD -o %i -j ACCEPT | Forward to the tunnel |
iptables -A FORWARD -i %i -o %i -j ACCEPT | Client-to-client traffic |
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE | NAT the tunnel traffic |
Best Practices
โ Do This:
# Generate keys with umask 077
umask 077; wg genkey | tee private.key | wg pubkey > public.key # โ
# Use PostUp for the forwarding rules
PostUp = iptables -A FORWARD -i %i -j ACCEPT # โ
# Use PersistentKeepalive on the client behind NAT
PersistentKeepalive = 25 # โ
# Use split tunnel for the client unless full tunnel is needed
AllowedIPs = 10.0.0.0/24 # โ
# Enable IP forwarding on the server
sysctl -w net.ipv4.ip_forward=1 # โ
# Verify with wg show
wg show # โ
โ Don’t Do This:
# Share the private key between peers
# Each peer must have its own keypair # โ
# Forget the forwarding rules on the server
# The clients cannot reach the network behind the server # โ
# Use 0.0.0.0/0 on the client without a reason
# All traffic goes through the VPN # โ
# Forget PersistentKeepalive behind NAT
# The tunnel stops working when the NAT mapping expires # โ
# Forget to enable IP forwarding
# The tunnel is up but the traffic is not forwarded # โ
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
| Client cannot reach the internet | No NAT rule on the server | iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE |
| Client cannot reach other clients | No -i %i -o %i rule | Add the client-to-client rule |
| Tunnel drops behind NAT | No keepalive | PersistentKeepalive = 25 |
| Handshake does not complete | Wrong public key or endpoint | Verify the keys and the endpoint |
| Traffic not routed | AllowedIPs missing the subnet | Add the subnet to the peer’s allowed IPs |
Real-World Examples
1. Server interface
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <server-key>
2. Server peer
[Peer]
PublicKey = <client-key>
AllowedIPs = 10.0.0.2/32
3. Client interface
[Interface]
Address = 10.0.0.2/32
PrivateKey = <client-key>
4. Client peer (split tunnel)
[Peer]
PublicKey = <server-key>
Endpoint = 203.0.113.5:51820
AllowedIPs = 10.0.0.0/24
PersistentKeepalive = 25
5. Client peer (full tunnel)
AllowedIPs = 0.0.0.0/0, ::/0
6. Server PostUp rules
PostUp = iptables -A FORWARD -i %i -j ACCEPT
PostUp = iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
7. Site-to-site peer
[Peer]
PublicKey = <remote-gateway-key>
Endpoint = remote.example.com:51820
AllowedIPs = 10.0.0.0/24, 192.168.50.0/24
8. Start the interface
wg-quick up wg0
9. Show the status
wg show
10. Add a peer at runtime
wg set wg0 peer <public-key> allowed-ips 10.0.0.3/32
Visual
The Hub-and-Spoke Topology
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ CLIENTS CONNECT TO THE SERVER; SERVER FORWARDS BETWEEN THEM โ
โ โ
โ Client 1 (10.0.0.2) โ
โ โ โ
โ โ WireGuard tunnel โ
โ โผ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Server (10.0.0.1) โ โ
โ โ โโโ [Peer] Client 1 allowed-ips 10.0.0.2/32 โ โ
โ โ โโโ [Peer] Client 2 allowed-ips 10.0.0.3/32 โ โ
โ โ โโโ iptables -A FORWARD -i wg0 -o wg0 -j ACCEPT โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โ WireGuard tunnel โ
โ โผ โ
โ Client 2 (10.0.0.3) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The AllowedIPs Semantics
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ AllowedIPs IS ROUTING AND ACCESS CONTROL โ
โ โ
โ Server peer for client 1: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ AllowedIPs = 10.0.0.2/32 โ โ
โ โ โ sends packets for 10.0.0.2 to client 1 โ โ
โ โ โ accepts packets from client 1 with source 10.0.0.2 โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ
โ Client peer for server: โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ AllowedIPs = 10.0.0.0/24 โ โ
โ โ โ sends packets for the tunnel subnet to the server โ โ
โ โ โ accepts packets from the server with source in the โ โ
โ โ subnet โ โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
The Configuration File
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ [Interface] AND [Peer] SECTIONS โ
โ โ
โ [Interface] โ
โ โโโ Address = 10.0.0.1/24 โ
โ โโโ ListenPort = 51820 โ
โ โโโ PrivateKey = <server-key> โ
โ โโโ PostUp = iptables ... โ
โ โโโ PostDown = iptables ... โ
โ โ
โ [Peer] โ
โ โโโ PublicKey = <client-key> โ
โ โโโ AllowedIPs = 10.0.0.2/32 โ
โ โโโ Endpoint = <optional> โ
โ โโโ PersistentKeepalive = <optional> โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Configuration file | /etc/wireguard/wg0.conf |
[Interface] key | PrivateKey, Address, ListenPort |
[Peer] key | PublicKey, AllowedIPs, Endpoint |
AllowedIPs | Routing table and access control |
| Server forwarding | iptables -A FORWARD -i %i -j ACCEPT |
| Server NAT | iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE |
| Client keepalive | PersistentKeepalive = 25 |
| Split tunnel | AllowedIPs = 10.0.0.0/24 |
| Full tunnel | AllowedIPs = 0.0.0.0/0, ::/0 |
| Start command | wg-quick up wg0 |
| Status command | wg show |
Key takeaways:
- The configuration file is divided into
[Interface]and[Peer]sections. The[Interface]section contains the private key, the address, the listening port, and the optional scripts. The[Peer]section contains the peer’s public key, the allowed IPs, the endpoint, and the keepalive . - The
AllowedIPsis both the routing table and the access control list. On the sending side, it maps the destination to the peer. On the receiving side, it validates the source. A peer that should receive all traffic has0.0.0.0/0, and a peer that should receive only a subnet has the subnet . - The server needs the forwarding rules and the NAT rule. The
iptables -A FORWARD -i %i -j ACCEPTand-o %i -j ACCEPTrules allow the traffic to pass, and theMASQUERADErule rewrites the source address of the tunnel traffic to the server’s physical address . - The client behind a NAT needs
PersistentKeepalive = 25. The keepalive keeps the UDP mapping alive, and the server updates the client’s endpoint when the address changes . - The hub-and-spoke pattern uses the server as the central point. The clients only know the server’s public key and endpoint, and the server has each client’s public key and tunnel address. The
-i %i -o %irule allows the client-to-client traffic . - The
wg-quicktool manages the interface from the configuration file. Thewg-quick up wg0command creates the interface and applies the configuration, and thewg-quick down wg0command removes it and runs thePostDownscripts .
Remember: WireGuard configuration is a file with an [Interface] section and one or more [Peer] sections. The AllowedIPs is the routing table and the access control list. The server needs the forwarding and NAT rules to let the clients reach the network behind it. The client behind a NAT needs the keepalive. The hub-and-spoke pattern uses the server as the central point, and the client-to-client rule allows the clients to reach each other. The wg-quick tool manages the interface from the file. The result is a tunnel that is simple to configure, fast enough for line-rate traffic, and small enough to audit.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!