wireguard.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. package conf
  2. import (
  3. "encoding/base64"
  4. "encoding/hex"
  5. "github.com/xtls/xray-core/proxy/wireguard"
  6. "google.golang.org/protobuf/proto"
  7. )
  8. type WireGuardPeerConfig struct {
  9. PublicKey string `json:"publicKey"`
  10. PreSharedKey string `json:"preSharedKey"`
  11. Endpoint string `json:"endpoint"`
  12. KeepAlive int `json:"keepAlive"`
  13. AllowedIPs []string `json:"allowedIPs,omitempty"`
  14. }
  15. func (c *WireGuardPeerConfig) Build() (proto.Message, error) {
  16. var err error
  17. config := new(wireguard.PeerConfig)
  18. config.PublicKey, err = parseWireGuardKey(c.PublicKey)
  19. if err != nil {
  20. return nil, err
  21. }
  22. if c.PreSharedKey != "" {
  23. config.PreSharedKey, err = parseWireGuardKey(c.PreSharedKey)
  24. if err != nil {
  25. return nil, err
  26. }
  27. } else {
  28. config.PreSharedKey = "0000000000000000000000000000000000000000000000000000000000000000"
  29. }
  30. config.Endpoint = c.Endpoint
  31. // default 0
  32. config.KeepAlive = int32(c.KeepAlive)
  33. if c.AllowedIPs == nil {
  34. config.AllowedIps = []string{"0.0.0.0/0", "::0/0"}
  35. } else {
  36. config.AllowedIps = c.AllowedIPs
  37. }
  38. return config, nil
  39. }
  40. type WireGuardConfig struct {
  41. SecretKey string `json:"secretKey"`
  42. Address []string `json:"address"`
  43. Peers []*WireGuardPeerConfig `json:"peers"`
  44. MTU int `json:"mtu"`
  45. NumWorkers int `json:"workers"`
  46. Reserved []byte `json:"reserved"`
  47. }
  48. func (c *WireGuardConfig) Build() (proto.Message, error) {
  49. config := new(wireguard.DeviceConfig)
  50. var err error
  51. config.SecretKey, err = parseWireGuardKey(c.SecretKey)
  52. if err != nil {
  53. return nil, err
  54. }
  55. if c.Address == nil {
  56. // bogon ips
  57. config.Endpoint = []string{"10.0.0.1", "fd59:7153:2388:b5fd:0000:0000:0000:0001"}
  58. } else {
  59. config.Endpoint = c.Address
  60. }
  61. if c.Peers != nil {
  62. config.Peers = make([]*wireguard.PeerConfig, len(c.Peers))
  63. for i, p := range c.Peers {
  64. msg, err := p.Build()
  65. if err != nil {
  66. return nil, err
  67. }
  68. config.Peers[i] = msg.(*wireguard.PeerConfig)
  69. }
  70. }
  71. if c.MTU == 0 {
  72. config.Mtu = 1420
  73. } else {
  74. config.Mtu = int32(c.MTU)
  75. }
  76. // these a fallback code exists in github.com/nanoda0523/wireguard-go code,
  77. // we don't need to process fallback manually
  78. config.NumWorkers = int32(c.NumWorkers)
  79. if len(c.Reserved) != 0 && len(c.Reserved) != 3 {
  80. return nil, newError(`"reserved" should be empty or 3 bytes`)
  81. }
  82. config.Reserved = c.Reserved
  83. return config, nil
  84. }
  85. func parseWireGuardKey(str string) (string, error) {
  86. if len(str) != 64 {
  87. // may in base64 form
  88. dat, err := base64.StdEncoding.DecodeString(str)
  89. if err != nil {
  90. return "", err
  91. }
  92. if len(dat) != 32 {
  93. return "", newError("key should be 32 bytes: " + str)
  94. }
  95. return hex.EncodeToString(dat), err
  96. } else {
  97. // already hex form
  98. return str, nil
  99. }
  100. }