libnetwork: setup DNS resolver without reexec
Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
parent
4733127a04
commit
50a4951ddc
1 changed files with 35 additions and 78 deletions
|
@ -4,22 +4,12 @@
|
|||
package libnetwork
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"os"
|
||||
"os/exec"
|
||||
"runtime"
|
||||
|
||||
"github.com/docker/docker/libnetwork/iptables"
|
||||
"github.com/docker/docker/pkg/reexec"
|
||||
"github.com/sirupsen/logrus"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
func init() {
|
||||
reexec.Register("setup-resolver", reexecSetupResolver)
|
||||
}
|
||||
|
||||
const (
|
||||
// outputChain used for docker embed dns
|
||||
outputChain = "DOCKER_OUTPUT"
|
||||
|
@ -27,79 +17,46 @@ const (
|
|||
postroutingchain = "DOCKER_POSTROUTING"
|
||||
)
|
||||
|
||||
func reexecSetupResolver() {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
|
||||
if len(os.Args) < 4 {
|
||||
logrus.Error("invalid number of arguments..")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
resolverIP, 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 {
|
||||
logrus.Errorf("failed get network namespace %q: %v", os.Args[1], err)
|
||||
os.Exit(2)
|
||||
}
|
||||
defer f.Close() //nolint:gosec
|
||||
|
||||
nsFD := f.Fd()
|
||||
if err = netns.Set(netns.NsHandle(nsFD)); err != nil {
|
||||
logrus.Errorf("setting into container net ns %v failed, %v", os.Args[1], err)
|
||||
os.Exit(3)
|
||||
}
|
||||
|
||||
// TODO IPv6 support
|
||||
iptable := iptables.GetIptable(iptables.IPv4)
|
||||
|
||||
// insert outputChain and postroutingchain
|
||||
err = iptable.RawCombinedOutputNative("-t", "nat", "-C", "OUTPUT", "-d", resolverIP, "-j", outputChain)
|
||||
if err == nil {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-F", outputChain)
|
||||
} else {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-N", outputChain)
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain)
|
||||
}
|
||||
|
||||
err = iptable.RawCombinedOutputNative("-t", "nat", "-C", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
|
||||
if err == nil {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-F", postroutingchain)
|
||||
} else {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-N", postroutingchain)
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
if iptable.RawCombinedOutputNative(rule...) != nil {
|
||||
logrus.Errorf("set 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()
|
||||
resolverIP, ipPort, _ := net.SplitHostPort(laddr)
|
||||
_, tcpPort, _ := net.SplitHostPort(ltcpaddr)
|
||||
rules := [][]string{
|
||||
{"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr},
|
||||
{"-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", ltcpaddr},
|
||||
{"-t", "nat", "-I", postroutingchain, "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
||||
}
|
||||
|
||||
cmd := &exec.Cmd{
|
||||
Path: reexec.Self(),
|
||||
Args: append([]string{"setup-resolver"}, r.resolverKey, laddr, ltcpaddr),
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
}
|
||||
if err := cmd.Run(); err != nil {
|
||||
return fmt.Errorf("reexec failed: %v", err)
|
||||
}
|
||||
return nil
|
||||
return r.backend.ExecFunc(func() {
|
||||
// TODO IPv6 support
|
||||
iptable := iptables.GetIptable(iptables.IPv4)
|
||||
|
||||
// insert outputChain and postroutingchain
|
||||
err := iptable.RawCombinedOutputNative("-t", "nat", "-C", "OUTPUT", "-d", resolverIP, "-j", outputChain)
|
||||
if err == nil {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-F", outputChain)
|
||||
} else {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-N", outputChain)
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain)
|
||||
}
|
||||
|
||||
err = iptable.RawCombinedOutputNative("-t", "nat", "-C", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
|
||||
if err == nil {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-F", postroutingchain)
|
||||
} else {
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-N", postroutingchain)
|
||||
iptable.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingchain)
|
||||
}
|
||||
|
||||
for _, rule := range rules {
|
||||
if iptable.RawCombinedOutputNative(rule...) != nil {
|
||||
logrus.Errorf("set up rule failed, %v", rule)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue