Move the iptables setup for embedded DNS into a reexec process
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
This commit is contained in:
parent
83d261fd47
commit
61510dc222
3 changed files with 89 additions and 18 deletions
|
@ -9,7 +9,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/docker/libnetwork/iptables"
|
|
||||||
"github.com/docker/libnetwork/types"
|
"github.com/docker/libnetwork/types"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
)
|
)
|
||||||
|
@ -105,8 +104,6 @@ func (r *resolver) SetupFunc() func() {
|
||||||
r.err = fmt.Errorf("error in opening name server socket %v", err)
|
r.err = fmt.Errorf("error in opening name server socket %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
laddr := r.conn.LocalAddr()
|
|
||||||
_, ipPort, _ := net.SplitHostPort(laddr.String())
|
|
||||||
|
|
||||||
// Listen on a TCP as well
|
// Listen on a TCP as well
|
||||||
tcpaddr := &net.TCPAddr{
|
tcpaddr := &net.TCPAddr{
|
||||||
|
@ -118,21 +115,6 @@ func (r *resolver) SetupFunc() func() {
|
||||||
r.err = fmt.Errorf("error in opening name TCP server socket %v", err)
|
r.err = fmt.Errorf("error in opening name TCP server socket %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ltcpaddr := r.tcpListen.Addr()
|
|
||||||
_, tcpPort, _ := net.SplitHostPort(ltcpaddr.String())
|
|
||||||
rules := [][]string{
|
|
||||||
{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr.String()},
|
|
||||||
{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
|
||||||
{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", ltcpaddr.String()},
|
|
||||||
{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rule := range rules {
|
|
||||||
r.err = iptables.RawCombinedOutputNative(rule...)
|
|
||||||
if r.err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
r.err = nil
|
r.err = nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -142,6 +124,11 @@ func (r *resolver) Start() error {
|
||||||
if r.err != nil {
|
if r.err != nil {
|
||||||
return r.err
|
return r.err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := r.setupIPTable(); err != nil {
|
||||||
|
return fmt.Errorf("setting up IP table rules failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
s := &dns.Server{Handler: r, PacketConn: r.conn}
|
s := &dns.Server{Handler: r, PacketConn: r.conn}
|
||||||
r.server = s
|
r.server = s
|
||||||
go func() {
|
go func() {
|
||||||
|
|
77
libnetwork/resolver_unix.go
Normal file
77
libnetwork/resolver_unix.go
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
// +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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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", "-A", "OUTPUT", "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[2]},
|
||||||
|
{"-t", "nat", "-A", "POSTROUTING", "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
|
||||||
|
{"-t", "nat", "-A", "OUTPUT", "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[3]},
|
||||||
|
{"-t", "nat", "-A", "POSTROUTING", "-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)
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
7
libnetwork/resolver_windows.go
Normal file
7
libnetwork/resolver_windows.go
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package libnetwork
|
||||||
|
|
||||||
|
func (r *resolver) setupIPTable() error {
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in a new issue