func (e *podEnv) unforwardPorts() error { ipt, err := iptables.New() if err != nil { return err } chain := e.portFwdChain() rule := e.portFwdRuleSpec(chain) // There's no clean way now to test if a chain exists or // even if a rule exists if the chain is not present. // So we swallow the errors for now :( // TODO(eyakubovich): move to using libiptc for iptable // manipulation // outside traffic hitting this hot ipt.Delete("nat", "PREROUTING", rule...) // traffic originating on this host ipt.Delete("nat", "OUTPUT", rule...) // there should be no references, delete the chain ipt.ClearChain("nat", chain) ipt.DeleteChain("nat", chain) return nil }
// TeardownIPMasq undoes the effects of SetupIPMasq func TeardownIPMasq(ipn *net.IPNet, chain string) error { ipt, err := iptables.New() if err != nil { return fmt.Errorf("failed to locate iptabes: %v", err) } if err = ipt.Delete("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain); err != nil { return err } if err = ipt.ClearChain("nat", chain); err != nil { return err } return ipt.DeleteChain("nat", chain) }
func (e *podEnv) forwardPorts(fps []ForwardedPort, defIP net.IP) error { if len(fps) == 0 { return nil } ipt, err := iptables.New() if err != nil { return err } // Create a separate chain for this pod. This helps with debugging // and makes it easier to cleanup chain := e.portFwdChain() if err = ipt.NewChain("nat", chain); err != nil { return err } rule := e.portFwdRuleSpec(chain) for _, entry := range [][]string{ {"nat", "PREROUTING"}, // outside traffic hitting this host {"nat", "OUTPUT"}, // traffic originating on this host } { exists, err := ipt.Exists(entry[0], entry[1], rule...) if err != nil { return err } if !exists { err = ipt.Insert(entry[0], entry[1], 1, rule...) if err != nil { return err } } } for _, p := range fps { if err = forwardPort(ipt, chain, &p, defIP); err != nil { return err } } return nil }
// SetupIPMasq installs iptables rules to masquerade traffic // coming from ipn and going outside of it func SetupIPMasq(ipn *net.IPNet, chain string) error { ipt, err := iptables.New() if err != nil { return fmt.Errorf("failed to locate iptabes: %v", err) } if err = ipt.NewChain("nat", chain); err != nil { if err.(*iptables.Error).ExitStatus() != 1 { // TODO(eyakubovich): assumes exit status 1 implies chain exists return err } } if err = ipt.AppendUnique("nat", chain, "-d", ipn.String(), "-j", "ACCEPT"); err != nil { return err } if err = ipt.AppendUnique("nat", chain, "!", "-d", "224.0.0.0/4", "-j", "MASQUERADE"); err != nil { return err } return ipt.AppendUnique("nat", "POSTROUTING", "-s", ipn.String(), "-j", chain) }