Today a client leaves to the internet from the same server it connected to.
Exit nodes split the two: clients connect to an *entry* node (reachable,
possibly behind DPI) and egress from an *exit* node (clean IP, other country).
One exit serves many entries and keeps serving its own AWG clients.
client --AWG--> [entry] amnezia-awg2 --WG/AWG link--> [exit] amnezia-exit --> internet
awg0 10.8.1.0/24 transit0 10.9.0.0/24
exit0 10.9.0.N (Table=off) one [Peer] per entry, /32
Exit side: a new protocol `exit` = container `amnezia-exit`, an AmneziaWG
listener on 55520/udp over the transit subnet 10.9.0.0/24. Peers are panel
nodes, never end users, and live in their own peersTable. ExitManager
subclasses AWGManager and closes every client-facing method.
Entry side: a second interface `exit0` inside the existing AWG container with
`Table = off`, plus policy routing - `from <client subnet> lookup 200`,
`default dev exit0` in table 200, and `blackhole default metric 1000` as a
kill-switch installed *before* the client tunnel comes up, so a container
restart cannot leak. Clients are MASQUERADEd into the entry's transit /32, so
the identical 10.8.1.0/24 of every instance can never collide at the exit.
TCP MSS is clamped, and rules 190/191 keep client<->client and AmneziaDNS
traffic local. State is file-driven: exit0.conf present means linked, and the
same shell block runs at container start and on a live (un)link.
Link crypto is WireGuard; AWG obfuscation is a per-exit-node property for hops
that cross DPI, and S3/S4 are deliberately not written on the transit - they
pad every transport packet and would eat the MTU budget of a tunnel inside a
tunnel. Private keys are generated inside the containers; the panel carries
public keys and a per-peer PSK only.
exit_link_service.py orchestrates linking with per-(entry, protocol) locks,
SSH off the event loop, a 15-second handshake gate that rolls back, and
lifecycle hooks for every way a link can go stale: exit uninstalled, stopped,
deleted, host cleared, entry reinstalled, container gone, backup restored.
Servers get a stable `uid` (already upstream) so reorder and delete cannot
break a link.
IPv4 only for now: while linked, client IPv6 is refused with `unreachable`
rather than leaking out of the entry.
Also included: an egress check that curls a public IP service bound to the
tunnel gateway (the client's exact path) and compares it with the direct one;
optional DNS resolution at the exit node; a default exit node applied to new
AWG installs; and reconciliation after a protocol restore.
244 tests pass. CURRENT_VERSION is untouched.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add SOCKS5 support
Add AdGuard Home integration
Add node status and latency tracking
Add drag-and-drop server management
Upgrade Xray from v1.8 to v26.3.27 with backward compatibility
Fix Telemt dependency installation
Extend Telegram bot to support all protocols
Improve server cleanup process
Enhance API structure (system routes moved to a separate group)
Add JWT token generation for external integrations