func ReleasePortMaps(containerip string, maps []pod.UserContainerPort) error { if len(maps) == 0 { return nil } for _, m := range maps { var proto string glog.V(1).Infof("release port map %d", m.HostPort) portMapper.ReleaseMap(m.Protocol, m.HostPort) if strings.EqualFold(m.Protocol, "udp") { proto = "udp" } else { proto = "tcp" } natArgs := []string{"-p", proto, "-m", proto, "--dport", strconv.Itoa(m.HostPort), "-j", "DNAT", "--to-destination", net.JoinHostPort(containerip, strconv.Itoa(m.ContainerPort))} iptables.OperatePortMap(iptables.Delete, "HYPER", natArgs) filterArgs := []string{"-d", containerip, "-p", proto, "-m", proto, "--dport", strconv.Itoa(m.ContainerPort), "-j", "ACCEPT"} iptables.Raw(append([]string{"-D", "HYPER"}, filterArgs...)...) } /* forbid to map ports twice */ return nil }
func setupIPTables(addr net.Addr) error { // Enable NAT natArgs := []string{"-s", addr.String(), "!", "-o", BridgeIface, "-j", "MASQUERADE"} if !iptables.Exists(iptables.Nat, "POSTROUTING", natArgs...) { if output, err := iptables.Raw(append([]string{ "-t", string(iptables.Nat), "-I", "POSTROUTING"}, natArgs...)...); err != nil { return fmt.Errorf("Unable to enable network bridge NAT: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "POSTROUTING", Output: output} } } // Accept all non-intercontainer outgoing packets outgoingArgs := []string{"-i", BridgeIface, "!", "-o", BridgeIface, "-j", "ACCEPT"} if !iptables.Exists(iptables.Filter, "FORWARD", outgoingArgs...) { if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, outgoingArgs...)...); err != nil { return fmt.Errorf("Unable to allow outgoing packets: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "FORWARD outgoing", Output: output} } } // Accept incoming packets for existing connections existingArgs := []string{"-o", BridgeIface, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} if !iptables.Exists(iptables.Filter, "FORWARD", existingArgs...) { if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, existingArgs...)...); err != nil { return fmt.Errorf("Unable to allow incoming packets: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "FORWARD incoming", Output: output} } } return nil }
func SetupPortMaps(containerip string, maps []pod.UserContainerPort) error { if len(maps) == 0 { return nil } for _, m := range maps { var proto string if strings.EqualFold(m.Protocol, "udp") { proto = "udp" } else { proto = "tcp" } natArgs := []string{"-p", proto, "-m", proto, "--dport", strconv.Itoa(m.HostPort), "-j", "DNAT", "--to-destination", net.JoinHostPort(containerip, strconv.Itoa(m.ContainerPort))} if iptables.PortMapExists("HYPER", natArgs) { return nil } if iptables.PortMapUsed("HYPER", natArgs) { return fmt.Errorf("Host port %d has aleady been used", m.HostPort) } err := iptables.OperatePortMap(iptables.Insert, "HYPER", natArgs) if err != nil { return err } err = portMapper.AllocateMap(m.Protocol, m.HostPort, containerip, m.ContainerPort) if err != nil { return err } filterArgs := []string{"-d", containerip, "-p", proto, "-m", proto, "--dport", strconv.Itoa(m.ContainerPort), "-j", "ACCEPT"} if output, err := iptables.Raw(append([]string{"-I", "HYPER"}, filterArgs...)...); err != nil { return fmt.Errorf("Unable to setup forward rule in HYPER chain: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "HYPER", Output: output} } } /* forbid to map ports twice */ return nil }
func SetupPortMaps(containerip string, maps []pod.UserContainerPort) error { var ( err error = nil i int = 0 ) if len(maps) == 0 { return nil } err = nil for _, m := range maps { var proto string if strings.EqualFold(m.Protocol, "udp") { proto = "udp" } else { proto = "tcp" } err = portMapper.AllocateMap(m.Protocol, m.HostPort, containerip, m.ContainerPort) if err != nil { break } natArgs := []string{"-p", proto, "-m", proto, "--dport", strconv.Itoa(m.HostPort), "-j", "DNAT", "--to-destination", net.JoinHostPort(containerip, strconv.Itoa(m.ContainerPort))} if !iptables.PortMapExists("HYPER", natArgs) { if iptables.PortMapUsed("HYPER", natArgs) { err = fmt.Errorf("Host port %d has aleady been used", m.HostPort) portMapper.ReleaseMap(m.Protocol, m.HostPort) break } err = iptables.OperatePortMap(iptables.Insert, "HYPER", natArgs) if err != nil { portMapper.ReleaseMap(m.Protocol, m.HostPort) break } } filterArgs := []string{"-d", containerip, "-p", proto, "-m", proto, "--dport", strconv.Itoa(m.ContainerPort), "-j", "ACCEPT"} if output, err := iptables.Raw(append([]string{"-I", "HYPER"}, filterArgs...)...); err != nil { err = fmt.Errorf("Unable to setup forward rule in HYPER chain: %s", err) } else if len(output) != 0 { err = &iptables.ChainError{Chain: "HYPER", Output: output} } if err != nil { portMapper.ReleaseMap(m.Protocol, m.HostPort) iptables.OperatePortMap(iptables.Delete, "HYPER", natArgs) break } i++ } if err == nil { return nil } for _, m := range maps { var proto string i-- if i < 0 { break } if strings.EqualFold(m.Protocol, "udp") { proto = "udp" } else { proto = "tcp" } portMapper.ReleaseMap(m.Protocol, m.HostPort) natArgs := []string{"-p", proto, "-m", proto, "--dport", strconv.Itoa(m.HostPort), "-j", "DNAT", "--to-destination", net.JoinHostPort(containerip, strconv.Itoa(m.ContainerPort))} iptables.OperatePortMap(iptables.Delete, "HYPER", natArgs) filterArgs := []string{"-d", containerip, "-p", proto, "-m", proto, "--dport", strconv.Itoa(m.ContainerPort), "-j", "ACCEPT"} iptables.Raw(append([]string{"-D", "HYPER"}, filterArgs...)...) } return err }
func setupIPTables(addr net.Addr) error { // Enable NAT natArgs := []string{"-s", addr.String(), "!", "-o", BridgeIface, "-j", "MASQUERADE"} if !iptables.Exists(iptables.Nat, "POSTROUTING", natArgs...) { if output, err := iptables.Raw(append([]string{ "-t", string(iptables.Nat), "-I", "POSTROUTING"}, natArgs...)...); err != nil { return fmt.Errorf("Unable to enable network bridge NAT: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "POSTROUTING", Output: output} } } // Create HYPER iptables Chain iptables.Raw("-N", "HYPER") // Goto HYPER chain gotoArgs := []string{"-o", BridgeIface, "-j", "HYPER"} if !iptables.Exists(iptables.Filter, "FORWARD", gotoArgs...) { if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, gotoArgs...)...); err != nil { return fmt.Errorf("Unable to setup goto HYPER rule %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "FORWARD goto HYPER", Output: output} } } // Accept all outgoing packets outgoingArgs := []string{"-i", BridgeIface, "-j", "ACCEPT"} if !iptables.Exists(iptables.Filter, "FORWARD", outgoingArgs...) { if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, outgoingArgs...)...); err != nil { return fmt.Errorf("Unable to allow outgoing packets: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "FORWARD outgoing", Output: output} } } // Accept incoming packets for existing connections existingArgs := []string{"-o", BridgeIface, "-m", "conntrack", "--ctstate", "RELATED,ESTABLISHED", "-j", "ACCEPT"} if !iptables.Exists(iptables.Filter, "FORWARD", existingArgs...) { if output, err := iptables.Raw(append([]string{"-I", "FORWARD"}, existingArgs...)...); err != nil { return fmt.Errorf("Unable to allow incoming packets: %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "FORWARD incoming", Output: output} } } err := Modprobe("br_netfilter") if err != nil { glog.V(1).Infof("modprobe br_netfilter failed %s", err) } file, err := os.OpenFile("/proc/sys/net/bridge/bridge-nf-call-iptables", os.O_RDWR, 0) if err != nil { return err } _, err = file.WriteString("1") if err != nil { return err } // Create HYPER iptables Chain iptables.Raw("-t", string(iptables.Nat), "-N", "HYPER") // Goto HYPER chain gotoArgs = []string{"-m", "addrtype", "--dst-type", "LOCAL", "!", "-d", "127.0.0.1/8", "-j", "HYPER"} if !iptables.Exists(iptables.Nat, "OUTPUT", gotoArgs...) { if output, err := iptables.Raw(append([]string{"-t", string(iptables.Nat), "-I", "OUTPUT"}, gotoArgs...)...); err != nil { return fmt.Errorf("Unable to setup goto HYPER rule %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "OUTPUT goto HYPER", Output: output} } } gotoArgs = []string{"-m", "addrtype", "--dst-type", "LOCAL", "-j", "HYPER"} if !iptables.Exists(iptables.Nat, "PREROUTING", gotoArgs...) { if output, err := iptables.Raw(append([]string{"-t", string(iptables.Nat), "-I", "PREROUTING"}, gotoArgs...)...); err != nil { return fmt.Errorf("Unable to setup goto HYPER rule %s", err) } else if len(output) != 0 { return &iptables.ChainError{Chain: "PREROUTING goto HYPER", Output: output} } } return nil }