Skip to content

Commit

Permalink
Move the iptables setup for embedded DNS into a reexec process
Browse files Browse the repository at this point in the history
Signed-off-by: Santhosh Manohar <santhosh@docker.com>
  • Loading branch information
Santhosh Manohar committed Apr 16, 2016
1 parent 6909b08 commit ddef81d
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 18 deletions.
23 changes: 5 additions & 18 deletions resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"time"

log "github.com/Sirupsen/logrus"
"github.com/docker/libnetwork/iptables"
"github.com/docker/libnetwork/types"
"github.com/miekg/dns"
)
Expand Down Expand Up @@ -105,8 +104,6 @@ func (r *resolver) SetupFunc() func() {
r.err = fmt.Errorf("error in opening name server socket %v", err)
return
}
laddr := r.conn.LocalAddr()
_, ipPort, _ := net.SplitHostPort(laddr.String())

// Listen on a TCP as well
tcpaddr := &net.TCPAddr{
Expand All @@ -118,21 +115,6 @@ func (r *resolver) SetupFunc() func() {
r.err = fmt.Errorf("error in opening name TCP server socket %v", err)
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
})
}
Expand All @@ -142,6 +124,11 @@ func (r *resolver) Start() error {
if r.err != nil {
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}
r.server = s
go func() {
Expand Down
77 changes: 77 additions & 0 deletions resolver_unix.go
Original file line number Diff line number Diff line change
@@ -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 changes: 7 additions & 0 deletions resolver_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build windows

package libnetwork

func (r *resolver) setupIPTable() error {
return nil
}

0 comments on commit ddef81d

Please sign in to comment.