net.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package ovpm
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "net"
  6. "time"
  7. "github.com/Sirupsen/logrus"
  8. "github.com/coreos/go-iptables/iptables"
  9. )
  10. // routedInterface returns a network interface that can route IP
  11. // traffic and satisfies flags. It returns nil when an appropriate
  12. // network interface is not found. Network must be "ip", "ip4" or
  13. // "ip6".
  14. func routedInterface(network string, flags net.Flags) *net.Interface {
  15. switch network {
  16. case "ip", "ip4", "ip6":
  17. default:
  18. return nil
  19. }
  20. ift, err := net.Interfaces()
  21. if err != nil {
  22. return nil
  23. }
  24. for _, ifi := range ift {
  25. if ifi.Flags&flags != flags {
  26. continue
  27. }
  28. if _, ok := hasRoutableIP(network, &ifi); !ok {
  29. continue
  30. }
  31. return &ifi
  32. }
  33. return nil
  34. }
  35. func hasRoutableIP(network string, ifi *net.Interface) (net.IP, bool) {
  36. ifat, err := ifi.Addrs()
  37. if err != nil {
  38. return nil, false
  39. }
  40. for _, ifa := range ifat {
  41. switch ifa := ifa.(type) {
  42. case *net.IPAddr:
  43. if ip := routableIP(network, ifa.IP); ip != nil {
  44. return ip, true
  45. }
  46. case *net.IPNet:
  47. if ip := routableIP(network, ifa.IP); ip != nil {
  48. return ip, true
  49. }
  50. }
  51. }
  52. return nil, false
  53. }
  54. func vpnInterface() *net.Interface {
  55. mask := net.IPMask(net.ParseIP(_DefaultServerNetMask))
  56. prefix := net.ParseIP(_DefaultServerNetwork)
  57. netw := prefix.Mask(mask).To4()
  58. netw[3] = byte(1) // Server is always gets xxx.xxx.xxx.1
  59. ipnet := net.IPNet{IP: netw, Mask: mask}
  60. ifs, err := net.Interfaces()
  61. if err != nil {
  62. logrus.Errorf("can not get system network interfaces: %v", err)
  63. return nil
  64. }
  65. for _, ifc := range ifs {
  66. addrs, err := ifc.Addrs()
  67. if err != nil {
  68. logrus.Errorf("can not get interface addresses: %v", err)
  69. return nil
  70. }
  71. for _, addr := range addrs {
  72. //logrus.Debugf("addr: %s == %s", addr.String(), ipnet.String())
  73. if addr.String() == ipnet.String() {
  74. return &ifc
  75. }
  76. }
  77. }
  78. return nil
  79. }
  80. func routableIP(network string, ip net.IP) net.IP {
  81. if !ip.IsLoopback() && !ip.IsLinkLocalUnicast() && !ip.IsGlobalUnicast() {
  82. return nil
  83. }
  84. switch network {
  85. case "ip4":
  86. if ip := ip.To4(); ip != nil {
  87. return ip
  88. }
  89. case "ip6":
  90. if ip.IsLoopback() { // addressing scope of the loopback address depends on each implementation
  91. return nil
  92. }
  93. if ip := ip.To16(); ip != nil && ip.To4() == nil {
  94. return ip
  95. }
  96. default:
  97. if ip := ip.To4(); ip != nil {
  98. return ip
  99. }
  100. if ip := ip.To16(); ip != nil {
  101. return ip
  102. }
  103. }
  104. return nil
  105. }
  106. // ensureNatEnabled launches a goroutine that constantly tries to enable nat.
  107. func ensureNatEnabled() {
  108. // Nat enablerer
  109. go func() {
  110. for {
  111. err := enableNat()
  112. if err == nil {
  113. logrus.Debug("nat is enabled")
  114. return
  115. }
  116. logrus.Debugf("can not enable nat: %v", err)
  117. // TODO(cad): employ a exponential back-off approach here
  118. // instead of sleeping for the constant duration.
  119. time.Sleep(1 * time.Second)
  120. }
  121. }()
  122. }
  123. // enableNat is an idempotent command that ensures nat is enabled for the vpn server.
  124. func enableNat() error {
  125. rif := routedInterface("ip", net.FlagUp|net.FlagBroadcast)
  126. if rif == nil {
  127. return fmt.Errorf("can not get routable network interface")
  128. }
  129. vpnIfc := vpnInterface()
  130. if vpnIfc == nil {
  131. return fmt.Errorf("can not get vpn network interface on the system")
  132. }
  133. // Enable ip forwarding.
  134. emitToFile("/proc/sys/net/ipv4/ip_forward", "1", 0)
  135. ipt, err := iptables.NewWithProtocol(iptables.ProtocolIPv4)
  136. if err != nil {
  137. return fmt.Errorf("can not create new iptables object: %v", err)
  138. }
  139. // Append iptables nat rules.
  140. ipt.AppendUnique("nat", "POSTROUTING", "-o", rif.Name, "-j", "MASQUERADE")
  141. // TODO(cad): we should use the interface name that we get when we query the system
  142. // with the vpn server's internal ip address, instead of default "tun0".
  143. ipt.AppendUnique("filter", "FORWARD", "-i", rif.Name, "-o", vpnIfc.Name, "-m", "state", "--state", "RELATED, ESTABLISHED", "-j", "ACCEPT")
  144. ipt.AppendUnique("filter", "FORWARD", "-i", vpnIfc.Name, "-o", rif.Name, "-j", "ACCEPT")
  145. return nil
  146. }
  147. func HostID2IP(hostid uint32) net.IP {
  148. ip := make([]byte, 4)
  149. binary.BigEndian.PutUint32(ip, hostid)
  150. return net.IP(ip)
  151. }
  152. func IP2HostID(ip net.IP) uint32 {
  153. hostid := binary.BigEndian.Uint32(ip)
  154. return hostid
  155. }