resolver_unix.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. // +build !windows
  2. package libnetwork
  3. import (
  4. "fmt"
  5. "net"
  6. "os"
  7. "os/exec"
  8. "runtime"
  9. log "github.com/Sirupsen/logrus"
  10. "github.com/docker/docker/pkg/reexec"
  11. "github.com/docker/libnetwork/iptables"
  12. "github.com/vishvananda/netns"
  13. )
  14. func init() {
  15. reexec.Register("setup-resolver", reexecSetupResolver)
  16. }
  17. func reexecSetupResolver() {
  18. runtime.LockOSThread()
  19. defer runtime.UnlockOSThread()
  20. if len(os.Args) < 4 {
  21. log.Error("invalid number of arguments..")
  22. os.Exit(1)
  23. }
  24. _, ipPort, _ := net.SplitHostPort(os.Args[2])
  25. _, tcpPort, _ := net.SplitHostPort(os.Args[3])
  26. rules := [][]string{
  27. {"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[2]},
  28. {"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
  29. {"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[3]},
  30. {"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
  31. }
  32. f, err := os.OpenFile(os.Args[1], os.O_RDONLY, 0)
  33. if err != nil {
  34. log.Errorf("failed get network namespace %q: %v", os.Args[1], err)
  35. os.Exit(2)
  36. }
  37. defer f.Close()
  38. nsFD := f.Fd()
  39. if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
  40. log.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
  41. os.Exit(3)
  42. }
  43. for _, rule := range rules {
  44. if iptables.RawCombinedOutputNative(rule...) != nil {
  45. log.Errorf("setting up rule failed, %v", rule)
  46. }
  47. }
  48. }
  49. func (r *resolver) setupIPTable() error {
  50. if r.err != nil {
  51. return r.err
  52. }
  53. laddr := r.conn.LocalAddr().String()
  54. ltcpaddr := r.tcpListen.Addr().String()
  55. cmd := &exec.Cmd{
  56. Path: reexec.Self(),
  57. Args: append([]string{"setup-resolver"}, r.sb.Key(), laddr, ltcpaddr),
  58. Stdout: os.Stdout,
  59. Stderr: os.Stderr,
  60. }
  61. if err := cmd.Run(); err != nil {
  62. return fmt.Errorf("reexec failed: %v", err)
  63. }
  64. return nil
  65. }