amneziawg_job.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package job
  2. import (
  3. "encoding/json"
  4. "github.com/mhsanaei/3x-ui/v3/internal/amneziawg"
  5. "github.com/mhsanaei/3x-ui/v3/internal/amneziawgnet"
  6. "github.com/mhsanaei/3x-ui/v3/internal/logger"
  7. "github.com/mhsanaei/3x-ui/v3/internal/web/service"
  8. "github.com/mhsanaei/3x-ui/v3/internal/xray"
  9. )
  10. // AmneziaWGJob converges embedded AmneziaWG interfaces (inbounds AND the
  11. // template's "amneziawg" outbounds) every 10s; stats stay with Xray.
  12. type AmneziaWGJob struct {
  13. inboundService service.InboundService
  14. settingService service.SettingService
  15. }
  16. // NewAmneziaWGJob creates a new AmneziaWG reconcile job instance.
  17. func NewAmneziaWGJob() *AmneziaWGJob {
  18. return new(AmneziaWGJob)
  19. }
  20. // Run reconciles desired AmneziaWG inbounds with running embedded interfaces.
  21. func (j *AmneziaWGJob) Run() {
  22. desired, err := j.inboundService.DesiredAmneziaWGInstances()
  23. if err != nil {
  24. logger.Warning("amneziawg job: get desired instances failed:", err)
  25. return
  26. }
  27. wanted := make([]amneziawgnet.Desired, 0, len(desired))
  28. for _, inst := range desired {
  29. wanted = append(wanted, amneziawgnet.Desired{
  30. Instance: inst,
  31. Options: amneziawgnet.DeviceOptions{
  32. HeaderProtectionKey: inst.Obfuscation.HeaderProtectionKey,
  33. ContentPaddingAddition: inst.Obfuscation.ContentPaddingAddition,
  34. RekeyAfterTime: inst.Obfuscation.RekeyAfterTime,
  35. RekeyTimeout: inst.Obfuscation.RekeyTimeout,
  36. RejectAfterTime: inst.Obfuscation.RejectAfterTime,
  37. KeepaliveTimeout: inst.Obfuscation.KeepaliveTimeout,
  38. MaxHandshakeAttempts: inst.Obfuscation.MaxHandshakeAttempts,
  39. RandomTrailers: inst.Obfuscation.RandomTrailers,
  40. DisableCookies: inst.Obfuscation.DisableCookies,
  41. },
  42. })
  43. }
  44. amneziawgnet.GetManager().Reconcile(wanted)
  45. outboundDesired, err := j.desiredOutboundInstances()
  46. if err != nil {
  47. logger.Warning("amneziawg job: get desired outbound instances failed:", err)
  48. return
  49. }
  50. amneziawgnet.GetOutboundManager().Reconcile(outboundDesired)
  51. }
  52. // desiredOutboundInstances derives client instances per template "amneziawg" outbound.
  53. func (j *AmneziaWGJob) desiredOutboundInstances() ([]amneziawgnet.OutboundDesired, error) {
  54. template, err := j.settingService.GetXrayConfigTemplate()
  55. if err != nil {
  56. return nil, err
  57. }
  58. if template == "" {
  59. return nil, nil
  60. }
  61. cfg := &xray.Config{}
  62. if err := json.Unmarshal([]byte(template), cfg); err != nil {
  63. return nil, err
  64. }
  65. if len(cfg.OutboundConfigs) == 0 {
  66. return nil, nil
  67. }
  68. var raws []json.RawMessage
  69. if err := json.Unmarshal(cfg.OutboundConfigs, &raws); err != nil {
  70. return nil, err
  71. }
  72. out := make([]amneziawgnet.OutboundDesired, 0, len(raws))
  73. for _, raw := range raws {
  74. if !amneziawg.IsAmneziaWGOutbound(raw) {
  75. continue
  76. }
  77. var probe struct {
  78. Tag string `json:"tag"`
  79. }
  80. if err := json.Unmarshal(raw, &probe); err != nil || probe.Tag == "" {
  81. continue
  82. }
  83. inst, ok := amneziawg.InstanceFromOutbound(probe.Tag, raw)
  84. if !ok {
  85. continue
  86. }
  87. out = append(out, amneziawgnet.OutboundDesired{
  88. Instance: inst,
  89. Options: amneziawgnet.DeviceOptions{
  90. HeaderProtectionKey: inst.Obfuscation.HeaderProtectionKey,
  91. ContentPaddingAddition: inst.Obfuscation.ContentPaddingAddition,
  92. RekeyAfterTime: inst.Obfuscation.RekeyAfterTime,
  93. RekeyTimeout: inst.Obfuscation.RekeyTimeout,
  94. RejectAfterTime: inst.Obfuscation.RejectAfterTime,
  95. KeepaliveTimeout: inst.Obfuscation.KeepaliveTimeout,
  96. MaxHandshakeAttempts: inst.Obfuscation.MaxHandshakeAttempts,
  97. RandomTrailers: inst.Obfuscation.RandomTrailers,
  98. DisableCookies: inst.Obfuscation.DisableCookies,
  99. },
  100. })
  101. }
  102. return out, nil
  103. }