socks_config.go 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. package amneziawgnet
  2. import (
  3. "crypto/rand"
  4. "encoding/base64"
  5. "fmt"
  6. "sync"
  7. )
  8. // SOCKSBasePort is the first loopback port used for an AmneziaWG inbound's
  9. // own Xray SOCKS5 relay inbound (see relay.go/SocksInboundSettings).
  10. const SOCKSBasePort = 65100
  11. // relayPortSlots is how many ids fit above SOCKSBasePort before wrapping.
  12. const relayPortSlots = 65535 - SOCKSBasePort
  13. // SOCKSPortForInbound derives one inbound's loopback SOCKS5 relay port from
  14. // its id, wrapping ids past relayPortSlots so no id ever lacks a port.
  15. func SOCKSPortForInbound(inboundID int) int {
  16. return SOCKSBasePort + 1 + (inboundID-1)%relayPortSlots
  17. }
  18. var (
  19. socksPasswordOnce sync.Once
  20. socksPassword string
  21. )
  22. // SocksPassword returns the process-wide password used to authenticate into
  23. // every AmneziaWG SOCKS5 relay inbound, generating and caching it once
  24. // (lazily, on first use) rather than persisting it anywhere: this traffic
  25. // never leaves loopback, both the config generator (SocksInboundSettings'
  26. // caller) and the relay dialer (SocksRelay/UDPRelay) live in this same
  27. // process, and Xray's own generated config is already rebuilt from scratch
  28. // on every reconcile -- there is nothing for a stored value to survive
  29. // across that a fresh one wouldn't equally satisfy. Not a real secret (see
  30. // SocksRelay's own doc comment); this only needs to be unpredictable enough
  31. // that nothing outside this process could plausibly guess it and dial in
  32. // over loopback.
  33. func SocksPassword() string {
  34. socksPasswordOnce.Do(func() {
  35. var b [24]byte
  36. if _, err := rand.Read(b[:]); err != nil {
  37. // crypto/rand failing is effectively unrecoverable for a
  38. // process that generates real WireGuard keys elsewhere too;
  39. // a fixed fallback keeps this from panicking outright.
  40. socksPassword = fmt.Sprintf("amneziawgnet-fallback-%x", b)
  41. return
  42. }
  43. socksPassword = base64.RawURLEncoding.EncodeToString(b[:])
  44. })
  45. return socksPassword
  46. }