config.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package aerotun
  2. import (
  3. "bytes"
  4. "encoding/base64"
  5. "fmt"
  6. "golang.org/x/crypto/curve25519"
  7. "net"
  8. "net/netip"
  9. "regexp"
  10. "strconv"
  11. "strings"
  12. )
  13. var interfaceName = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]{0,11}$`)
  14. func validateConfig(c *TunnelInstance) error {
  15. if c.Protocol == 0 {
  16. c.Protocol = 2
  17. }
  18. if c.Protocol != 2 && c.Protocol != 3 {
  19. return fmt.Errorf("unsupported AeroTUN version")
  20. }
  21. if c.Protocol == 3 {
  22. if _, err := decodeKey(c.PSK); err != nil {
  23. return err
  24. }
  25. priv, err := decodeKey(c.PrivateKey)
  26. if err != nil {
  27. return fmt.Errorf("invalid local identity key")
  28. }
  29. pub, err := curve25519.X25519(priv, curve25519.Basepoint)
  30. if err != nil {
  31. return err
  32. }
  33. c.PublicKey = base64.StdEncoding.EncodeToString(pub)
  34. if c.PeerPublicKey != "" || !c.Disabled {
  35. peer, err := decodeKey(c.PeerPublicKey)
  36. if err != nil || bytes.Equal(peer, pub) {
  37. return fmt.Errorf("a different pinned peer public key is required")
  38. }
  39. }
  40. if len(c.AllowedIPs) == 0 {
  41. return fmt.Errorf("v3 requires explicit allowed source IP prefixes")
  42. }
  43. for _, prefix := range c.AllowedIPs {
  44. if _, err := netip.ParsePrefix(prefix); err != nil {
  45. return fmt.Errorf("invalid allowed source IP prefix")
  46. }
  47. }
  48. }
  49. c.Mode = strings.ToLower(strings.TrimSpace(c.Mode))
  50. if c.Mode != "server" && c.Mode != "client" {
  51. return fmt.Errorf("mode must be server or client")
  52. }
  53. // Reserve three characters for the fallback endpoint suffix.
  54. if !interfaceName.MatchString(c.Name) {
  55. return fmt.Errorf("interface name must contain 1–12 letters, digits, dots, underscores or dashes")
  56. }
  57. if c.MTU == 0 {
  58. c.MTU = DefaultMTU
  59. }
  60. if c.MTU < 576 || c.MTU > 9000 {
  61. return fmt.Errorf("MTU must be between 576 and 9000")
  62. }
  63. if c.ListenPort == 0 && c.Mode == "server" {
  64. c.ListenPort = DefaultPort
  65. }
  66. if c.ListenPort < 0 || c.ListenPort > 65535 {
  67. return fmt.Errorf("invalid UDP listen port")
  68. }
  69. if len(c.PSK) < 32 {
  70. return fmt.Errorf("PSK must contain at least 32 characters; use Generate Key")
  71. }
  72. ip, _, err := net.ParseCIDR(c.LocalAddress)
  73. if err != nil || ip.IsUnspecified() || ip.IsMulticast() {
  74. return fmt.Errorf("local address must be a unicast IP in CIDR notation")
  75. }
  76. peer, err := peerIP(c.PeerAddress)
  77. if err != nil {
  78. return err
  79. }
  80. if peer != nil && ((ip.To4() == nil) != (peer.To4() == nil) || peer.Equal(ip)) {
  81. return fmt.Errorf("peer and local address must be distinct and use the same IP family")
  82. }
  83. if ip.To4() == nil && c.MTU < 1280 {
  84. return fmt.Errorf("IPv6 requires MTU of at least 1280")
  85. }
  86. if c.Mode == "client" && c.RemoteEndpoint == "" {
  87. return fmt.Errorf("client requires a remote endpoint")
  88. }
  89. if c.RemoteEndpoint != "" {
  90. host, port, err := net.SplitHostPort(c.RemoteEndpoint)
  91. p, portErr := strconv.Atoi(port)
  92. if err != nil || host == "" || portErr != nil || p < 1 || p > 65535 {
  93. return fmt.Errorf("remote endpoint must be host:port")
  94. }
  95. }
  96. if c.DefaultRoute && (c.Mode != "client" || c.RemoteEndpoint == "") {
  97. return fmt.Errorf("default route requires a client with a fixed remote endpoint")
  98. }
  99. return nil
  100. }
  101. func peerIP(s string) (net.IP, error) {
  102. if s == "" {
  103. return nil, nil
  104. }
  105. ip := net.ParseIP(s)
  106. if ip == nil {
  107. ip, _, _ = net.ParseCIDR(s)
  108. }
  109. if ip == nil || ip.IsUnspecified() || ip.IsMulticast() {
  110. return nil, fmt.Errorf("invalid peer IP address")
  111. }
  112. return ip, nil
  113. }
  114. func configurePeer(dev VirtualDevice, c TunnelInstance) error {
  115. peer, err := peerIP(c.PeerAddress)
  116. if err != nil {
  117. return err
  118. }
  119. if peer == nil {
  120. return nil
  121. }
  122. family := "-4"
  123. prefix := "/32"
  124. if peer.To4() == nil {
  125. family = "-6"
  126. prefix = "/128"
  127. }
  128. if _, err := runIP(family, "route", "add", peer.String()+prefix, "dev", dev.Name()); err != nil {
  129. return fmt.Errorf("peer route: %w", err)
  130. }
  131. // ARP is disabled on the veth fallback: explicitly map the peer to its local
  132. // endpoint MAC rather than relying on unresolved Ethernet neighbour discovery.
  133. if v, ok := dev.(*vethTun); ok {
  134. _, err = runIP(family, "neigh", "replace", peer.String(), "lladdr", net.HardwareAddr(v.epHwAddr[:]).String(), "nud", "permanent", "dev", dev.Name())
  135. }
  136. return err
  137. }