resolver_unix.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //go:build !windows
  2. // +build !windows
  3. package libnetwork
  4. import (
  5. "fmt"
  6. "net"
  7. "github.com/docker/docker/libnetwork/iptables"
  8. )
  9. const (
  10. // output chain used for docker embedded DNS resolver
  11. outputChain = "DOCKER_OUTPUT"
  12. // postrouting chain used for docker embedded DNS resolver
  13. postroutingChain = "DOCKER_POSTROUTING"
  14. )
  15. func (r *Resolver) setupIPTable() error {
  16. if r.err != nil {
  17. return r.err
  18. }
  19. laddr := r.conn.LocalAddr().String()
  20. ltcpaddr := r.tcpListen.Addr().String()
  21. resolverIP, ipPort, _ := net.SplitHostPort(laddr)
  22. _, tcpPort, _ := net.SplitHostPort(ltcpaddr)
  23. rules := [][]string{
  24. {"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr},
  25. {"-t", "nat", "-I", postroutingChain, "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
  26. {"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", ltcpaddr},
  27. {"-t", "nat", "-I", postroutingChain, "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
  28. }
  29. var setupErr error
  30. err := r.backend.ExecFunc(func() {
  31. // TODO IPv6 support
  32. iptable := iptables.GetIptable(iptables.IPv4)
  33. // insert outputChain and postroutingchain
  34. if iptable.ExistsNative("nat", "OUTPUT", "-d", resolverIP, "-j", outputChain) {
  35. if err := iptable.RawCombinedOutputNative("-t", "nat", "-F", outputChain); err != nil {
  36. setupErr = err
  37. return
  38. }
  39. } else {
  40. if err := iptable.RawCombinedOutputNative("-t", "nat", "-N", outputChain); err != nil {
  41. setupErr = err
  42. return
  43. }
  44. if err := iptable.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain); err != nil {
  45. setupErr = err
  46. return
  47. }
  48. }
  49. if iptable.ExistsNative("nat", "POSTROUTING", "-d", resolverIP, "-j", postroutingChain) {
  50. if err := iptable.RawCombinedOutputNative("-t", "nat", "-F", postroutingChain); err != nil {
  51. setupErr = err
  52. return
  53. }
  54. } else {
  55. if err := iptable.RawCombinedOutputNative("-t", "nat", "-N", postroutingChain); err != nil {
  56. setupErr = err
  57. return
  58. }
  59. if err := iptable.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingChain); err != nil {
  60. setupErr = err
  61. return
  62. }
  63. }
  64. for _, rule := range rules {
  65. if iptable.RawCombinedOutputNative(rule...) != nil {
  66. setupErr = fmt.Errorf("set up rule failed, %v", rule)
  67. return
  68. }
  69. }
  70. })
  71. if err != nil {
  72. return err
  73. }
  74. return setupErr
  75. }