iptables.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  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 = setForwardPolicy()
  21. if err != nil {
  22. logger.Log(0, "error setting iptables forward policy: "+err.Error())
  23. }
  24. err = portForwardServices(force)
  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(force bool) 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", servercfg.GetMQServerPort(), servercfg.GetMQServerPort(), false, force)
  44. case "dns":
  45. err = iptablesPortForward("coredns", "53", "53", false, force)
  46. case "ssh":
  47. err = iptablesPortForward("netmaker", "22", "22", false, force)
  48. default:
  49. params := strings.Split(service, ":")
  50. if len(params) == 3 {
  51. err = iptablesPortForward(params[0], params[1], params[2], true, force)
  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(2, "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, force bool) error {
  78. var address string
  79. if !isIP {
  80. out:
  81. for i := 1; i < 4; i++ {
  82. ips, err := net.LookupIP(entry)
  83. if err != nil && i > 2 {
  84. return err
  85. }
  86. for _, ip := range ips {
  87. if ipv4 := ip.To4(); ipv4 != nil {
  88. address = ipv4.String()
  89. }
  90. }
  91. if address != "" {
  92. break out
  93. }
  94. time.Sleep(time.Second)
  95. }
  96. } else {
  97. address = entry
  98. }
  99. if address == "" {
  100. return errors.New("could not locate ip for " + entry)
  101. }
  102. 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 {
  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. } else {
  114. logger.Log(3, "mq forwarding is already set... skipping")
  115. }
  116. return nil
  117. }
  118. // if running in host networking mode, run iptables to map to CoreDNS container
  119. func setHostCoreDNSMapping() error {
  120. logger.Log(1, "forwarding dns traffic on host from netmaker interfaces to 53053")
  121. ncutils.RunCmd("iptables -t nat -A PREROUTING -i nm-+ -p tcp --match tcp --dport 53 --jump REDIRECT --to-ports 53053", true)
  122. _, err := ncutils.RunCmd("iptables -t nat -A PREROUTING -i nm-+ -p udp --match udp --dport 53 --jump REDIRECT --to-ports 53053", true)
  123. return err
  124. }