Skip to content

kmod-amneziawg: add AmneziaWG kernel module package - #30492

Open
karen07 wants to merge 1 commit into
openwrt:masterfrom
karen07:add-kmod-amneziawg
Open

kmod-amneziawg: add AmneziaWG kernel module package#30492
karen07 wants to merge 1 commit into
openwrt:masterfrom
karen07:add-kmod-amneziawg

Conversation

@karen07

@karen07 karen07 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

AmneziaWG OpenWrt integration — 1/3

This PR adds the kmod-amneziawg package.

It is the first part of a complete AmneziaWG integration for OpenWrt:

  1. kmod-amneziawg — kernel module (this PR)
  2. amneziawg-tools — userspace tools
  3. luci-proto-amneziawg — LuCI protocol integration

The related PRs will be linked here once submitted.

Maintenance approach

I maintain the complete integration here:

https://github.com/karen07/amneziawg-openwrt-package

The repository is built around a generator:

https://github.com/karen07/amneziawg-openwrt-package/blob/main/generate.py

The goal is to avoid maintaining a large, manually diverging copy of the
OpenWrt WireGuard integration.

generate.py is the source of truth for the generated packages.

For amneziawg-tools and luci-proto-amneziawg, the generator starts from
the corresponding upstream OpenWrt / LuCI WireGuard packages, performs the
mechanical WireGuard-to-AmneziaWG transformations, and then applies only the
AmneziaWG-specific changes.

For review, the generation process can be stopped at separate stages:

vanilla -> files -> text -> full

This makes it possible to inspect separately:

  • the original upstream WireGuard/OpenWrt baseline;
  • file and path renames;
  • identifier renames;
  • the actual AmneziaWG-specific delta.

This is intended to make both review and future maintenance easier: when the
OpenWrt or LuCI WireGuard integration changes, the AmneziaWG packages can be
regenerated from the new upstream baseline instead of manually rebasing a
large copied implementation.

kmod-amneziawg/Makefile is also generated by the same script from the pinned
AmneziaWG kernel-module version.

The generator is maintenance and review tooling only. The generated package
files are committed to Git, so OpenWrt does not need the generator at build
time.

Upstream tracking

The generator provides:

./generate.py check

to check whether a newer AmneziaWG kernel-module or tools release is available.

I currently run this check manually on a regular basis (normally daily).
When a new upstream version appears, the script stops and requires the version
change to be reviewed explicitly before regeneration, rather than silently
updating to an unreviewed upstream revision.

AmneziaWG sources are pinned to official upstream release tags.

Build and testing workflow

The repository contains an OpenWrt SDK build workflow and a GitHub Actions
target/subtarget matrix for building the generated packages across OpenWrt
targets.

The same repository can also build and install the packages directly on an
OpenWrt device for local testing.

I use this AmneziaWG OpenWrt integration myself, so it is maintained as a
working deployment rather than only as a packaging experiment.

Previous submissions

This is a renewed attempt to bring AmneziaWG support to OpenWrt, with a focus
on addressing the long-term maintenance and reviewability concerns raised
around previous submissions.

Related previous work:

The reproducible generation approach is specifically intended to keep the
WireGuard-derived parts synchronized with OpenWrt/LuCI upstream while keeping
the AmneziaWG-specific changes small and auditable.

PR series

Once all parts are submitted, this section will link the complete series:

@stangri

stangri commented Sep 9, 2026

Copy link
Copy Markdown
Member

Thanks for this endeavour, I'm sure it would be appreciated by many OpenWrt users.

FWIW regarding the luci app -- as far as I remember the previous discussions, there was a strong preference from the core team to adjust the luci-app-wireguard to support additional amneziawg options, rather than duplicating the code of the existing app into luci-app-amneziawg.

@karen07

karen07 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

Thanks, that makes sense, and I agree that avoiding a duplicated LuCI implementation would be preferable.

There is one part I am not yet sure how you would prefer to handle: the existing luci-proto-wireguard backend is not only UI code. Its rpcd helper directly calls wg (wg genkey, wg pubkey, wg show all dump, etc.) and parses the WireGuard dump format.

AmneziaWG uses awg show all dump, and its interface dump contains additional AWG-specific fields between listen_port and fwmark. My current implementation therefore adapts the rpcd backend as well as the UI. For example, the AWG parser reads the additional fields and treats fwmark as the final interface field instead of assuming record[4].

So I think sharing the existing WireGuard LuCI code is possible, and I would actually prefer that if it is acceptable upstream, but it would require making the existing LuCI/rpcd implementation protocol-aware rather than simply adding the AWG options to the WireGuard form.

For example, the common code could select wg vs awg and use the corresponding dump parser depending on the protocol.

Is this roughly the approach the core team had in mind?

Also, what do you think about the overall approach of this integration and the way I am trying to keep the AmneziaWG-specific delta small and reviewable?

@BKPepe

BKPepe commented Sep 9, 2026

Copy link
Copy Markdown
Member

What is different than in the last PR #26971 and others https://github.com/openwrt/packages/pulls?q=is%3Apr+state%3Aclosed+kmod-amneziawg ? 🤔

@karen07

karen07 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@BKPepe The main difference is that this time I am submitting the complete integration as a coordinated set of three parts:

  1. kmod-amneziawg
  2. amneziawg-tools
  3. luci-proto-amneziawg

They are maintained together in one repository, and the OpenWrt package sources are generated from the corresponding WireGuard packages in a staged way. This makes the AmneziaWG-specific delta explicit and easier to review.

I also track upstream changes in both WireGuard/OpenWrt and AmneziaWG, so the generated packages can be kept in sync instead of drifting as independent copies.

In addition, I use these packages myself, and around 30 other users are currently using them as well. So far we have not encountered any known issues with the integration.

So compared to the previous PRs, this is intended as a complete, actively used, and maintainable integration rather than separate one-off package submissions.

@BKPepe

BKPepe commented Sep 9, 2026

Copy link
Copy Markdown
Member

Sorry, but from your response I am kinda confused.

For LuCI:

For packages repository:

  • for both packages, which you are saying as parts, there were also multiple attempts.

Well, I am not sure how they are maintained in one repository as looking into the PKG_SOURCE_URL, but fine, maybe the AI prompt was not right. Even thought, all previous attempts were complete and actively used as well.

@karen07

karen07 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@BKPepe You're right, my previous wording was unclear.

By "maintained together in one repository" I did not mean that the upstream source code of the kernel module and tools lives in the same repository. PKG_SOURCE_URL correctly points to the official AmneziaWG upstream repositories.

What I meant is that I maintain the OpenWrt integration for all three parts in one repository:

  • kmod-amneziawg
  • amneziawg-tools
  • luci-proto-amneziawg

I also did not mean to imply that the previous attempts were incomplete or unused. I understand that there were several complete attempts before.

The main difference in my approach is the maintenance model. The OpenWrt packages are generated from the corresponding WireGuard packages in stages, so I can regularly track changes in the OpenWrt WireGuard implementation and keep the AmneziaWG-specific delta small and explicit.

For example, the generation process separates:

  • the vanilla WireGuard package state,
  • file/name renaming,
  • mechanical identifier changes,
  • the actual AmneziaWG-specific changes.

This makes it easier for me to see what really differs from WireGuard and to update the packages when either OpenWrt WireGuard or AmneziaWG changes.

So the difference I was trying to describe is not that this is the first complete or actively used attempt, but rather that I am trying to provide a reproducible maintenance process for keeping all three parts synchronized over time.

https://github.com/karen07/amneziawg-openwrt-package

https://github.com/karen07/amneziawg-openwrt-package/blob/main/generate.py

https://github.com/karen07/amneziawg-openwrt-package/compare/2a3cddbc783ef2dd59331b81d67f1bac2de2b461..main

@karen07

karen07 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor Author

@BKPepe Thanks for the clarification.

Then I think the most useful question from my side is: what exactly would need to be changed or improved for AmneziaWG support to be acceptable for inclusion in OpenWrt?

There have already been several attempts over the years, so I would really like to understand whether there are still concrete technical or maintenance blockers, and what you would prefer to see addressed.

I am happy to rework the integration if needed. For example, if the preferred approach for LuCI is to share more code with luci-proto-wireguard instead of maintaining a separate copy, I can work in that direction as well.

My goal is not just to submit another version of the same PR, but to understand the upstream expectations and maintain the packages accordingly.

This support is also quite important in practice. AmneziaWG is widely used by people in Russia and other places where ordinary WireGuard traffic may be blocked or filtered, so having the packages available directly from the official OpenWrt repositories would make a significant difference for users.

If there are specific requirements that would make these packages mergeable, please let me know and I will try to address them.

Comment thread net/kmod-amneziawg/Makefile Outdated
FILES:=$(PKG_BUILD_DIR)/$(MAKE_PATH)/amneziawg.ko
DEPENDS:= \
+kmod-udptunnel4 \
+kmod-udptunnel6 \

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kmod-udptunnel6 is declared DEPENDS:=@IPV6, so an unconditional dependency makes kmod-amneziawg unselectable on IPv6-disabled builds. Use the conditional form, like kmod-wireguard and kernel/ovpn-dco.

Suggested change
+kmod-udptunnel6 \
+IPV6:kmod-udptunnel6 \

Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks


Generated by Claude Code

Comment thread net/amneziawg/Makefile

PKG_BUILD_PARALLEL:=1

MAKE_PATH:=src

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The module is built in $(PKG_BUILD_DIR)/src, but PKG_EXTMOD_SUBDIRS is left at its default ., so collect_module_symvers looks for Module.symvers/modules.order in the build-dir root and stores an empty symvers file for this package. Set it too, the way kernel/ovpn-dco and net/batman-adv do.

Suggested change
MAKE_PATH:=src
MAKE_PATH:=src
PKG_EXTMOD_SUBDIRS:=src

Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks


Generated by Claude Code

Comment thread net/kmod-amneziawg/Makefile Outdated
+kmod-udptunnel4 \
+kmod-udptunnel6 \
+kmod-crypto-lib-chacha20poly1305 \
+kmod-crypto-lib-curve25519

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No AUTOLOAD here, while kmod-wireguard and the other out-of-tree kmods in this feed (kernel/ovpn-dco, net/siit, net/jool) all set one. The v3.1.20260906 sources do carry MODULE_ALIAS_RTNL_LINK / MODULE_ALIAS_GENL_FAMILY, so on-demand probing should work — is omitting AUTOLOAD:=$(call AutoProbe,amneziawg) intentional?


Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks


Generated by Claude Code

Comment thread net/kmod-amneziawg/Makefile Outdated
Comment on lines +28 to +31
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
TITLE:=AmneziaWG VPN Kernel Module

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: two things on this block:

  • SECTION and CATEGORY are already set for every KernelPackage by kernel.mk.
  • A define KernelPackage/<name> metadata block is indented with two spaces rather than tabs; same for the FILES/DEPENDS lines below.
Suggested change
SECTION:=kernel
CATEGORY:=Kernel modules
SUBMENU:=Network Support
TITLE:=AmneziaWG VPN Kernel Module
SUBMENU:=Network Support
TITLE:=AmneziaWG VPN Kernel Module

Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks


Generated by Claude Code

Comment thread net/kmod-amneziawg/Makefile Outdated
PKG_VERSION:=3.1.20260906
PKG_RELEASE:=1

PKG_SOURCE_PROTO:=git

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: PKG_SOURCE_PROTO:=git is meant as a last resort when upstream ships no archives, and upstream tags releases here. The usual form in this feed is a tarball plus PKG_HASH, e.g. PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz with PKG_SOURCE_URL:=https://codeload.github.com/amnezia-vpn/amneziawg-linux-kernel-module/tar.gz/v$(PKG_VERSION)?, which also drops PKG_MIRROR_HASH.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks — solved with the archive/refs/tags/ + PKG_SOURCE_URL_FILE form rather than codeload, which works equally well.


Generated by Claude Code

Comment thread net/kmod-amneziawg/Makefile Outdated
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk

PKG_NAME:=kmod-amneziawg

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: no other package in this feed carries a kmod- prefix in PKG_NAME or in its directory name — kernel-module packages are named after the source (kernel/ovpn-dcoovpn-backports, net/batman-adv, kernel/mdio-netlink). PKG_NAME:=amneziawg still produces the kmod-amneziawg package through $(eval $(call KernelPackage,amneziawg)).


Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks — solved by renaming both PKG_NAME and the directory to amneziawg.


Generated by Claude Code

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit; no new issues found.


Generated by Claude Code

@karen07
karen07 requested a review from openwrt-ai September 10, 2026 15:00
@karen07 karen07 changed the title kmod-amneziawg: Add AmneziaWG kernel module package kmod-amneziawg: add AmneziaWG kernel module package Sep 10, 2026

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit.


Generated by Claude Code

Comment thread net/amneziawg/Makefile Outdated
PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/archive/refs/tags/
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz
PKG_HASH:=e32fa46f1b6f9e319c5261f0b0765c3a9261e40cb7c4616fd73500da961a2932
PKG_BUILD_DIR:=$(BUILD_DIR)/amneziawg-linux-kernel-module-$(PKG_VERSION)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$(BUILD_DIR) is shared by every subtarget of the same arch (ath79/generic and ath79/nand are both mips_24kc), so an out-of-tree module built here is reused against a different kernel and is not removed by make target/linux/clean — which is why kernel.mk defaults kmod build dirs to $(KERNEL_BUILD_DIR). Keep the override under it, as net/jool/Makefile:23 does.

Suggested change
PKG_BUILD_DIR:=$(BUILD_DIR)/amneziawg-linux-kernel-module-$(PKG_VERSION)
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/amneziawg-linux-kernel-module-$(PKG_VERSION)

Generated by Claude Code

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, thanks


Generated by Claude Code

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit; no new issues found.


Generated by Claude Code

@karen07

karen07 commented Sep 10, 2026

Copy link
Copy Markdown
Contributor Author

@BKPepe @stangri, I fixed all the issues raised by the @openwrt-ai reviewer.

@karen07

karen07 commented Sep 11, 2026

Copy link
Copy Markdown
Contributor Author

@neheb @1715173329 @hnyman Could you please take a look at this PR?

Comment thread net/amneziawg/Makefile Outdated

PKG_SOURCE:=amneziawg-linux-kernel-module-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://github.com/amnezia-vpn/amneziawg-linux-kernel-module/archive/refs/tags/
PKG_SOURCE_URL_FILE:=v$(PKG_VERSION).tar.gz

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not right

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed)

Comment thread net/amneziawg/Makefile Outdated
endef

define KernelPackage/amneziawg/description
AmneziaWG VPN kernel module.

@BKPepe BKPepe Sep 11, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is quite short description, it looks like as TITLE.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed)

@BKPepe

BKPepe commented Sep 11, 2026

Copy link
Copy Markdown
Member

Look, you've just dropped two massive essays here within a few minutes, and it's honestly really hard to parse through because, first of all, it was clearly written by AI, and second, you aren't actually answering what I asked. 🤷 Maybe, you'll need to tweak your AI prompts a lot.

  • Why should we have and support AmneziaWG as a paid service that merely offers a free tier as an afterthought, when WireGuard already exists?

  • Why do we need dedicated packages for AmneziaWG instead of just using WireGuard? Sure, there are likely some specific modifications and so on, but essentially they will be two nearly identical packages. I expect there will probably be a conflict regarding the wireguard module or tools or can they actually be used side by side?

Also, it’s definitely not appropriate to mass-ping people for a review just 2 days after opening a pull request.

According to Repology, barely any distributions package AmneziaWG anyway.

@emilastanov

Copy link
Copy Markdown

Hi, just adding a user perspective here.

I use OpenWrt in networks where plain WireGuard gets filtered and becomes unreliable, while AmneziaWG works fine for the same use case.

For me this has nothing to do with the commercial Amnezia VPN service. I use AWG in a fully self-hosted setup.

Right now this means relying on third-party packages. Having the kernel module and tools in the official OpenWrt packages would make the setup much simpler and more accessible for users who don’t want to maintain their own builds or feeds

@karen07

karen07 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

I think the main missing context here is what AWG actually changes compared to WG, and why those changes exist in the first place.

Why AWG exists when WG already exists

Plain WireGuard is very easy to fingerprint on the wire.

A standard WG handshake initiation packet has a fixed size of 148 bytes and starts with:

01 00 00 00

The handshake response has a fixed size of 92 bytes and starts with:

02 00 00 00

So even a very simple first-pass detector can look for a characteristic pattern such as:

UDP 148 bytes / type 1 -> UDP 92 bytes / type 2

There is no need to break the encryption, know the keys, or perform particularly sophisticated DPI. These are observable properties of the WireGuard wire protocol itself.

In Russia, this stopped being a theoretical problem a long time ago. Protocol-level filtering of WireGuard has been observed for years, and in 2023 there were widespread reports of plain WG being blocked across multiple Russian networks.

This is exactly the problem AWG is intended to solve.

AWG keeps the cryptographic foundation and much of the architecture of WireGuard, but deliberately changes the protocol properties that DPI can observe on the wire.

And the differences are no longer limited to just a couple of additional parameters.

What AWG actually adds on top of WG

Let me start with the simpler mechanisms.

Jc specifies the number of junk packets sent before the handshake.

Jmin and Jmax define the size range of those junk packets.

So instead of the first characteristic packet in a flow immediately being a standard 148-byte WG handshake, there may be a variable number of packets of varying sizes before it.

Then there are S1-S4.

S1 — padding for handshake initiation.

S2 — padding for handshake response.

S3 — padding for cookie reply.

S4 — padding for transport data messages.

This directly removes one of the simplest fingerprints of standard WireGuard: fixed message sizes.

WG initiation is 148 bytes, and the response is 92 bytes. With AWG, those message sizes no longer have to match the standard values.

The next group is H1-H4.

In standard WireGuard, every packet starts with a 32-bit message type:

1 — handshake initiation
2 — handshake response
3 — cookie reply
4 — transport data

That is why you see the characteristic:

01 00 00 00

and:

02 00 00 00

on the wire.

AWG allows those values to be changed:

H1 — header for handshake initiation;

H2 — header for handshake response;

H3 — header for cookie reply;

H4 — header for transport packets.

Modern AWG versions can also use ranges rather than just one fixed value.

So another very simple WireGuard fingerprint — fixed message types 1/2/3/4 — stops being fixed.

Then there are I1-I5.

These are not just padding applied to existing WireGuard packets. AWG can send up to five additional custom packets before the handshake.

Each I1...I5 describes the contents of such a packet. They can include combinations of:

  • fixed byte sequences;
  • random bytes;
  • random digits;
  • random ASCII characters;
  • timestamps.

So the beginning of a connection no longer necessarily looks like the beginning of a WireGuard flow at all.

AWG 3 also introduced HeaderProtectionKey.

This is a separate 32-byte key used for header protection.

Its purpose is to protect low-entropy packet-header fields that would otherwise remain convenient classification signals.

When header protection is enabled, S1-S4 are also involved in nonce construction, which is why sufficient padding is required.

Another parameter is ContentPaddingAddition.

It adds additional variable padding to packet contents.

This can be specified as a range, for example something conceptually like:

20-80

rather than as a single constant value.

That makes packet-size fingerprints even less stable: the same logical traffic does not necessarily produce packets of the same size every time.

AWG also allows the timing behavior of WireGuard to be changed.

For that, it adds parameters such as:

RekeyAfterTime — when to initiate a new handshake/rekey;

RekeyTimeout — how long to wait before retrying a handshake;

RejectAfterTime — when an existing key/session becomes too old and incoming traffic is rejected until a new handshake occurs;

KeepaliveTimeout — how long to wait without outgoing traffic before sending a keepalive;

MaxHandshakeAttempts — how many handshake attempts are made;

and the normal WG PersistentKeepalive can also be expressed as a range in AWG rather than only as one fixed interval.

The idea is the same: avoid stable and easily recognizable timing patterns.

AWG 3.1 added further mechanisms.

RandomTrailers adds random trailers to packets, so packet length can vary independently of the main payload.

DisableCookies allows the standard WireGuard cookie mechanism to be disabled, removing another part of WireGuard's characteristic protocol behavior.

There is also a per-peer AdvancedSecurity setting in the userspace API to indicate that AWG-specific advanced protocol behavior is being used for a particular peer.

So if we reduce this to observable properties, plain WG gives DPI a fairly stable picture:

fixed message types
fixed handshake sizes
predictable handshake sequence
predictable protocol timings

AWG allows nearly all of those characteristics to be changed:

Jc/Jmin/Jmax -> what appears before the handshake and how large it is

S1-S4 -> sizes of the main protocol messages

H1-H4 -> message type values

I1-I5 -> additional packets and their contents before the handshake

HeaderProtectionKey -> observable header fields

ContentPaddingAddition -> packet-content sizes

RekeyAfterTime/RekeyTimeout/RejectAfterTime/KeepaliveTimeout/MaxHandshakeAttempts -> protocol timing behavior

PersistentKeepalive range -> keepalive timing

RandomTrailers -> additional packet-length variability

DisableCookies -> cookie behavior

So the question "why not just use WireGuard?" has a very concrete technical answer:

if a network filters standard WireGuard by its wire fingerprint, continuing to use the same wire protocol does not solve the problem.

This is not a paid Amnezia service

I also think two very different things are being conflated here: the commercial Amnezia VPN service and AmneziaWG as an open-source protocol implementation.

The packages in these PRs are for the open-source amneziawg-linux-kernel-module and amneziawg-tools.

Using AWG does not require:

  • an Amnezia subscription;
  • an Amnezia account;
  • an Amnezia-operated server;
  • or any commercial Amnezia service at all.

AWG can be fully self-hosted.

That is exactly how I use it myself.

I maintain my own OpenWrt AWG packages here:

https://github.com/karen07/amneziawg-openwrt-package

and my own deployment here:

https://github.com/karen07/openwrt-mesh-builder

I deploy and control both ends myself: the OpenWrt nodes and the servers.

There is no paid Amnezia service involved anywhere in that setup.

There are other self-hosted deployment options as well, including Docker-based deployments.

More importantly, AWG does not even have to be used in a traditional:

VPN provider -> customer

model.

For example, I use AWG simply as a secure infrastructure link between my own routers and servers.

So it is more accurate to think of AWG primarily as an independent WireGuard-derived protocol implementation, not as a client for some paid VPN service.

For my own infrastructure, inclusion of these packages in the official OpenWrt feed is not even necessary: I already have my own packages, builder and working deployment.

I am upstreaming this because there are many OpenWrt users in Russia who need AWG directly on their routers because plain WG is filtered, and most of those users are not going to maintain their own kernel module, userspace tools, LuCI integration and OpenWrt package feed.

Why AWG needs separate packages

Here I actually agree with part of the concern: the OpenWrt integration for WG and AWG is indeed very similar.

That is intentional.

AWG is derived from WireGuard. They have essentially the same model for:

  • interfaces;
  • private/public keys;
  • peers;
  • endpoints;
  • AllowedIPs;
  • routing;
  • keepalive.

There is no reason to rewrite all of that from scratch just to make it look different.

In fact, my generate.py is deliberately designed to keep the AWG integration as close as possible to upstream WireGuard integration.

It starts from the WireGuard-based OpenWrt integration, performs the mechanical WG -> AWG transformation separately, and only then adds the AWG-specific functionality.

This compare shows exactly that substantive delta:

https://github.com/karen07/amneziawg-openwrt-package/compare/2a3cddbc783ef2dd59331b81d67f1bac2de2b461..main

This is important: the starting commit in that compare is already the state after the normal WireGuard -> AmneziaWG renaming has been done.

So the diff is not thousands of lines of:

wg -> awg

wireguard -> amneziawg

or file and namespace renames.

It specifically shows what actually needs to be added on top of the WireGuard integration in order to support AWG.

You can see the new AWG configuration fields, range types, handling of the additional parameters, their propagation through netifd/LuCI/userspace interfaces, and the other pieces required for AWG-specific protocol functionality.

So the statement that "essentially they will be two nearly identical packages" is true in one sense:

at the OpenWrt integration level, they should remain as similar as possible.

I consider that an advantage.

The smaller the independent delta from the existing WireGuard integration, the easier it is to read, review and maintain.

But that does not mean the backend is the same.

It is not:

WG:

wireguard + wg

AWG:

amneziawg + awg

The amneziawg implementation is what provides the wire-protocol changes described above.

Stock wireguard does not know about:

Jc/Jmin/Jmax

S1-S4

H1-H4

I1-I5

HeaderProtectionKey

ContentPaddingAddition

AWG-specific timing ranges

RandomTrailers

DisableCookies

or the other AWG protocol extensions.

So simply adding these fields to LuCI or UCI while continuing to use ordinary kmod-wireguard would not be enough.

The UI could store H1 or S1, but the stock WireGuard kernel module would have no idea what to do with them.

That is why a separate kernel module and the matching userspace control tool are required.

Can WG and AWG be used side by side?

Yes.

And this is not theoretical either.

WG uses:

wireguard + wg

AWG uses:

amneziawg + awg

They are separate kernel modules, separate interface types and separate userspace tools.

Installing AWG does not replace kmod-wireguard or wireguard-tools.

They can be installed and used at the same time on the same system.

My own deployment is a practical example of exactly that setup.

I use AWG for infrastructure links between nodes, while ordinary WG is used for access VPN.

So on the same OpenWrt router you can have, for example:

awg0 — infrastructure AWG tunnel

and:

wg0 — ordinary WireGuard access tunnel

with each serving a different purpose.

There is no requirement to choose "either WG or AWG".

WG and AWG compatibility

There is another relevant detail here.

AWG is derived from WG and, with the appropriate configuration, can operate in a WG-compatible mode.

In other words, if the AWG-specific protocol modifications are effectively disabled and the standard WG values are used, the AWG implementation can behave like ordinary WireGuard.

The reverse is not true.

Stock WireGuard cannot suddenly understand a connection using AWG-specific:

  • headers;
  • padding;
  • custom pre-handshake packets;
  • header protection;
  • randomized protocol behavior.

Stock WireGuard simply does not implement those extensions.

So, very roughly, the relationship is:

AWG -> can behave like WG

but:

WG -> cannot speak obfuscated AWG

That is another reason why having a separate implementation is natural here.

To answer the two questions directly

  1. Why support AWG when WireGuard already exists?

Because AWG is not a paid VPN service and not just another frontend for WireGuard.

It is a self-hostable WireGuard-derived protocol implementation specifically designed to change the wire-level characteristics that make plain WG very easy to fingerprint and block.

Where plain WG works, you can continue using WG.

Where the standard WG fingerprint is filtered, you need different wire behavior — and that is what AWG exists for.

  1. Why are separate AWG packages needed, and do they conflict with WG?

The OpenWrt integration is intentionally kept as close as possible to WireGuard, and the compare above shows the relatively small AWG-specific delta without the noise of mechanical renaming.

But the backend is different because the changes are part of the wire protocol itself.

WG uses wireguard + wg.

AWG uses amneziawg + awg.

They do not replace each other, they do not require choosing one over the other, and they can run side by side on the same OpenWrt router.

That is exactly how I already use them in my own deployment.

@GitHubbie0836

Copy link
Copy Markdown

Great initiative!

@BKPepe

BKPepe commented Sep 12, 2026

Copy link
Copy Markdown
Member

Honestly, that AI-written comment of yours is too long, and I’m going to spend way more time reading it than I would the actual source code you’re adding. I think you might want to tame that AI in a little bit. I’d genuinely love to know who actually read the whole thing. 😄

@karen07

karen07 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

I personally reread and rewrote that reply about ten times, trying to choose every word carefully.

I didn’t want to just formally respond to the comments — I wanted to properly explain what exactly differs between WireGuard and AmneziaWG, what additional features AWG introduces, why they are needed, and why some parts of the package are implemented the way they are.

I mainly use AI to translate from Russian into English. The content, technical arguments, and the points I want to get across are my own)

AmneziaWG is a WireGuard-based VPN protocol with additional traffic
obfuscation features designed to make VPN traffic harder to identify
and block. This package provides the AmneziaWG Linux kernel module for
OpenWrt.

Signed-off-by: Karen Khachatryan <karen0734@gmail.com>
@evgenyvolferts

Copy link
Copy Markdown
  • Why should we have and support AmneziaWG as a paid service that merely offers a free tier as an afterthought, when WireGuard already exists?

Lots of people in Russia use AWG as a replacement for WG - just as a VPN protocol, that cannot be filtered by government. WG tunnel don't live even several hours here.
Every update on my routers, routers of my friends, etc follows installation of AWG. It would be great if we could get AWG from official repo - that means no manual tasks after the upgrade.

@openwrt-ai openwrt-ai left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed 1 new commit; no new issues found.


Generated by Claude Code

@karen07

karen07 commented Sep 13, 2026

Copy link
Copy Markdown
Contributor Author

Is there anything else I should explain or fix?

@kolobjk

kolobjk commented Sep 13, 2026

Copy link
Copy Markdown

Hi! I would really appreciate having AmneziaWG support in OpenWrt. I run my own AWG server, so being able to connect to it directly from my router would be very useful and convenient. Thanks for your work on this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants