33package libnetwork
44
55import (
6+ "context"
67 "fmt"
78 "net"
89
10+ "github.com/docker/docker/libnetwork/internal/nftables"
911 "github.com/docker/docker/libnetwork/iptables"
1012)
1113
@@ -16,14 +18,22 @@ const (
1618 postroutingChain = "DOCKER_POSTROUTING"
1719)
1820
19- func (r * Resolver ) setupIPTable ( ) error {
21+ func (r * Resolver ) setupNAT ( ctx context. Context ) error {
2022 if r .err != nil {
2123 return r .err
2224 }
2325 laddr := r .conn .LocalAddr ().String ()
2426 ltcpaddr := r .tcpListen .Addr ().String ()
2527 resolverIP , ipPort , _ := net .SplitHostPort (laddr )
2628 _ , tcpPort , _ := net .SplitHostPort (ltcpaddr )
29+
30+ if nftables .Enabled () {
31+ return r .setupNftablesNAT (ctx , laddr , ltcpaddr , resolverIP , ipPort , tcpPort )
32+ }
33+ return r .setupIptablesNAT (laddr , ltcpaddr , resolverIP , ipPort , tcpPort )
34+ }
35+
36+ func (r * Resolver ) setupIptablesNAT (laddr , ltcpaddr , resolverIP , ipPort , tcpPort string ) error {
2737 rules := [][]string {
2838 {"-t" , "nat" , "-I" , outputChain , "-d" , resolverIP , "-p" , "udp" , "--dport" , dnsPort , "-j" , "DNAT" , "--to-destination" , laddr },
2939 {"-t" , "nat" , "-I" , postroutingChain , "-s" , resolverIP , "-p" , "udp" , "--sport" , ipPort , "-j" , "SNAT" , "--to-source" , ":" + dnsPort },
@@ -81,3 +91,40 @@ func (r *Resolver) setupIPTable() error {
8191 }
8292 return setupErr
8393}
94+
95+ func (r * Resolver ) setupNftablesNAT (ctx context.Context , laddr , ltcpaddr , resolverIP , ipPort , tcpPort string ) error {
96+ table , err := nftables .NewTable (nftables .IPv4 , "docker-dns" )
97+ if err != nil {
98+ return err
99+ }
100+
101+ dnatChain , err := table .BaseChain ("dns-dnat" , nftables .BaseChainTypeNAT , nftables .BaseChainHookOutput , nftables .BaseChainPriorityDstNAT )
102+ if err != nil {
103+ return err
104+ }
105+ if err := dnatChain .AppendRule (0 , "ip daddr %s udp dport %s counter dnat to %s" , resolverIP , dnsPort , laddr ); err != nil {
106+ return err
107+ }
108+ if err := dnatChain .AppendRule (0 , "ip daddr %s tcp dport %s counter dnat to %s" , resolverIP , dnsPort , ltcpaddr ); err != nil {
109+ return err
110+ }
111+
112+ snatChain , err := table .BaseChain ("dns-snat" , nftables .BaseChainTypeNAT , nftables .BaseChainHookPostrouting , nftables .BaseChainPrioritySrcNAT )
113+ if err != nil {
114+ return err
115+ }
116+ if err := snatChain .AppendRule (0 , "ip saddr %s udp sport %s counter snat to :%s" , resolverIP , ipPort , dnsPort ); err != nil {
117+ return err
118+ }
119+ if err := snatChain .AppendRule (0 , "ip saddr %s tcp sport %s counter snat to :%s" , resolverIP , tcpPort , dnsPort ); err != nil {
120+ return err
121+ }
122+
123+ var setupErr error
124+ if err := r .backend .ExecFunc (func () {
125+ setupErr = table .Apply (ctx )
126+ }); err != nil {
127+ return err
128+ }
129+ return setupErr
130+ }
0 commit comments