예제 #1
0
파일: network.go 프로젝트: huangqg/hyper
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
}
예제 #2
0
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
}
예제 #3
0
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
}
예제 #4
0
파일: network.go 프로젝트: huangqg/hyper
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
}
예제 #5
0
파일: network.go 프로젝트: huangqg/hyper
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
}