github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/integration/networking/net_out_test.go (about) 1 package networking_test 2 3 import ( 4 "fmt" 5 "io" 6 "strings" 7 8 "github.com/cloudfoundry-incubator/garden" 9 . "github.com/onsi/ginkgo" 10 . "github.com/onsi/gomega" 11 12 "github.com/onsi/gomega/gbytes" 13 ) 14 15 var _ = Describe("Net Out", func() { 16 var ( 17 container garden.Container 18 otherContainer garden.Container 19 gardenArgs []string 20 21 containerNetwork string 22 denyRange string 23 allowRange string 24 ) 25 26 const containerHandle = "6e4ea858-6b31-4243-5dcc-093cfb83952d" 27 28 BeforeEach(func() { 29 denyRange = "" 30 allowRange = "" 31 gardenArgs = []string{} 32 }) 33 34 JustBeforeEach(func() { 35 gardenArgs = []string{ 36 "-denyNetworks", strings.Join([]string{ 37 denyRange, 38 allowRange, // so that it can be overridden by allowNetworks below 39 }, ","), 40 "-allowNetworks", allowRange, 41 "-iptablesLogMethod", "nflog", // so that we can read logs when running in fly 42 } 43 client = startGarden(gardenArgs...) 44 45 var err error 46 container, err = client.Create(garden.ContainerSpec{Network: containerNetwork, Privileged: true, Handle: containerHandle}) 47 Expect(err).ToNot(HaveOccurred()) 48 }) 49 50 AfterEach(func() { 51 err := client.Destroy(container.Handle()) 52 Expect(err).ToNot(HaveOccurred()) 53 }) 54 55 runInContainer := func(container garden.Container, script string) (garden.Process, *gbytes.Buffer) { 56 out := gbytes.NewBuffer() 57 process, err := container.Run(garden.ProcessSpec{ 58 User: "alice", 59 Path: "sh", 60 Args: []string{"-c", script}, 61 }, garden.ProcessIO{ 62 Stdout: io.MultiWriter(out, GinkgoWriter), 63 Stderr: GinkgoWriter, 64 }) 65 Expect(err).ToNot(HaveOccurred()) 66 67 return process, out 68 } 69 70 Context("external addresses", func() { 71 var ( 72 ByAllowingTCP, ByRejectingTCP func() 73 ) 74 75 BeforeEach(func() { 76 ByAllowingTCP = func() { 77 By("allowing outbound tcp traffic", func() { 78 Expect(checkInternet(container)).To(Succeed()) 79 }) 80 } 81 82 ByRejectingTCP = func() { 83 By("rejecting outbound tcp traffic", func() { 84 Expect(checkInternet(container)).To(HaveOccurred()) 85 }) 86 } 87 }) 88 89 Context("when the target address is inside DENY_NETWORKS", func() { 90 //The target address is the ip addr of www.example.com in these tests 91 BeforeEach(func() { 92 denyRange = "0.0.0.0/0" 93 allowRange = "9.9.9.9/30" 94 containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode()) 95 }) 96 97 It("disallows TCP connections", func() { 98 ByRejectingTCP() 99 }) 100 101 Context("when a rule that allows all traffic to the target is added", func() { 102 JustBeforeEach(func() { 103 err := container.NetOut(garden.NetOutRule{ 104 Networks: []garden.IPRange{ 105 garden.IPRangeFromIP(externalIP), 106 }, 107 }) 108 Expect(err).ToNot(HaveOccurred()) 109 }) 110 111 It("allows TCP traffic to the target", func() { 112 ByAllowingTCP() 113 }) 114 }) 115 }) 116 117 Context("when the target address is inside ALLOW_NETWORKS", func() { 118 BeforeEach(func() { 119 denyRange = "0.0.0.0/0" 120 allowRange = "0.0.0.0/0" 121 containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode()) 122 }) 123 124 It("allows connections", func() { 125 ByAllowingTCP() 126 }) 127 }) 128 129 Context("when the target address is in neither ALLOW_NETWORKS nor DENY_NETWORKS", func() { 130 BeforeEach(func() { 131 denyRange = "4.4.4.4/30" 132 allowRange = "4.4.4.4/30" 133 containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode()) 134 }) 135 136 It("allows connections", func() { 137 ByAllowingTCP() 138 }) 139 }) 140 141 Context("when there are two containers in the same subnet", func() { 142 BeforeEach(func() { 143 denyRange = "0.0.0.0/0" 144 containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode()) 145 }) 146 147 It("does not allow rules from the second container to affect the first", func() { 148 var err error 149 secondContainer, err := client.Create(garden.ContainerSpec{Network: containerNetwork, Privileged: true}) 150 Expect(err).ToNot(HaveOccurred()) 151 152 ByRejectingTCP() 153 154 Expect(secondContainer.NetOut(garden.NetOutRule{ 155 Networks: []garden.IPRange{ 156 garden.IPRangeFromIP(externalIP), 157 }, 158 })).To(Succeed()) 159 160 By("continuing to reject") 161 ByRejectingTCP() 162 }) 163 }) 164 }) 165 166 Describe("Other Containers", func() { 167 168 const tcpPort = 8080 169 170 targetIP := func(c garden.Container) string { 171 info, err := c.Info() 172 Expect(err).ToNot(HaveOccurred()) 173 return info.ContainerIP 174 } 175 176 ByAllowingTCP := func() { 177 By("allowing tcp traffic to it", func() { 178 Eventually(func() error { 179 return checkConnection(container, targetIP(otherContainer), tcpPort) 180 }).Should(Succeed()) 181 }) 182 } 183 184 Context("containers in the same subnet", func() { 185 JustBeforeEach(func() { 186 var err error 187 otherContainer, err = client.Create(garden.ContainerSpec{Network: containerNetwork}) 188 Expect(err).ToNot(HaveOccurred()) 189 190 runInContainer(otherContainer, fmt.Sprintf("echo hello | nc -l -p %d", tcpPort)) //tcp 191 }) 192 193 Context("even if the address is in deny networks", func() { 194 BeforeEach(func() { 195 denyRange = "0.0.0.0/8" 196 allowRange = "" 197 containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode()) 198 }) 199 200 It("can route to each other", func() { 201 ByAllowingTCP() 202 }) 203 }) 204 }) 205 206 Context("containers in distinct subnets", func() { 207 var otherContainerNetwork string 208 209 JustBeforeEach(func() { 210 otherContainerNetwork = fmt.Sprintf("10.1%d.1.0/24", GinkgoParallelNode()) 211 var err error 212 otherContainer, err = client.Create(garden.ContainerSpec{Network: otherContainerNetwork}) 213 Expect(err).ToNot(HaveOccurred()) 214 215 runInContainer(otherContainer, fmt.Sprintf("echo hello | nc -l -p %d", tcpPort)) //tcp 216 }) 217 218 Context("when deny networks is empty", func() { 219 It("can route to each other", func() { 220 ByAllowingTCP() 221 }) 222 }) 223 }) 224 }) 225 })