[PR #165] fix: detect AWG 1.0 vs 2.0 peers for header generation #214

Open
opened 2026-10-13 21:07:42 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/pull/165
Author: @otternetwork
Created: 4/5/2026
Status: 🔄 Open

Base: master ← Head: fix/detect-awg1-vs-awg2-peers


📝 Commits (2)

  • 27c4269 fix: restore per-peer legacy WireGuard client support
  • 7eb04a3 fix: detect AWG 1.0 vs 2.0 peers for header generation

📊 Changes

9 files changed (+155 additions, -46 deletions)

View changed files

📝 src/magic_header.h (+9 -0)
📝 src/netlink.c (+24 -2)
📝 src/netlink.h (+2 -1)
📝 src/noise.c (+6 -1)
📝 src/peer.c (+4 -0)
📝 src/peer.h (+1 -0)
📝 src/receive.c (+27 -6)
📝 src/send.c (+78 -36)
📝 src/uapi/wireguard.h (+4 -0)

📄 Description

Summary

When an AWG 2.0 server has ranged H1-H4 values, it generates random headers from those ranges for all AWG peers via mh_genheader(). This breaks AWG 1.0 clients that expect exact fixed values (the range starts).

This PR adds per-peer detection of fixed vs ranged header support:

  • Add ranged_headers field to struct wg_peer
  • Add mh_peerheader() helper: returns range start for fixed (AWG 1.0) peers, random value for ranged (AWG 2.0) peers
  • Auto-detect in noise.c during handshake consumption: if the peer's init header differs from the range start, it must support ranged headers
  • Apply same detection logic in cookie responses
  • Default ranged_headers for netlink-configured peers based on whether the device's header ranges are actual ranges

Detection heuristic and its limitations

The detection works by comparing the incoming H1 value against the configured range start:

  • Value != range start → peer supports ranged headers (AWG 2.0)
  • Value == range start → peer uses fixed headers (AWG 1.0)

This heuristic is conservative and safe in the "wrong" direction:

  • If an AWG 2.0 peer's random H1 happens to land on the range start, it is classified as AWG 1.0. The server responds with range start values, which are valid within the range — the 2.0 peer accepts them. No breakage.
  • Important: AWG 1.0 clients MUST be configured with H1-H4 values equal to the range start values of the AWG 2.0 server. If a 1.0 client uses a fixed value that falls within the range but is not the range start (e.g., client has H1=150 while server has H1=100-200), the server will misclassify it as AWG 2.0 and respond with random values from the range, which the 1.0 client will reject. This is an inherent limitation of heuristic detection without explicit version negotiation in the handshake.

UAPI extension

Expose the new flag to userspace via WGPEER_A_RANGED_HEADERS netlink attribute (backward compatible — old userspace ignores unknown attributes). This allows userspace apps to distinguish three peer states:

advanced_security ranged_headers Peer type
false - Legacy WireGuard
true false AWG 1.0 (fixed headers)
true true AWG 2.0 (ranged headers)

Depends on #164 — must be merged first.

Test plan

  • AWG 1.0 client (fixed H1-H4 at range starts) connects to AWG 2.0 server (ranged H1-H4)
  • AWG 2.0 client (ranged H1-H4) connects to AWG 2.0 server
  • Legacy WireGuard client still connects (unchanged from #164)
  • Userspace can read WGPEER_A_RANGED_HEADERS attribute for connected peers
  • Make sure it doesn't break the client mode

Closes #163


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/pull/165 **Author:** [@otternetwork](https://github.com/otternetwork) **Created:** 4/5/2026 **Status:** 🔄 Open **Base:** `master` ← **Head:** `fix/detect-awg1-vs-awg2-peers` --- ### 📝 Commits (2) - [`27c4269`](https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/commit/27c426989ca6556b9ee07630cfb2955d255a525d) fix: restore per-peer legacy WireGuard client support - [`7eb04a3`](https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/commit/7eb04a36ce20dfbf76adfa831fc4cd621f21d26f) fix: detect AWG 1.0 vs 2.0 peers for header generation ### 📊 Changes **9 files changed** (+155 additions, -46 deletions) <details> <summary>View changed files</summary> 📝 `src/magic_header.h` (+9 -0) 📝 `src/netlink.c` (+24 -2) 📝 `src/netlink.h` (+2 -1) 📝 `src/noise.c` (+6 -1) 📝 `src/peer.c` (+4 -0) 📝 `src/peer.h` (+1 -0) 📝 `src/receive.c` (+27 -6) 📝 `src/send.c` (+78 -36) 📝 `src/uapi/wireguard.h` (+4 -0) </details> ### 📄 Description ## Summary When an AWG 2.0 server has ranged H1-H4 values, it generates random headers from those ranges for all AWG peers via `mh_genheader()`. This breaks AWG 1.0 clients that expect exact fixed values (the range starts). This PR adds per-peer detection of fixed vs ranged header support: - Add `ranged_headers` field to `struct wg_peer` - Add `mh_peerheader()` helper: returns range start for fixed (AWG 1.0) peers, random value for ranged (AWG 2.0) peers - Auto-detect in `noise.c` during handshake consumption: if the peer's init header differs from the range start, it must support ranged headers - Apply same detection logic in cookie responses - Default `ranged_headers` for netlink-configured peers based on whether the device's header ranges are actual ranges ### Detection heuristic and its limitations The detection works by comparing the incoming H1 value against the configured range start: - Value != range start → peer supports ranged headers (AWG 2.0) - Value == range start → peer uses fixed headers (AWG 1.0) This heuristic is conservative and safe in the "wrong" direction: - If an AWG 2.0 peer's random H1 happens to land on the range start, it is classified as AWG 1.0. The server responds with range start values, which are valid within the range — the 2.0 peer accepts them. No breakage. - Important: AWG 1.0 clients MUST be configured with H1-H4 values equal to the range start values of the AWG 2.0 server. If a 1.0 client uses a fixed value that falls within the range but is not the range start (e.g., client has H1=150 while server has H1=100-200), the server will misclassify it as AWG 2.0 and respond with random values from the range, which the 1.0 client will reject. This is an inherent limitation of heuristic detection without explicit version negotiation in the handshake. ### UAPI extension Expose the new flag to userspace via `WGPEER_A_RANGED_HEADERS` netlink attribute (backward compatible — old userspace ignores unknown attributes). This allows userspace apps to distinguish three peer states: | `advanced_security` | `ranged_headers` | Peer type | |---|---|---| | false | - | Legacy WireGuard | | true | false | AWG 1.0 (fixed headers) | | true | true | AWG 2.0 (ranged headers) | **Depends on #164** — must be merged first. ## Test plan - [x] AWG 1.0 client (fixed H1-H4 at range starts) connects to AWG 2.0 server (ranged H1-H4) - [x] AWG 2.0 client (ranged H1-H4) connects to AWG 2.0 server - [x] Legacy WireGuard client still connects (unchanged from #164) - [x] Userspace can read `WGPEER_A_RANGED_HEADERS` attribute for connected peers - [x] Make sure it doesn't break the client mode Closes #163 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
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/amneziawg-linux-kernel-module#214
No description provided.