123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- // +build !windows
- package libnetwork
- import (
- "fmt"
- "net"
- "os"
- "os/exec"
- "runtime"
- log "github.com/Sirupsen/logrus"
- "github.com/docker/docker/pkg/reexec"
- "github.com/docker/libnetwork/iptables"
- "github.com/vishvananda/netns"
- )
- func init() {
- reexec.Register("setup-resolver", reexecSetupResolver)
- }
- const (
- // outputChain used for docker embed dns
- outputChain = "DOCKER_OUTPUT"
- //postroutingchain used for docker embed dns
- postroutingchain = "DOCKER_POSTROUTING"
- )
- func reexecSetupResolver() {
- runtime.LockOSThread()
- defer runtime.UnlockOSThread()
- if len(os.Args) < 4 {
- log.Error("invalid number of arguments..")
- os.Exit(1)
- }
- _, ipPort, _ := net.SplitHostPort(os.Args[2])
- _, tcpPort, _ := net.SplitHostPort(os.Args[3])
- rules := [][]string{
- {"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[2]},
- {"-t", "nat", "-I", postroutingchain, "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
- {"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[3]},
- {"-t", "nat", "-I", postroutingchain, "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
- }
- f, err := os.OpenFile(os.Args[1], os.O_RDONLY, 0)
- if err != nil {
- log.Errorf("failed get network namespace %q: %v", os.Args[1], err)
- os.Exit(2)
- }
- defer f.Close()
- nsFD := f.Fd()
- if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
- log.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
- os.Exit(3)
- }
- // insert outputChain and postroutingchain
- err = iptables.RawCombinedOutputNative("-t", "nat", "-C", "OUTPUT", "-d", resolverIP, "-j", outputChain)
- if err == nil {
- iptables.RawCombinedOutputNative("-t", "nat", "-F", outputChain)
- } else {
- iptables.RawCombinedOutputNative("-t", "nat", "-N", outputChain)
- iptables.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain)
- }
- err = iptables.RawCombinedOutputNative("-t", "nat", "-C", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
- if err == nil {
- iptables.RawCombinedOutputNative("-t", "nat", "-F", postroutingchain)
- } else {
- iptables.RawCombinedOutputNative("-t", "nat", "-N", postroutingchain)
- iptables.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
- }
- for _, rule := range rules {
- if iptables.RawCombinedOutputNative(rule...) != nil {
- log.Errorf("setting up rule failed, %v", rule)
- }
- }
- }
- func (r *resolver) setupIPTable() error {
- if r.err != nil {
- return r.err
- }
- laddr := r.conn.LocalAddr().String()
- ltcpaddr := r.tcpListen.Addr().String()
- cmd := &exec.Cmd{
- Path: reexec.Self(),
- Args: append([]string{"setup-resolver"}, r.sb.Key(), laddr, ltcpaddr),
- Stdout: os.Stdout,
- Stderr: os.Stderr,
- }
- if err := cmd.Run(); err != nil {
- return fmt.Errorf("reexec failed: %v", err)
- }
- return nil
- }
|