resolver_unix.go 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. err := iptable.RawCombinedOutputNative("-t", "nat", "-C", "OUTPUT", "-d", resolverIP, "-j", outputChain)
  35. if err == nil {
  36. if err := iptable.RawCombinedOutputNative("-t", "nat", "-F", outputChain); err != nil {
  37. setupErr = err
  38. return
  39. }
  40. } else {
  41. if err := iptable.RawCombinedOutputNative("-t", "nat", "-N", outputChain); err != nil {
  42. setupErr = err
  43. return
  44. }
  45. if err := iptable.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain); err != nil {
  46. setupErr = err
  47. return
  48. }
  49. }
  50. err = iptable.RawCombinedOutputNative("-t", "nat", "-C", "POSTROUTING", "-d", resolverIP, "-j", postroutingChain)
  51. if err == nil {
  52. if err := iptable.RawCombinedOutputNative("-t", "nat", "-F", postroutingChain); err != nil {
  53. setupErr = err
  54. return
  55. }
  56. } else {
  57. if err := iptable.RawCombinedOutputNative("-t", "nat", "-N", postroutingChain); err != nil {
  58. setupErr = err
  59. return
  60. }
  61. if err := iptable.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingChain); err != nil {
  62. setupErr = err
  63. return
  64. }
  65. }
  66. for _, rule := range rules {
  67. if iptable.RawCombinedOutputNative(rule...) != nil {
  68. setupErr = fmt.Errorf("set up rule failed, %v", rule)
  69. return
  70. }
  71. }
  72. })
  73. if err != nil {
  74. return err
  75. }
  76. return setupErr
  77. }