github.com/schwarzm/garden-linux@v0.0.0-20150507151835-33bca2147c47/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  			Path: "sh",
    59  			Args: []string{"-c", script},
    60  		}, garden.ProcessIO{
    61  			Stdout: io.MultiWriter(out, GinkgoWriter),
    62  			Stderr: GinkgoWriter,
    63  		})
    64  		Expect(err).ToNot(HaveOccurred())
    65  
    66  		return process, out
    67  	}
    68  
    69  	Context("external addresses", func() {
    70  		var (
    71  			ByAllowingTCP, ByRejectingTCP func()
    72  		)
    73  
    74  		BeforeEach(func() {
    75  			ByAllowingTCP = func() {
    76  				By("allowing outbound tcp traffic", func() {
    77  					Expect(checkInternet(container)).To(Succeed())
    78  				})
    79  			}
    80  
    81  			ByRejectingTCP = func() {
    82  				By("rejecting outbound tcp traffic", func() {
    83  					Expect(checkInternet(container)).To(HaveOccurred())
    84  				})
    85  			}
    86  		})
    87  
    88  		Context("when the target address is inside DENY_NETWORKS", func() {
    89  			//The target address is the ip addr of www.example.com in these tests
    90  			BeforeEach(func() {
    91  				denyRange = "0.0.0.0/0"
    92  				allowRange = "9.9.9.9/30"
    93  				containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode())
    94  			})
    95  
    96  			It("disallows TCP connections", func() {
    97  				ByRejectingTCP()
    98  			})
    99  
   100  			Context("when a rule that allows all traffic to the target is added", func() {
   101  				JustBeforeEach(func() {
   102  					err := container.NetOut(garden.NetOutRule{
   103  						Networks: []garden.IPRange{
   104  							garden.IPRangeFromIP(externalIP),
   105  						},
   106  					})
   107  					Expect(err).ToNot(HaveOccurred())
   108  				})
   109  
   110  				It("allows TCP traffic to the target", func() {
   111  					ByAllowingTCP()
   112  				})
   113  			})
   114  		})
   115  
   116  		Context("when the target address is inside ALLOW_NETWORKS", func() {
   117  			BeforeEach(func() {
   118  				denyRange = "0.0.0.0/0"
   119  				allowRange = "0.0.0.0/0"
   120  				containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode())
   121  			})
   122  
   123  			It("allows connections", func() {
   124  				ByAllowingTCP()
   125  			})
   126  		})
   127  
   128  		Context("when the target address is in neither ALLOW_NETWORKS nor DENY_NETWORKS", func() {
   129  			BeforeEach(func() {
   130  				denyRange = "4.4.4.4/30"
   131  				allowRange = "4.4.4.4/30"
   132  				containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode())
   133  			})
   134  
   135  			It("allows connections", func() {
   136  				ByAllowingTCP()
   137  			})
   138  		})
   139  
   140  		Context("when there are two containers in the same subnet", func() {
   141  			BeforeEach(func() {
   142  				denyRange = "0.0.0.0/0"
   143  				containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode())
   144  			})
   145  
   146  			It("does not allow rules from the second container to affect the first", func() {
   147  				var err error
   148  				secondContainer, err := client.Create(garden.ContainerSpec{Network: containerNetwork, Privileged: true})
   149  				Expect(err).ToNot(HaveOccurred())
   150  
   151  				ByRejectingTCP()
   152  
   153  				Expect(secondContainer.NetOut(garden.NetOutRule{
   154  					Networks: []garden.IPRange{
   155  						garden.IPRangeFromIP(externalIP),
   156  					},
   157  				})).To(Succeed())
   158  
   159  				By("continuing to reject")
   160  				ByRejectingTCP()
   161  			})
   162  		})
   163  	})
   164  
   165  	Describe("Other Containers", func() {
   166  
   167  		const tcpPort = 8080
   168  
   169  		targetIP := func(c garden.Container) string {
   170  			info, err := c.Info()
   171  			Expect(err).ToNot(HaveOccurred())
   172  			return info.ContainerIP
   173  		}
   174  
   175  		ByAllowingTCP := func() {
   176  			By("allowing tcp traffic to it", func() {
   177  				Expect(checkConnection(container, targetIP(otherContainer), tcpPort)).To(Succeed())
   178  			})
   179  		}
   180  
   181  		Context("containers in the same subnet", func() {
   182  			JustBeforeEach(func() {
   183  				var err error
   184  				otherContainer, err = client.Create(garden.ContainerSpec{Network: containerNetwork})
   185  				Expect(err).ToNot(HaveOccurred())
   186  
   187  				runInContainer(otherContainer, fmt.Sprintf("echo hello | nc -l -p %d", tcpPort)) //tcp
   188  			})
   189  
   190  			Context("even if the address is in deny networks", func() {
   191  				BeforeEach(func() {
   192  					denyRange = "0.0.0.0/8"
   193  					allowRange = ""
   194  					containerNetwork = fmt.Sprintf("10.1%d.0.0/24", GinkgoParallelNode())
   195  				})
   196  
   197  				It("can route to each other", func() {
   198  					ByAllowingTCP()
   199  				})
   200  			})
   201  		})
   202  
   203  		Context("containers in distinct subnets", func() {
   204  			var otherContainerNetwork string
   205  
   206  			JustBeforeEach(func() {
   207  				otherContainerNetwork = fmt.Sprintf("10.1%d.1.0/24", GinkgoParallelNode())
   208  				var err error
   209  				otherContainer, err = client.Create(garden.ContainerSpec{Network: otherContainerNetwork})
   210  				Expect(err).ToNot(HaveOccurred())
   211  
   212  				runInContainer(otherContainer, fmt.Sprintf("echo hello | nc -l -p %d", tcpPort)) //tcp
   213  			})
   214  
   215  			Context("when deny networks is empty", func() {
   216  				It("can route to each other", func() {
   217  					ByAllowingTCP()
   218  				})
   219  			})
   220  		})
   221  	})
   222  })