github.com/jfrazelle/docker@v1.1.2-0.20210712172922-bf78e25fe508/libnetwork/drivers/bridge/setup_ip_tables_test.go (about) 1 // +build linux 2 3 package bridge 4 5 import ( 6 "net" 7 "testing" 8 9 "github.com/docker/docker/libnetwork/iptables" 10 "github.com/docker/docker/libnetwork/portmapper" 11 "github.com/docker/docker/libnetwork/testutils" 12 "github.com/vishvananda/netlink" 13 ) 14 15 const ( 16 iptablesTestBridgeIP = "192.168.42.1" 17 ) 18 19 func TestProgramIPTable(t *testing.T) { 20 // Create a test bridge with a basic bridge configuration (name + IPv4). 21 defer testutils.SetupTestOSContext(t)() 22 23 nh, err := netlink.NewHandle() 24 if err != nil { 25 t.Fatal(err) 26 } 27 28 createTestBridge(getBasicTestConfig(), &bridgeInterface{nlh: nh}, t) 29 30 // Store various iptables chain rules we care for. 31 rules := []struct { 32 rule iptRule 33 descr string 34 }{ 35 {iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-d", "127.1.2.3", "-i", "lo", "-o", "lo", "-j", "DROP"}}, "Test Loopback"}, 36 {iptRule{table: iptables.Nat, chain: "POSTROUTING", preArgs: []string{"-t", "nat"}, args: []string{"-s", iptablesTestBridgeIP, "!", "-o", DefaultBridgeName, "-j", "MASQUERADE"}}, "NAT Test"}, 37 {iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-o", DefaultBridgeName, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"}}, "Test ACCEPT INCOMING"}, 38 {iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-i", DefaultBridgeName, "!", "-o", DefaultBridgeName, "-j", "ACCEPT"}}, "Test ACCEPT NON_ICC OUTGOING"}, 39 {iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-i", DefaultBridgeName, "-o", DefaultBridgeName, "-j", "ACCEPT"}}, "Test enable ICC"}, 40 {iptRule{table: iptables.Filter, chain: "FORWARD", args: []string{"-i", DefaultBridgeName, "-o", DefaultBridgeName, "-j", "DROP"}}, "Test disable ICC"}, 41 } 42 43 // Assert the chain rules' insertion and removal. 44 for _, c := range rules { 45 assertIPTableChainProgramming(c.rule, c.descr, t) 46 } 47 } 48 49 func TestSetupIPChains(t *testing.T) { 50 // Create a test bridge with a basic bridge configuration (name + IPv4). 51 defer testutils.SetupTestOSContext(t)() 52 53 nh, err := netlink.NewHandle() 54 if err != nil { 55 t.Fatal(err) 56 } 57 58 driverconfig := &configuration{ 59 EnableIPTables: true, 60 } 61 d := &driver{ 62 config: driverconfig, 63 } 64 assertChainConfig(d, t) 65 66 config := getBasicTestConfig() 67 br := &bridgeInterface{nlh: nh} 68 createTestBridge(config, br, t) 69 70 assertBridgeConfig(config, br, d, t) 71 72 config.EnableIPMasquerade = true 73 assertBridgeConfig(config, br, d, t) 74 75 config.EnableICC = true 76 assertBridgeConfig(config, br, d, t) 77 78 config.EnableIPMasquerade = false 79 assertBridgeConfig(config, br, d, t) 80 } 81 82 func getBasicTestConfig() *networkConfiguration { 83 config := &networkConfiguration{ 84 BridgeName: DefaultBridgeName, 85 AddressIPv4: &net.IPNet{IP: net.ParseIP(iptablesTestBridgeIP), Mask: net.CIDRMask(16, 32)}} 86 return config 87 } 88 89 func createTestBridge(config *networkConfiguration, br *bridgeInterface, t *testing.T) { 90 if err := setupDevice(config, br); err != nil { 91 t.Fatalf("Failed to create the testing Bridge: %s", err.Error()) 92 } 93 if err := setupBridgeIPv4(config, br); err != nil { 94 t.Fatalf("Failed to bring up the testing Bridge: %s", err.Error()) 95 } 96 } 97 98 // Assert base function which pushes iptables chain rules on insertion and removal. 99 func assertIPTableChainProgramming(rule iptRule, descr string, t *testing.T) { 100 // Add 101 if err := programChainRule(iptables.IPv4, rule, descr, true); err != nil { 102 t.Fatalf("Failed to program iptable rule %s: %s", descr, err.Error()) 103 } 104 105 iptable := iptables.GetIptable(iptables.IPv4) 106 if iptable.Exists(rule.table, rule.chain, rule.args...) == false { 107 t.Fatalf("Failed to effectively program iptable rule: %s", descr) 108 } 109 110 // Remove 111 if err := programChainRule(iptables.IPv4, rule, descr, false); err != nil { 112 t.Fatalf("Failed to remove iptable rule %s: %s", descr, err.Error()) 113 } 114 if iptable.Exists(rule.table, rule.chain, rule.args...) == true { 115 t.Fatalf("Failed to effectively remove iptable rule: %s", descr) 116 } 117 } 118 119 // Assert function which create chains. 120 func assertChainConfig(d *driver, t *testing.T) { 121 var err error 122 123 d.natChain, d.filterChain, d.isolationChain1, d.isolationChain2, err = setupIPChains(d.config, iptables.IPv4) 124 if err != nil { 125 t.Fatal(err) 126 } 127 } 128 129 // Assert function which pushes chains based on bridge config parameters. 130 func assertBridgeConfig(config *networkConfiguration, br *bridgeInterface, d *driver, t *testing.T) { 131 nw := bridgeNetwork{portMapper: portmapper.New(""), 132 config: config} 133 nw.driver = d 134 135 // Attempt programming of ip tables. 136 err := nw.setupIP4Tables(config, br) 137 if err != nil { 138 t.Fatalf("%v", err) 139 } 140 }