[GH-ISSUE #3261] AWG/WireGuard: new client IP is "last AllowedIPs in the file + 1", which hands out duplicate IPs when the server config is not sorted #1510

Open
opened 2026-10-13 20:44:04 +00:00 by bsakaguchi · 0 comments
Owner

Originally created by @dimkvin on GitHub (Oct 6, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amnezia-client/issues/3261

AWG/WireGuard: new client IP is "last AllowedIPs in the file + 1", which hands out duplicate IPs when the server config is not sorted

Environment

  • AmneziaVPN 5.0.3.0 (Linux desktop and Android)
  • Self-hosted server, AmneziaWG 3.1 (the container is named amnezia-awg2)
  • Code checked against dev at 3e9b70a

What happens

WireguardConfigurator::prepareWireguardConfig (client/core/configurators/wireguardConfigurator.cpp) picks the next client IP like this:

QString getIpsScript = QString("cat %1 | grep AllowedIPs").arg(configPath);   // line 128
...
lastIp = ips.last();                                                          // line 153
... result.setAddress(lastIp.toIPv4Address() + 1);

and then appends the new [Peer] to the end of the file (ScpAppendToExisting, line 190).

This only works while awg0.conf is sorted by IP and nothing has been re-added out of order. If the last [Peer] in the file has a lower IP than some earlier peer, the new client gets an address that is already in use. Several things leave the file in that state: manual edits, a peer that gets removed and re-added, or a third-party panel managing the same server.

WireGuard does not report an error for this. It moves the allowed IP to the newest peer, and the older client ends up with allowed ips: (none) and stops passing traffic.

Real case (anonymized)

Server config order after another tool re-added the .1 peer at the end of the file:

... .28, .30, .1, .2, .3, .4, .5, .6, .7, .8

Clients created afterwards in AmneziaVPN got .9 and .10, but those addresses already belonged to two older peers higher up in the file. Both older clients now show allowed ips: (none) in awg show and have silently lost connectivity.

Steps to reproduce

  1. Server with clients 10.8.1.2 … 10.8.1.5.
  2. Move the [Peer] block of 10.8.1.2 to the end of /opt/amnezia/awg/awg0.conf and run awg syncconf.
  3. In AmneziaVPN, create a new client with Share. It gets 10.8.1.3.
  4. awg show: the original 10.8.1.3 client now has allowed ips: (none).

Expected

The next IP should be chosen from the set of all used addresses: the first free one, or max + 1 if it is not taken. It should not depend on the order of peers in the file.

Suggested fix

In prepareWireguardConfig, build a set from getIpsFromConf(stdOut) and pick the first address in the subnet that is not in the set, skipping the network and gateway addresses. Optionally, also skip IPs stored in clientsTable (userData.allowed_ips).

Originally created by @dimkvin on GitHub (Oct 6, 2026). Original GitHub issue: https://github.com/amnezia-vpn/amnezia-client/issues/3261 # AWG/WireGuard: new client IP is "last AllowedIPs in the file + 1", which hands out duplicate IPs when the server config is not sorted ## Environment - AmneziaVPN 5.0.3.0 (Linux desktop and Android) - Self-hosted server, AmneziaWG 3.1 (the container is named `amnezia-awg2`) - Code checked against `dev` at `3e9b70a` ## What happens `WireguardConfigurator::prepareWireguardConfig` (`client/core/configurators/wireguardConfigurator.cpp`) picks the next client IP like this: ```cpp QString getIpsScript = QString("cat %1 | grep AllowedIPs").arg(configPath); // line 128 ... lastIp = ips.last(); // line 153 ... result.setAddress(lastIp.toIPv4Address() + 1); ``` and then appends the new `[Peer]` to the end of the file (`ScpAppendToExisting`, line 190). This only works while `awg0.conf` is sorted by IP and nothing has been re-added out of order. If the last `[Peer]` in the file has a lower IP than some earlier peer, the new client gets an address that is already in use. Several things leave the file in that state: manual edits, a peer that gets removed and re-added, or a third-party panel managing the same server. WireGuard does not report an error for this. It moves the allowed IP to the newest peer, and the older client ends up with `allowed ips: (none)` and stops passing traffic. ## Real case (anonymized) Server config order after another tool re-added the `.1` peer at the end of the file: ``` ... .28, .30, .1, .2, .3, .4, .5, .6, .7, .8 ``` Clients created afterwards in AmneziaVPN got `.9` and `.10`, but those addresses already belonged to two older peers higher up in the file. Both older clients now show `allowed ips: (none)` in `awg show` and have silently lost connectivity. ## Steps to reproduce 1. Server with clients `10.8.1.2 … 10.8.1.5`. 2. Move the `[Peer]` block of `10.8.1.2` to the end of `/opt/amnezia/awg/awg0.conf` and run `awg syncconf`. 3. In AmneziaVPN, create a new client with Share. It gets `10.8.1.3`. 4. `awg show`: the original `10.8.1.3` client now has `allowed ips: (none)`. ## Expected The next IP should be chosen from the set of all used addresses: the first free one, or max + 1 if it is not taken. It should not depend on the order of peers in the file. ## Suggested fix In `prepareWireguardConfig`, build a set from `getIpsFromConf(stdOut)` and pick the first address in the subnet that is not in the set, skipping the network and gateway addresses. Optionally, also skip IPs stored in `clientsTable` (`userData.allowed_ips`).
Sign in to join this conversation.
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
amnezia-vpn/amnezia-client#1510
No description provided.