feat(amneziawg): add native AmneziaWG protocol backend

AmneziaWG (WireGuard plus DPI-resistant obfuscation) needs no Docker
here — it runs as a genuine kernel interface via awg-quick/awg, managed
the same way internal/mtproto manages mtg: one Inbound row is one
desired Instance, and a Manager reconciles running interfaces toward
the database every 10s (internal/web/job/amneziawg_job.go) plus
immediately after a client edit (applyLocalAmneziaWG).

Clients reuse model.Client verbatim (the same PrivateKey/PublicKey/
PreSharedKey/AllowedIPs fields WireGuard already uses), so bulk
operations, the QR/share-link modal and subscriptions come from the
shared inbound infrastructure instead of a parallel implementation.
internal/amneziawg owns the obfuscation param generator/validator
(ported from coinman-dev/3ax-ui, upgraded to AmneziaWG 2.0's S3/S4
padding and I1 signature packet) and the exec wrapper around
awg-quick/awg, with fingerprint-based reconcile (noop / reload-via-
syncconf / full restart) mirroring mtproto.Manager so a same-protocol
edit doesn't force an unnecessary interface bounce that would drop
every peer's connection.

Frontend and install.sh's DKMS/awg-tools setup are tracked separately;
this is backend-only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Kuzz007
2026-07-25 00:39:41 +03:00
parent cd674c8d4f
commit 83cc545953
17 changed files with 1799 additions and 10 deletions
+8
View File
@@ -16,6 +16,7 @@ import (
"strings"
"time"
"github.com/mhsanaei/3x-ui/v3/internal/amneziawg"
"github.com/mhsanaei/3x-ui/v3/internal/config"
"github.com/mhsanaei/3x-ui/v3/internal/eventbus"
"github.com/mhsanaei/3x-ui/v3/internal/logger"
@@ -288,6 +289,7 @@ const (
cadenceXrayRestart = "@every 30s"
cadenceXrayTraffic = "@every 5s"
cadenceMtproto = "@every 10s"
cadenceAmneziaWG = "@every 10s"
cadenceClientIPScan = "@every 10s"
cadenceNodeHeartbeat = "@every 5s"
cadenceNodeTraffic = "@every 5s"
@@ -327,6 +329,11 @@ func (s *Server) startTask(restartXray bool) {
_, _ = s.cron.AddJob(cadenceMtproto, mtJob)
go mtJob.Run()
// Reconcile AmneziaWG interfaces and scrape their traffic
awgJob := job.NewAmneziaWGJob()
_, _ = s.cron.AddJob(cadenceAmneziaWG, awgJob)
go awgJob.Run()
// check client ips from log file every 10 sec
_, _ = s.cron.AddJob(cadenceClientIPScan, job.NewCheckClientIpJob())
@@ -680,6 +687,7 @@ func (s *Server) stop(stopXray bool, stopTgBot bool) error {
if stopXray {
_ = s.xrayService.StopXray()
mtproto.GetManager().StopAll()
amneziawg.GetManager().StopAll()
}
if s.cron != nil {
s.cron.Stop()