wireguard-go-awg2-lx/README.md

4.8 KiB
Raw Blame History

English · Русский

wireguard-go (lx fork) — sagernet + AmneziaWG 2.0

The WireGuard-Go runtime used by sing-box-lx: sagernet/wireguard-go (the fork sing-box builds on) + AmneziaWG 2.0 obfuscation, merged together.

This is not a general-purpose project. It exists for one reason — see below — and lives on the lx branch.


Why this fork exists

sing-box's WireGuard endpoint needs sagernet/wireguard-go's additions (the conn.Bind.Send(…, offset) contract, device.InputPacket, reserved/control). AmneziaWG's DPI-evasion obfuscation lives in amnezia-vpn/amneziawg-go, which is a fork of upstream wireguard-go and therefore lacks those sagernet additions.

So neither fork alone works for sing-box-lx:

sing-box-compat API AmneziaWG obfuscation
sagernet/wireguard-go
amnezia-vpn/amneziawg-go
this fork

The approach: keep the sagernet base and graft the obfuscation onto it — rather than the reverse (adding sagernet's APIs to amneziawg-go, which would route even plain WireGuard through a foreign device). This way sing-box compiles unchanged, the obfuscation is additive and off by default, and a config without AWG fields behaves exactly like plain WireGuard.

How the merge works

Both sagernet/wireguard-go and amneziawg-go descend from the same upstream git.zx2c4.com/wireguard-go, so they share git history — which makes a real 3-way merge possible (not a hand-port).

  • Base: sagernet/wireguard-go (the exact commit sing-box pins — currently 506b7631853c).
  • Merged in: amnezia-vpn/amneziawg-go (a tip with AWG2 / I1I5 + the S4-keepalive fix).
  • Key trick: MessageEncapsulatingTransportSize is set to 0 in device/noise-protocol.go. sing-box-lx does not use sagernet's 8-byte Bind.Send headroom, and zeroing it makes the AmneziaWG obfuscation compose cleanly with no weave conflicts in the packet send path.
  • Isolation: the obfuscation is confined to device/ — new files device/obf*.go, device/magic-header.go, plus grafts in device/{send,receive,device,uapi}.go. conn/, tun/, ipc/ stay pure sagernet.
  • Module path is unchanged (module github.com/sagernet/wireguard-go) so the consumer plugs it in with a replace directive and needs no import edits.

Consumed by

sing-box-lx wires this in as a git submodule + a replace:

# sing-box-lx/.gitmodules
[submodule "submodules/wireguard-go"]
    url = https://github.com/Leadaxe/wireguard-go-awg2-lx
    branch = lx

# sing-box-lx/go.mod   (// lx)
replace github.com/sagernet/wireguard-go => ./submodules/wireguard-go

Built with the with_awg tag, it has been live-validated against a real AmneziaWG 2.0 server (handshake + keepalive + outbound traffic) and cross-compiles on linux/darwin/windows × amd64/arm64.

Maintaining it (rebase onto a new sagernet tag)

When sing-box bumps sagernet/wireguard-go, redo the merge:

git remote add origin  https://github.com/sagernet/wireguard-go    # base
git remote add amnezia https://github.com/amnezia-vpn/amneziawg-go # obfuscation source
git fetch --all
git checkout -b lx <new-sagernet-commit>
git merge amnezia/master          # real 3-way merge via the shared upstream ancestor

Conflict resolution recipe:

  1. New device/obf*.go + device/magic-header.go come in clean.
  2. Mechanical conflicts (amnezia → sagernet import paths, queueconstants*, sticky*, tun.go) → take ours (sagernet).
  3. Remove amnezia-added infra duplicates: conn/gso_*.go, outline/*, tun/*_test.go.
  4. device/device.gounion (sagernet pauseManager + amnezia obf fields).
  5. device/send.go / receive.go → take amnezia's obfuscation, set MessageEncapsulatingTransportSize = 0, and keep the 3-arg bind.Send(…, 0) calls.
  6. conn/, tun/, ipc/, go.mod module path → ours (sagernet).

Then in sing-box-lx: bump the submodule, make -f Makefile.lx lx-build, and re-test against an AWG2 server.

Consumer Leadaxe/sing-box-lx
Base sagernet/wireguard-go
Obfuscation source amnezia-vpn/amneziawg-go · docs.amnezia.org
Original WireGuard/wireguard-go

License

MIT, inherited from WireGuard-Go (see LICENSE). The AmneziaWG obfuscation is likewise MIT (from amneziawg-go). This is an unofficial fork, not affiliated with WireGuard, SagerNet, or Amnezia.