resolver_unix.go 2.5 KB

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