iptables.go 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package serverctl
  2. import (
  3. "errors"
  4. "net"
  5. "os"
  6. "os/exec"
  7. "strings"
  8. "time"
  9. "github.com/gravitl/netmaker/logger"
  10. "github.com/gravitl/netmaker/netclient/ncutils"
  11. "github.com/gravitl/netmaker/servercfg"
  12. )
  13. const netmakerProcessName = "netmaker"
  14. // InitIPTables - intializes the server iptables
  15. func InitIPTables() error {
  16. _, err := exec.LookPath("iptables")
  17. if err != nil {
  18. return err
  19. }
  20. err = setForwardPolicy()
  21. if err != nil {
  22. logger.Log(0, "error setting iptables forward policy: "+err.Error())
  23. }
  24. err = portForwardServices()
  25. if err != nil {
  26. return err
  27. }
  28. if isContainerized() && servercfg.IsHostNetwork() {
  29. err = setHostCoreDNSMapping()
  30. }
  31. return err
  32. }
  33. // set up port forwarding for services listed in config
  34. func portForwardServices() error {
  35. var err error
  36. services := servercfg.GetPortForwardServiceList()
  37. if len(services) == 0 || services[0] == "" {
  38. return nil
  39. }
  40. for _, service := range services {
  41. switch service {
  42. case "mq":
  43. err = iptablesPortForward("mq", "1883", "1883", false)
  44. case "dns":
  45. err = iptablesPortForward("coredns", "53", "53", false)
  46. case "ssh":
  47. err = iptablesPortForward("netmaker", "22", "22", false)
  48. default:
  49. params := strings.Split(service, ":")
  50. if len(params) == 3 {
  51. err = iptablesPortForward(params[0], params[1], params[2], true)
  52. }
  53. }
  54. if err != nil {
  55. return err
  56. }
  57. }
  58. return nil
  59. }
  60. // determine if process is running in container
  61. func isContainerized() bool {
  62. fileBytes, err := os.ReadFile("/proc/1/sched")
  63. if err != nil {
  64. logger.Log(1, "error determining containerization: "+err.Error())
  65. return false
  66. }
  67. fileString := string(fileBytes)
  68. return strings.Contains(fileString, netmakerProcessName)
  69. }
  70. // make sure host allows forwarding
  71. func setForwardPolicy() error {
  72. logger.Log(1, "setting iptables forward policy")
  73. _, err := ncutils.RunCmd("iptables --policy FORWARD ACCEPT", false)
  74. return err
  75. }
  76. // port forward from an entry, can contain a dns name for lookup
  77. func iptablesPortForward(entry string, inport string, outport string, isIP bool) error {
  78. logger.Log(1, "forwarding "+entry+" traffic from host port "+inport+" to container port "+outport)
  79. var address string
  80. if !isIP {
  81. out:
  82. for i := 1; i < 4; i++ {
  83. ips, err := net.LookupIP(entry)
  84. if err != nil && i > 2 {
  85. return err
  86. }
  87. for _, ip := range ips {
  88. if ipv4 := ip.To4(); ipv4 != nil {
  89. address = ipv4.String()
  90. }
  91. }
  92. if address != "" {
  93. break out
  94. }
  95. time.Sleep(time.Second)
  96. }
  97. } else {
  98. address = entry
  99. }
  100. if address == "" {
  101. return errors.New("could not locate ip for " + entry)
  102. }
  103. _, err := ncutils.RunCmd("iptables -t nat -A PREROUTING -p tcp --dport "+inport+" -j DNAT --to-destination "+address+":"+outport, false)
  104. if err != nil {
  105. return err
  106. }
  107. _, err = ncutils.RunCmd("iptables -t nat -A PREROUTING -p udp --dport "+inport+" -j DNAT --to-destination "+address+":"+outport, false)
  108. if err != nil {
  109. return err
  110. }
  111. _, err = ncutils.RunCmd("iptables -t nat -A POSTROUTING -j MASQUERADE", false)
  112. return err
  113. }
  114. // if running in host networking mode, run iptables to map to CoreDNS container
  115. func setHostCoreDNSMapping() error {
  116. logger.Log(1, "forwarding dns traffic on host from netmaker interfaces to 53053")
  117. ncutils.RunCmd("iptables -t nat -A PREROUTING -i nm-+ -p tcp --match tcp --dport 53 --jump REDIRECT --to-ports 53053", true)
  118. _, err := ncutils.RunCmd("iptables -t nat -A PREROUTING -i nm-+ -p udp --match udp --dport 53 --jump REDIRECT --to-ports 53053", true)
  119. return err
  120. }