github.com/moby/docker@v26.1.3+incompatible/libnetwork/firewall_linux_test.go (about) 1 package libnetwork 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 8 "github.com/docker/docker/internal/testutils/netnsutils" 9 "github.com/docker/docker/libnetwork/config" 10 "github.com/docker/docker/libnetwork/iptables" 11 "github.com/docker/docker/libnetwork/netlabel" 12 "github.com/docker/docker/libnetwork/options" 13 "gotest.tools/v3/assert" 14 is "gotest.tools/v3/assert/cmp" 15 ) 16 17 const ( 18 fwdChainName = "FORWARD" 19 usrChainName = userChain 20 ) 21 22 func TestUserChain(t *testing.T) { 23 iptable4 := iptables.GetIptable(iptables.IPv4) 24 iptable6 := iptables.GetIptable(iptables.IPv6) 25 26 tests := []struct { 27 iptables bool 28 insert bool // insert other rules to FORWARD 29 fwdChain []string 30 userChain []string 31 }{ 32 { 33 iptables: false, 34 insert: false, 35 fwdChain: []string{"-P FORWARD ACCEPT"}, 36 }, 37 { 38 iptables: true, 39 insert: false, 40 fwdChain: []string{"-P FORWARD ACCEPT", "-A FORWARD -j DOCKER-USER"}, 41 userChain: []string{"-N DOCKER-USER", "-A DOCKER-USER -j RETURN"}, 42 }, 43 { 44 iptables: true, 45 insert: true, 46 fwdChain: []string{"-P FORWARD ACCEPT", "-A FORWARD -j DOCKER-USER", "-A FORWARD -j DROP"}, 47 userChain: []string{"-N DOCKER-USER", "-A DOCKER-USER -j RETURN"}, 48 }, 49 } 50 51 for _, tc := range tests { 52 tc := tc 53 t.Run(fmt.Sprintf("iptables=%v,insert=%v", tc.iptables, tc.insert), func(t *testing.T) { 54 defer netnsutils.SetupTestOSContext(t)() 55 defer resetIptables(t) 56 57 c, err := New( 58 OptionBoltdbWithRandomDBFile(t), 59 config.OptionDriverConfig("bridge", map[string]any{ 60 netlabel.GenericData: options.Generic{ 61 "EnableIPTables": tc.iptables, 62 "EnableIP6Tables": tc.iptables, 63 }, 64 })) 65 assert.NilError(t, err) 66 defer c.Stop() 67 68 // init. condition, FORWARD chain empty DOCKER-USER not exist 69 assert.Check(t, is.DeepEqual(getRules(t, iptable4, fwdChainName), []string{"-P FORWARD ACCEPT"})) 70 assert.Check(t, is.DeepEqual(getRules(t, iptable6, fwdChainName), []string{"-P FORWARD ACCEPT"})) 71 72 if tc.insert { 73 _, err = iptable4.Raw("-A", fwdChainName, "-j", "DROP") 74 assert.Check(t, err) 75 _, err = iptable6.Raw("-A", fwdChainName, "-j", "DROP") 76 assert.Check(t, err) 77 } 78 arrangeUserFilterRule() 79 80 assert.Check(t, is.DeepEqual(getRules(t, iptable4, fwdChainName), tc.fwdChain)) 81 assert.Check(t, is.DeepEqual(getRules(t, iptable6, fwdChainName), tc.fwdChain)) 82 if tc.userChain != nil { 83 assert.Check(t, is.DeepEqual(getRules(t, iptable4, usrChainName), tc.userChain)) 84 assert.Check(t, is.DeepEqual(getRules(t, iptable6, usrChainName), tc.userChain)) 85 } else { 86 _, err = iptable4.Raw("-S", usrChainName) 87 assert.Check(t, is.ErrorContains(err, "No chain/target/match by that name"), "ipv4 chain %v: created unexpectedly", usrChainName) 88 _, err = iptable6.Raw("-S", usrChainName) 89 assert.Check(t, is.ErrorContains(err, "No chain/target/match by that name"), "ipv6 chain %v: created unexpectedly", usrChainName) 90 } 91 }) 92 } 93 } 94 95 func getRules(t *testing.T, iptable *iptables.IPTable, chain string) []string { 96 t.Helper() 97 output, err := iptable.Raw("-S", chain) 98 assert.NilError(t, err, "chain %s: failed to get rules", chain) 99 100 rules := strings.Split(string(output), "\n") 101 if len(rules) > 0 { 102 rules = rules[:len(rules)-1] 103 } 104 return rules 105 } 106 107 func resetIptables(t *testing.T) { 108 t.Helper() 109 110 for _, ipVer := range []iptables.IPVersion{iptables.IPv4, iptables.IPv6} { 111 iptable := iptables.GetIptable(ipVer) 112 113 _, err := iptable.Raw("-F", fwdChainName) 114 assert.Check(t, err) 115 _ = iptable.RemoveExistingChain(usrChainName, iptables.Filter) 116 } 117 }