mirror of
https://github.com/amnezia-vpn/amneziawg-linux-kernel-module.git
synced 2026-10-13 21:34:34 +00:00
[GH-ISSUE #168] AWG 2.0 server with S3-S4 junk offsets cannot communicate with AWG clients that lack S3-S4 support #102
Labels
No labels
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
amnezia-vpn/amneziawg-linux-kernel-module#102
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @otternetwork on GitHub (Apr 26, 2026).
Original GitHub issue: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/issues/168
An AmneziaWG 2.0 server configured with S3-S4 junk offsets (S3>0, S4>0) cannot communicate with AmneziaWG clients that do not support S3-S4 junk offsets. This includes AWG 1.0 clients and AWG 2.0 clients configured without S3-S4. The S3/S4 junk prefix is applied unconditionally at the device level to all AWG peers, with no per-peer detection or fallback.
This is the same class of backward-compatibility regression as #162 (per-peer
advanced_securityfor legacy WireGuard clients) and #163 (per-peerranged_headersfor AWG 1.0 vs 2.0 headers), but for the S3-S4 junk offset parameters.Client classes affected
A server configured with S1>0, S2>0, S3>0, S4>0 and custom H1-H4 should be able to serve all of:
peer->advanced_securityRoot cause
Send path — transport data (S4)
In
src/send.c,wg_packet_encrypt_workerprepends S4 junk to transport data packets for ALL peers withadvanced_security:When S4>0, every AWG peer receives S4-prefixed transport packets regardless of whether the peer supports S4. An AWG client without S3-S4 sees an unexpected junk prefix and cannot find the transport header at the expected offset.
Send path — cookie reply (S3)
Similarly,
wg_packet_send_handshake_cookieprepends S3 junk for all non-legacy peers:A client without S3 expects the cookie header at offset 0, but receives it at offset S3.
Receive path — incoming transport data
In
src/receive.c,prepare_awg_messagetries to match transport packets at offset S4:When S4>0, an incoming packet from an AWG client without S4 has the AWG H4 header at offset 0, not at offset S4. The size check may also fail since the packet is smaller by S4 bytes. There is no fallback to try the AWG H4 header at offset 0 (without the S4 junk prefix).
The same issue exists for incoming cookie replies (S3 offset).
Relationship to existing per-peer flags
The codebase already has the pattern for per-peer capability detection:
peer->advanced_security— distinguishes legacy WireGuard peers from AWG peers. Detected during handshake consumption innoise.cby checking whether the incoming H1 header matches the AWG range. Fixes #162.peer->ranged_headers— distinguishes AWG 1.0 (fixed headers) from AWG 2.0 (ranged headers). Detected by checking whether the incoming H1 value differs from the range start. Fixes #163.A third per-peer flag is needed:
peer->junk_offsets— distinguishes AWG peers with S3-S4 support from AWG peers without it.Detection approach
Detection follows the same try-and-fallback pattern already used in
prepare_awg_messagefor S1-S2. When S4>0, the function first tries to match at offset S4 with AWG H4. If that fails, it should try AWG H4 at offset 0 (no S4 junk). The result (whether junk offsets were present) is threaded through towg_packet_consume_data, which sets the per-peer flag after the peer is identified viakey_idx.Note: when S4=0, the "strip S4" block already performs a no-op
skb_pull(skb, 0), so the fallback is only needed when S4>0.Cookie S3 limitation
During cookie send (
wg_packet_send_handshake_cookie), there is no peer context — the peer hasn't been fully identified yet. S3 junk on cookies must follow the server's device-level configuration for AWG peers. This is acceptable because cookie replies are rare (only under load), temporary, and the client will retry the handshake.Suggested fix
bool junk_offsetstostruct wg_peer, following theadvanced_security/ranged_headerspatterntruewhenadvanced_security && (S3>0 || S4>0)prepare_awg_messagetries AWG-with-S4 first, falls back to AWG-without-S4wg_packet_consume_datavia function arguments (same ashad_junk_offsetsbool)wg_packet_encrypt_workeronpeer->advanced_security && peer->junk_offsetsWGPEER_A_JUNK_OFFSETS) and netlink for userspace visibility