WireGuard is celebrated for its simplicity, performance, and cryptographic clarity. Yet many deployments — particularly those serving businesses, developers, or multi-tenant hosting environments — require clients to receive predictable, static IP addresses. Assigning static IPs to WireGuard clients provides consistent routing, easier firewalling, reliable DNS records, and simpler access control. This article gives a practical, security-focused walkthrough for configuring WireGuard with static client IPs, including server and client examples, routing considerations, firewall rules, and operational tips.
Design considerations before you configure
Before touching configuration files, consider these architectural points:
- Address plan: Choose an internal subnet that won’t conflict with networks the clients need to access (for example, 10.99.0.0/24 rather than 10.0.0.0/8 if you anticipate conflicts).
- Static vs. reserved assignment: WireGuard does not include a DHCP server — IPs are set in client configs. You can enforce and document static allocations centrally (recommended) or use some automation to generate per-client configs.
- Mapping and access control: Decide how clients are mapped to services. You can restrict AllowedIPs per client to limit what they can access through the tunnel.
- Key lifecycle: Generate unique keypairs for each client and store private keys securely. Rotate keys on schedule or upon compromise.
Basic server prerequisites
The following assumes a Linux server (Debian/Ubuntu/CentOS) with WireGuard installed and kernel module available (wireguard or wireguard-go). Also ensure IP forwarding is enabled system-wide:
sysctl -w net.ipv4.ip_forward=1
To make it persistent:
echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
Or edit a sysctl.d file. If you need IPv6 forwarding, enable net.ipv6.conf.all.forwarding=1 as well.
Server configuration example
Below is a minimal but practical /etc/wireguard/wg0.conf layout. This example uses UDP port 51820 and a 10.99.0.0/24 tunnel. The server reserves .1, and clients get static addresses in the same /24.
[Interface]
Address = 10.99.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
SaveConfig = true
PostUp/PostDown to set NAT and firewall rules (iptables example)
PostUp = iptables -t nat -A POSTROUTING -s 10.99.0.0/24 -o eth0 -j MASQUERADE
PostDown = iptables -t nat -D POSTROUTING -s 10.99.0.0/24 -o eth0 -j MASQUERADE
Peer entries follow...
Notes:
- Set SaveConfig=true if you plan to add/remove peers with wg commands and want WireGuard to persist them.
- Replace
eth0with your server’s outbound interface. - Consider nftables or firewalld instead of iptables depending on your environment.
Adding static-IP clients (server-side)
On the server, each peer block determines which public key is allowed and which AllowedIPs the peer may claim. For static IP assignments, set the client IP inside the AllowedIPs field as a /32 (IPv4) or /128 (IPv6). The server does not assign — AllowedIPs enforces what address the peer may use.
[Peer]
Client A
PublicKey = <CLIENT_A_PUBLIC_KEY>
AllowedIPs = 10.99.0.10/32
[Peer]
Client B
PublicKey = <CLIENT_B_PUBLIC_KEY>
AllowedIPs = 10.99.0.11/32
When a client connects, WireGuard will accept traffic only if the packet originates from the peer with the listed public key and source IP matches an entry under AllowedIPs.
Dynamic peer management
To add a peer without editing wg0.conf directly, use wg or wg-quick commands:
wg set wg0 peer <CLIENT_PUBKEY> allowed-ips 10.99.0.12/32
wg-quick save wg0 # if SaveConfig=true and you want to persist
Use wg show to inspect handshake times and transfer stats.
Client configuration — setting the static IP
On each client, the static address is declared in the [Interface] Address field. Here’s a minimal client config for Client A:
[Interface]
PrivateKey = <CLIENT_A_PRIVATE_KEY>
Address = 10.99.0.10/32
DNS = 10.99.0.1 # optional, if your server runs DNS resolver
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
Endpoint = vpn.example.com:51820
AllowedIPs = 0.0.0.0/0, ::/0 # or a narrower subset
PersistentKeepalive = 25
Key points:
- Address is where you specify the static VPN IP. Make sure it matches a /32 that the server has in AllowedIPs.
- Set PersistentKeepalive (typically 25 seconds) for clients behind NAT so the server can reach them and keep the NAT mapping alive.
- AllowedIPs on the client determines what traffic is routed into the tunnel. For split-tunnel, provide specific prefixes; for full-tunnel, use 0.0.0.0/0 and ::/0.
Routing and firewall best practices
When enabling internet routing via the VPN:
- Use PostUp/PostDown to manage NAT rules on the server. For nftables, create equivalents so your rules survive restarts/updates.
- Add iptables/nftables rules to accept forwarded traffic between the wireguard interface and your WAN interface only for the tunnel subnet.
- Limit what each client can access by tightening AllowedIPs on the server. For example, if Client B should only access a specific internal subnet, set AllowedIPs=B: 10.10.10.0/24 on the server and on the client push routes accordingly.
- Guard management ports and SSH. Prefer a separate management network or restrict access to static client IPs for administration.
Example firewall snippet (iptables)
# Accept forwarding for wireguard
iptables -A FORWARD -i wg0 -o eth0 -s 10.99.0.0/24 -m conntrack --ctstate NEW,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o wg0 -d 10.99.0.0/24 -m conntrack --ctstate ESTABLISHED -j ACCEPT
Adopt equivalent nftables rules if your distro uses nftables by default.
DNS and service discovery
With static IPs, you can assign stable DNS records for clients, improving service discovery and access control. You can run an internal resolver (Unbound, dnsmasq) on the server and point clients to it via the client DNS config line. For dynamic updates, maintain your DNS records in automation or configuration management that generates client configs.
Security hardening and operational tips
- Per-peer pre-shared keys: Optionally use pre-shared symmetric keys (psk) for an extra layer of defense (PSK with Noise protocol). Generate one for each peer with wg genpsk and include it on both sides:
PresharedKey = <PSK>. - Key management: Keep private keys only on the device that owns them. Use secure storage and limit access. Rotate keys on suspicion of compromise.
- Monitor connectivity: Use
wg showand system metrics to detect inactive or failing peers. Consider automated alerts for long handshake absence. - Automate config generation: For teams or many clients, script key generation and config templating to avoid mistakes and ensure address uniqueness.
- Audit firewall rules regularly: Ensure that NAT and forwarding rules haven’t drifted and that only expected subnets are reachable via the tunnel.
Troubleshooting common issues
If a client cannot reach resources or the server:
- Confirm client Address matches a /32 listed in server AllowedIPs.
- Ensure server has IP forwarding enabled and NAT rules applied if internet routing is expected.
- Check PersistentKeepalive for NATed clients so the server can reach them.
- Use tcpdump/tshark on the server to verify incoming UDP handshake packets from the client’s public IP/port.
- Verify no IP address overlap exists between the tunnel subnet and either side’s physical networks — overlapping addresses break routing.
Scaling patterns
For large deployments (hundreds+ clients), consider these strategies:
- Configuration templating and inventory: Use CM tools (Ansible, Terraform, or bespoke scripts) to generate configs and maintain an inventory of assigned IPs.
- Dynamic peer endpoints: Many peers will be mobile and get new public endpoints; rely on the persistent AllowedIPs and keepalives rather than static endpoints.
- Multiple servers: Use multiple WireGuard servers in different regions or AZs. Consider orchestration for config distribution and key rotation.
- Centralized logging/monitoring: Aggregate WireGuard stats and logs to detect anomalies.
Assigning static IPs to WireGuard clients is conceptually simple: put the desired IP on the client and enforce it on the server using AllowedIPs. The operational complexity grows with scale and security requirements, but the payoff is predictable routing, easier firewall rules, and reliable service access. With proper key management, firewall hygiene, and automation, WireGuard with static client IPs becomes a robust solution for businesses, developers, and operators.
For more practical guides and managed static-IP VPN options, visit Dedicated-IP-VPN at https://dedicated-ip-vpn.com/.