github.com/cloudfoundry-attic/garden-linux@v0.333.2-candidate/linux_container/iptables_manager/filter.go (about) 1 package iptables_manager 2 3 import ( 4 "net" 5 6 "os/exec" 7 8 "fmt" 9 10 "bytes" 11 "io/ioutil" 12 13 "github.com/cloudfoundry-incubator/garden-linux/sysconfig" 14 "github.com/cloudfoundry/gunk/command_runner" 15 "github.com/pivotal-golang/lager" 16 ) 17 18 type filterChain struct { 19 cfg *sysconfig.IPTablesFilterConfig 20 runner command_runner.CommandRunner 21 logger lager.Logger 22 } 23 24 func NewFilterChain(cfg *sysconfig.IPTablesFilterConfig, runner command_runner.CommandRunner, logger lager.Logger) *filterChain { 25 return &filterChain{ 26 cfg: cfg, 27 runner: runner, 28 logger: logger, 29 } 30 } 31 32 func (mgr *filterChain) Setup(containerID, bridgeName string, ip net.IP, network *net.IPNet) error { 33 instanceChain := mgr.cfg.InstancePrefix + containerID 34 35 commands := []*exec.Cmd{ 36 // Create filter instance chain 37 exec.Command("iptables", "--wait", "-N", instanceChain), 38 // Allow intra-subnet traffic (Linux ethernet bridging goes through ip stack) 39 exec.Command("iptables", "--wait", "-A", instanceChain, "-s", network.String(), "-d", network.String(), "-j", "ACCEPT"), 40 // Otherwise, use the default filter chain 41 exec.Command("iptables", "--wait", "-A", instanceChain, "--goto", mgr.cfg.DefaultChain), 42 // Bind filter instance chain to filter forward chain 43 exec.Command("iptables", "--wait", "-I", mgr.cfg.ForwardChain, "2", "--in-interface", bridgeName, "--source", ip.String(), "--goto", instanceChain), 44 } 45 46 for _, cmd := range commands { 47 buffer := &bytes.Buffer{} 48 cmd.Stderr = buffer 49 logger := mgr.logger.Session("setup", lager.Data{"cmd": cmd}) 50 logger.Debug("starting") 51 if err := mgr.runner.Run(cmd); err != nil { 52 stderr, _ := ioutil.ReadAll(buffer) 53 logger.Error("failed", err, lager.Data{"stderr": string(stderr)}) 54 return fmt.Errorf("iptables_manager: filter: %s", err) 55 } 56 logger.Debug("ended") 57 } 58 59 return nil 60 } 61 62 func (mgr *filterChain) Teardown(containerID string) error { 63 instanceChain := mgr.cfg.InstancePrefix + containerID 64 65 commands := []*exec.Cmd{ 66 // Prune forward chain 67 exec.Command("sh", "-c", fmt.Sprintf( 68 `iptables --wait -S %s 2> /dev/null | grep "\-g %s\b" | sed -e "s/-A/-D/" | xargs --no-run-if-empty --max-lines=1 iptables --wait`, 69 mgr.cfg.ForwardChain, instanceChain, 70 )), 71 // Flush instance chain 72 exec.Command("sh", "-c", fmt.Sprintf("iptables --wait -F %s 2> /dev/null || true", instanceChain)), 73 // Delete instance chain 74 exec.Command("sh", "-c", fmt.Sprintf("iptables --wait -X %s 2> /dev/null || true", instanceChain)), 75 } 76 77 for _, cmd := range commands { 78 buffer := &bytes.Buffer{} 79 cmd.Stderr = buffer 80 logger := mgr.logger.Session("teardown", lager.Data{"cmd": cmd}) 81 logger.Debug("starting") 82 if err := mgr.runner.Run(cmd); err != nil { 83 stderr, _ := ioutil.ReadAll(buffer) 84 logger.Error("failed", err, lager.Data{"stderr": string(stderr)}) 85 return fmt.Errorf("iptables_manager: filter: %s", err) 86 } 87 logger.Debug("ended") 88 } 89 90 return nil 91 }