iptables.go 3.8 KB

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