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