v0.8.0
The project is now awgtun, published from
AYastrebov/awgtun. It was called
boringtun, which is Cloudflare's crate name and was never available to this
fork. See the rename entry under Changed for what that breaks.
Added
- AmneziaWG 3.1:
random_trailersanddisable_cookies, at parity with amneziawg-go1b86b2a. Random trailers append a random number of bytes to each initiation, response and cookie reply — outside the MAC, trimmed by the receiver using the message's fixed size — and widen transport content padding inside the AEAD whencontent_padding_additionis unset. Their length is bounded by a per-peer sliding UDP window that tracks the largest datagram the tunnel has carried and resets when the endpoint changes.disable_cookieswithholds cookie replies without changing the rate limiter's decision. Both default to off, and both peers must agree onrandom_trailers: a receiver only tolerates a trailing byte when it is enabled. Configurable throughAmnezia3Config, the UAPI socket, and the C FFI (random_trailers/disable_cookiesappended toamnezia3_config, so existing field offsets are unchanged). - AmneziaWG 3.0: ChaCha20 header protection, content padding inside the AEAD envelope, and randomized WireGuard timings, at parity with amneziawg-go
d57d98d Amnezia3ConfigandTunn::new_with_amnezia3;Tunn::newandTunn::new_with_amneziaare unchanged and now delegate to it- C FFI:
amnezia3_configandnew_tunnel_amnezia3 Amnezia3Config::parsereads a UAPI-stylekey=valueconfiguration block, covering the AmneziaWG 2.0 and 3.0 keys under their upstream names- JNI:
new_tunnel_amnezia3(configured from that block),wireguard_poll_outgoing_packetandtunnel_free, so Android consumers can run AmneziaWG without binding the C FFI directly wireguard_ffi.h: declarations for the AmneziaWG 2.0 surface (amnezia_config,new_tunnel_amnezia,wireguard_poll_outgoing_packet), which were missing entirely, alongside the new 3.0 onesdevice: AmneziaWG support, makingawgtun-clia full AmneziaWG endpoint. Parameters are set withset=1and reported byget=1, so amneziawg-tools'awg setconf/showconfdrive it directly.Amnezia3Config::to_uapi_block, the inverse ofparse, emitting only non-default fieldsPacketClassifier, which strips the padding prefix and decrypts the protected header without aTunn. A device has to classify a datagram before it knows which peer it belongs to, as amneziawg-go does on its ownDevice.- Verified interoperability with the AmneziaWG kernel module over a full 3.0 configuration — header protection, content padding and randomized timings — alongside the existing amneziawg-go result. Sessions held open for the better part of an hour completed 30 rekeys inside the configured
RekeyAfterTimewindow and carried ~144 MB each way without a stall, so rekeying and sustained load are no longer unverified against a real peer. SeeAMNEZIA.md.
Removed
AWG2_MAX_HANDSHAKE_PADDING,AWG2_MAX_TRANSPORT_PADDING,AWG2_MAX_JUNK_COUNT,AWG2_MIN_JUNK_SIZE,AWG2_MAX_JUNK_SIZE, and theConfigErrorvariantsPaddingOutOfRange,JunkCountOutOfRangeandJunkSizeOutOfRange. The limits they expressed are not part of the protocol.HeaderConfig::validate_wireguard_compatibleand theConfigErrorvariantsStandardHeaderValue,InitPacketRequiresI1andInitPacketGap. The rules they expressed are not part of the protocol either;HeaderConfig::validatenow checks only for overlap, which is all amneziawg-go checks.
Changed
- Renamed from
boringtuntoawgtun. The library crate isawgtunand the binary isawgtun-cli;use boringtun::becomesuse awgtun::. The JNI class moves toio.github.ayastrebov.awgtun.AwgTunJNI, which breaks the ABI for anything already built against the old exports.repositoryanddocumentationpointed at cloudflare/boringtun and docs.rs/boringtun and now point here;keywordsandcategoriesare set so the crate is findable under "amneziawg" despite the name. BSD-3-Clause requires no name to be kept, andLICENSE.mdretains Cloudflare's copyright notice as clauses 1 and 2 require. - Version restarts at 0.8.0. The inherited 0.7.1 collided with a real, unrelated crates.io release of the same number.
- Supported platforms table corrected. It advertised
armv7-apple-ios, a target Rust no longer has, and omittedaarch64-apple-darwin, which is every Mac since 2020. It now lists exactly what the release workflow builds. - Minimum supported Rust version raised from 1.78 to 1.85. 1.78 was never a compatibility promise — it was the floor implied by
Cargo.lockbeing format v4 — and holding it meant pinning transitive crates that had already moved past it.awgtun-clihas required 1.88 throughout. - Dependencies refreshed to their latest semver-compatible releases.
chacha20poly1305andaeadno longer name pre-release versions (0.10.0-pre.1,0.5.0-pre.2) in their requirements, which had leftcargo updatefree to pull an unreleased AEAD into the packet path. - Keepalives now carry the S4 padding prefix, matching amneziawg-go. This changes the wire size of keepalives for existing AmneziaWG 2.0 configurations with a non-zero S4.
- Transport payloads that are neither IPv4 nor IPv6 are dropped silently and counted as data received instead of returning
InvalidPacket
Fixed
- Keepalives were treated as data whenever
S4or content padding was configured, so they armed the new-handshake timer instead of keeping the session quiet — the mechanism provoked rekeys rather than preventing them. Outbound, whether a packet is a keepalive is now a property of the call rather than of its wire size; inbound, a payload whose first byte is zero is recognised as one, since a content-padded keepalive decrypts to zeros rather than to nothing. Matches amneziawg-go08d68cdand kernel modulece16310, which fixed the same bug in both implementations. - Configurations from real AmneziaWG servers were rejected. S1-S4 were capped at 64 (32 for S4),
Jcat 10 and junk sizes to 64-1024 — ranges taken from Amnezia's documentation rather than the protocol. amneziawg-go enforces no maximum on any of them, and a live server whoseS2exceeded 64 was unreachable as a result. Only the checks upstream also makes are kept, plusJmin <= Jmax, which upstream omits and would underflow on. - JNI: tunnels created through the bindings could not be released — there was no
tunnel_freebinding, so every tunnel leaked device:set=1split each line on every=rather than the first, rejecting any value containing one- C FFI: a zeroed
amnezia_configwas rejected instead of yielding standard WireGuard behavior, because the all-zero H1-H4 fields were read as four overlapping ranges - Range generation no longer overflows for a range covering the whole
u32space - Junk packet sizes are drawn from the half-open range
[Jmin, Jmax), matching amneziawg-go'smin + fastrandn(max - min). PreviouslyJmaxitself could be produced. Amnezia3Config::validatenow rejects inverted content-padding and timing ranges, which a public struct literal could construct while bypassingU32Range::newTunn::persistent_keepalivereports the interval armed from an AWG 3.0persistent_keepaliverange instead of returningNonewhile keepalives were being sent- Content padding is clamped to the space left in the caller's
dstbuffer, so enabling it no longer raises the buffer requirement ofencapsulate/update_timersand cannot panic an existing caller. amneziawg-go gets this for free from its pooled 64 KiB buffers; a tightdstnow yields less padding instead. - Configurations that enable junk, padding or I-packets while leaving H1-H4 at the WireGuard defaults were rejected. amneziawg-go defaults H1-H4 to the standard types 1-4 and never refuses them, so
s1=16 s2=16 s3=16 s4=16— a valid obfuscation profile — was unconfigurable. - I1-I5 no longer have to be contiguous. amneziawg-go stores each chain independently and sends every configured one, so
i1plusi3is valid there; requiring I1 and refusing gaps rejected it.InitPacketConfig::active_chainsnow yields every configured chain rather than stopping at the first gap, which would otherwise have dropped I-packets a peer expects. device: AmneziaWG keys inset=1are now incremental, as they are in amneziawg-go and as the rest of the UAPI is. Setting one key replaced the whole AmneziaWG configuration, soawg set <if> jc 5wiped S1-S4, H1-H4 and the header protection key.device: changing the AmneziaWG configuration rebuilds the peers' tunnels. ATunncaptures its parameters at construction, so inbound datagrams were classified with the new configuration while peers still sent with the old one.device:mtuis no longer accepted over the UAPI socket. A device knows its interface MTU and uses it, so the key was reported byget=1without being honored.
Verify a download:
gh attestation verify <file>.tar.gz --repo AYastrebov/awgtun