github.com/rawahars/moby@v24.0.4+incompatible/libnetwork/resolver_unix.go (about)

     1  //go:build !windows
     2  // +build !windows
     3  
     4  package libnetwork
     5  
     6  import (
     7  	"fmt"
     8  	"net"
     9  
    10  	"github.com/docker/docker/libnetwork/iptables"
    11  )
    12  
    13  const (
    14  	// output chain used for docker embedded DNS resolver
    15  	outputChain = "DOCKER_OUTPUT"
    16  	// postrouting chain used for docker embedded DNS resolver
    17  	postroutingChain = "DOCKER_POSTROUTING"
    18  )
    19  
    20  func (r *Resolver) setupIPTable() error {
    21  	if r.err != nil {
    22  		return r.err
    23  	}
    24  	laddr := r.conn.LocalAddr().String()
    25  	ltcpaddr := r.tcpListen.Addr().String()
    26  	resolverIP, ipPort, _ := net.SplitHostPort(laddr)
    27  	_, tcpPort, _ := net.SplitHostPort(ltcpaddr)
    28  	rules := [][]string{
    29  		{"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", laddr},
    30  		{"-t", "nat", "-I", postroutingChain, "-s", resolverIP, "-p", "udp", "--sport", ipPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
    31  		{"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "tcp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", ltcpaddr},
    32  		{"-t", "nat", "-I", postroutingChain, "-s", resolverIP, "-p", "tcp", "--sport", tcpPort, "-j", "SNAT", "--to-source", ":" + dnsPort},
    33  	}
    34  
    35  	var setupErr error
    36  	err := r.backend.ExecFunc(func() {
    37  		// TODO IPv6 support
    38  		iptable := iptables.GetIptable(iptables.IPv4)
    39  
    40  		// insert outputChain and postroutingchain
    41  		if iptable.ExistsNative("nat", "OUTPUT", "-d", resolverIP, "-j", outputChain) {
    42  			if err := iptable.RawCombinedOutputNative("-t", "nat", "-F", outputChain); err != nil {
    43  				setupErr = err
    44  				return
    45  			}
    46  		} else {
    47  			if err := iptable.RawCombinedOutputNative("-t", "nat", "-N", outputChain); err != nil {
    48  				setupErr = err
    49  				return
    50  			}
    51  			if err := iptable.RawCombinedOutputNative("-t", "nat", "-I", "OUTPUT", "-d", resolverIP, "-j", outputChain); err != nil {
    52  				setupErr = err
    53  				return
    54  			}
    55  		}
    56  
    57  		if iptable.ExistsNative("nat", "POSTROUTING", "-d", resolverIP, "-j", postroutingChain) {
    58  			if err := iptable.RawCombinedOutputNative("-t", "nat", "-F", postroutingChain); err != nil {
    59  				setupErr = err
    60  				return
    61  			}
    62  		} else {
    63  			if err := iptable.RawCombinedOutputNative("-t", "nat", "-N", postroutingChain); err != nil {
    64  				setupErr = err
    65  				return
    66  			}
    67  			if err := iptable.RawCombinedOutputNative("-t", "nat", "-I", "POSTROUTING", "-d", resolverIP, "-j", postroutingChain); err != nil {
    68  				setupErr = err
    69  				return
    70  			}
    71  		}
    72  
    73  		for _, rule := range rules {
    74  			if iptable.RawCombinedOutputNative(rule...) != nil {
    75  				setupErr = fmt.Errorf("set up rule failed, %v", rule)
    76  				return
    77  			}
    78  		}
    79  	})
    80  	if err != nil {
    81  		return err
    82  	}
    83  	return setupErr
    84  }