Example #1
0
def _create_profile_for_netgroup(profile_name):
    """
    Create a profile which allows traffic from other Endpoints in the same
    profile.
    """
    _log.info("Autocreating profile %s", profile_name)
    datastore.create_profile(profile_name)
    prof = datastore.get_profile(profile_name)
    allow_from_profile = Rule(action="allow", src_tag=profile_name)
    allow_to_all = Rule(action="allow")
    prof.rules = Rules(id=profile_name,
                       inbound_rules=[allow_from_profile],
                       outbound_rules=[allow_to_all])
    datastore.profile_update_rules(prof)
Example #2
0
def _create_profile_for_host_communication(profile_name):
    """
    Create a profile which allows traffic to and from the host.
    """
    _log.info("Autocreating profile %s", profile_name)
    datastore.create_profile(profile_name)
    prof = datastore.get_profile(profile_name)

    host_net = str(_get_host_ip_net())
    _log.info("adding accept rule for %s" % host_net)
    allow_from_slave = Rule(action="allow", src_net=host_net)
    allow_to_slave = Rule(action="allow", dst_net=host_net)
    prof.rules = Rules(id=profile_name,
                       inbound_rules=[allow_from_slave],
                       outbound_rules=[allow_to_slave])
    datastore.profile_update_rules(prof)
Example #3
0
def _create_profile_with_default_mesos_rules(profile):
    _log.info("Autocreating profile %s", profile)
    datastore.create_profile(profile)
    prof = datastore.get_profile(profile)
    # Set up the profile rules to allow incoming connections from the host
    # since the slave process will be running there.
    # Also allow connections from others in the profile.
    # Deny other connections (default, so not explicitly needed).
    # TODO: confirm that we're not getting more interfaces than we bargained for
    ipv4 = get_host_ips(4, exclude=["docker0"]).pop()
    host_net = str(_get_host_ip_net())
    _log.info("adding accept rule for %s" % host_net)
    allow_slave = Rule(action="allow", src_net=host_net)
    allow_self = Rule(action="allow", src_tag=profile)
    allow_all = Rule(action="allow")
    prof.rules = Rules(id=profile,
                       inbound_rules=[allow_slave, allow_self],
                       outbound_rules=[allow_all])
    datastore.profile_update_rules(prof)
Example #4
0
def _create_profile_for_public_communication(profile_name):
    """
    Create a public profile which allows open traffic from all.
    """
    _log.info("Creating public profile: %s", profile_name)
    datastore.create_profile(profile_name)
    prof = datastore.get_profile(profile_name)
    allow_all = Rule(action="allow")
    prof.rules = Rules(id=profile_name,
                       inbound_rules=[allow_all],
                       outbound_rules=[allow_all])
    datastore.profile_update_rules(prof)
Example #5
0
def profile_rule_add_remove(operation,
                            name,
                            position,
                            action,
                            direction,
                            protocol=None,
                            icmp_type=None,
                            icmp_code=None,
                            src_net=None,
                            src_tag=None,
                            src_ports=None,
                            dst_net=None,
                            dst_tag=None,
                            dst_ports=None):
    """
    Add or remove a rule from a profile.

    Arguments not documented below are passed through to the rule.

    :param operation: "add" or "remove".
    :param name: Name of the profile.
    :param position: Position to insert/remove rule or None for the default.
    :param action: Rule action: "allow" or "deny".
    :param direction: "inbound" or "outbound".

    :return:
    """
    if icmp_type is not None:
        icmp_type = int(icmp_type)
    if icmp_code is not None:
        icmp_code = int(icmp_code)

    # Convert the input into a Rule.
    rule_dict = {
        k: v
        for (k, v) in locals().iteritems()
        if k in Rule.ALLOWED_KEYS and v is not None
    }
    rule_dict["action"] = action
    if (protocol not in ("tcp", "udp")) and (src_ports is not None
                                             or dst_ports is not None):
        print "Ports are not valid with protocol %r" % protocol
        sys.exit(1)
    rule = Rule(**rule_dict)

    # Get the profile.
    try:
        nmp = NetworkMappedProfile(name)
    except KeyError:
        print "Profile %s not found." % name
        sys.exit(1)

    if direction == "inbound":
        rules = nmp.profile.rules.inbound_rules
    else:
        rules = nmp.profile.rules.outbound_rules

    if operation == "add":
        if position is None:
            # Default to append.
            position = len(rules) + 1
        if not 0 < position <= len(rules) + 1:
            print "Position %s is out-of-range." % position
        if rule in rules:
            print "Rule already present, skipping."
            return
        rules.insert(position - 1, rule)  # Accepts 0 and len(rules).
    else:
        # Remove.
        if position is not None:
            # Position can only be used on its own so no need to examine the
            # rule.
            if 0 < position <= len(rules):  # 1-indexed
                rules.pop(position - 1)
            else:
                print "Rule position out-of-range."
        else:
            # Attempt to match the rule.
            try:
                rules.remove(rule)
            except ValueError:
                print "Rule not found."
                sys.exit(1)
    nmp.update_rules()
Example #6
0
def isolate(cpid, cont_id, ip_str, profile_str):
    _log.info("Isolating executor with Container ID %s, PID %s.", cont_id,
              cpid)
    _log.info("IP: %s, Profile(s) %s", ip_str, profile_str)

    # Just auto assign ipv4 addresses for now.
    if ip_str.lower() == "auto":
        ip = assign_ipv4()
    else:
        try:
            ip = IPAddress(ip_str)
        except AddrFormatError:
            _log.warning("IP address %s could not be parsed" % ip_str)
            sys.exit(1)
        else:
            version = "v%s" % ip.version
            _log.debug('Attempting to assign IP%s address %s', version, ip)
            pools = datastore.get_ip_pools(version)
            pool = None
            for candidate_pool in pools:
                if ip in candidate_pool:
                    pool = candidate_pool
                    _log.debug('Using IP pool %s', pool)
                    break
            if not pool:
                _log.warning(
                    "Requested IP %s isn't in any configured "
                    "pool. Container %s", ip, cont_id)
                sys.exit(1)
            if not datastore.assign_address(pool, ip):
                _log.warning(
                    "IP address couldn't be assigned for "
                    "container %s, IP=%s", cont_id, ip)
    hostname = socket.gethostname()
    next_hop_ips = datastore.get_default_next_hops(hostname)

    endpoint = netns.set_up_endpoint(ip=ip,
                                     hostname=hostname,
                                     orchestrator_id=ORCHESTRATOR_ID,
                                     workload_id=cont_id,
                                     cpid=cpid,
                                     next_hop_ips=next_hop_ips,
                                     veth_name="eth0",
                                     proc_alias="/proc")

    if profile_str == "" or profile_str.lower() == "none":
        profiles = ["public"]
    else:
        parts = profile_str.split(",")
        profiles = filter(lambda x: len(x) > 0, map(lambda x: x.strip(),
                                                    parts))

    (ipv4, _) = datastore.get_host_ips(hostname)
    host_net = ipv4 + "/32"
    allow_slave = Rule(action="allow", src_net=host_net)
    for profile_id in profiles:
        if not datastore.profile_exists(profile_id):
            _log.info("Autocreating profile %s", profile_id)
            datastore.create_profile(profile_id)
            prof = datastore.get_profile(profile_id)

            # Set up the profile rules to allow incoming connections from the
            # host since the slave process will be running there.
            # Also allow connections from others in the profile.
            # Deny other connections (default, so not explicitly needed).
            allow_self = Rule(action="allow", src_tag=profile_id)
            allow_all = Rule(action="allow")
            if profile_id == "public":
                # 'public' profile is a special case, and we allow anything to
                # connect to it.
                prof.rules = Rules(id=profile_id,
                                   inbound_rules=[allow_all],
                                   outbound_rules=[allow_all])
            else:
                prof.rules = Rules(id=profile_id,
                                   inbound_rules=[allow_slave, allow_self],
                                   outbound_rules=[allow_all])
            datastore.profile_update_rules(prof)
        else:
            # Profile already exists.  Modify it to accept connections from
            # this slave if it doesn't already.
            prof = datastore.get_profile(profile_id)
            if allow_slave not in prof.rules.inbound_rules:
                _log.info("Adding %s rule to profile %s", allow_slave.pprint(),
                          profile_id)
                prof.rules.inbound_rules.append(allow_slave)
                datastore.profile_update_rules(prof)

    _log.info("Adding container %s to profile(s) %s", cont_id, profiles)
    endpoint.profile_ids = profiles
    _log.info("Finished adding container %s to profiles %s", cont_id, profiles)

    datastore.set_endpoint(endpoint)
    _log.info("Finished network for container %s, IP=%s", cont_id, ip)
Example #7
0
def isolate(cpid, cont_id, ip_str, profile_str):
    _log.info("Isolating executor with Container ID %s, PID %s.",
              cont_id, cpid)
    _log.info("IP: %s, Profile(s) %s", ip_str, profile_str)

    # Just auto assign ipv4 addresses for now.
    if ip_str.lower() == "auto":
        ip = assign_ipv4()
    else:
        try:
            ip = IPAddress(ip_str)
        except AddrFormatError:
            _log.warning("IP address %s could not be parsed" % ip_str)
            sys.exit(1)
        else:
            version = "v%s" % ip.version
            _log.debug('Attempting to assign IP%s address %s', version, ip)
            pools = datastore.get_ip_pools(version)
            pool = None
            for candidate_pool in pools:
                if ip in candidate_pool:
                    pool = candidate_pool
                    _log.debug('Using IP pool %s', pool)
                    break
            if not pool:
                _log.warning("Requested IP %s isn't in any configured "
                             "pool. Container %s", ip, cont_id)
                sys.exit(1)
            if not datastore.assign_address(pool, ip):
                _log.warning("IP address couldn't be assigned for "
                             "container %s, IP=%s", cont_id, ip)
    hostname = socket.gethostname()
    next_hop_ips = datastore.get_default_next_hops(hostname)

    endpoint = netns.set_up_endpoint(ip=ip,
                                     hostname=hostname,
                                     orchestrator_id=ORCHESTRATOR_ID,
                                     workload_id=cont_id,
                                     cpid=cpid,
                                     next_hop_ips=next_hop_ips,
                                     veth_name="eth0",
                                     proc_alias="/proc")

    if profile_str == "":
        profiles = ["public"]
    else:
        parts = profile_str.split(",")
        profiles = filter(lambda x: len(x) > 0,
                          map(lambda x: x.strip(), parts))

    (ipv4, _) = datastore.get_host_ips(hostname)
    host_net = ipv4 + "/32"
    allow_slave = Rule(action="allow", src_net=host_net)
    for profile_id in profiles:
        if not datastore.profile_exists(profile_id):
            _log.info("Autocreating profile %s", profile_id)
            datastore.create_profile(profile_id)
            prof = datastore.get_profile(profile_id)

            # Set up the profile rules to allow incoming connections from the
            # host since the slave process will be running there.
            # Also allow connections from others in the profile.
            # Deny other connections (default, so not explicitly needed).
            allow_self = Rule(action="allow", src_tag=profile_id)
            allow_all = Rule(action="allow")
            if profile_id == "public":
                # 'public' profile is a special case, and we allow anything to
                # connect to it.
                prof.rules = Rules(id=profile_id,
                                   inbound_rules=[allow_all],
                                   outbound_rules=[allow_all])
            else:
                prof.rules = Rules(id=profile_id,
                                   inbound_rules=[allow_slave, allow_self],
                                   outbound_rules=[allow_all])
            datastore.profile_update_rules(prof)
        else:
            # Profile already exists.  Modify it to accept connections from
            # this slave if it doesn't already.
            prof = datastore.get_profile(profile_id)
            if allow_slave not in prof.rules.inbound_rules:
                _log.info("Adding %s rule to profile %s",
                          allow_slave.pprint(), profile_id)
                prof.rules.inbound_rules.append(allow_slave)
                datastore.profile_update_rules(prof)

    _log.info("Adding container %s to profile(s) %s", cont_id, profiles)
    endpoint.profile_ids = profiles
    _log.info("Finished adding container %s to profiles %s",
              cont_id, profiles)

    datastore.set_endpoint(endpoint)
    _log.info("Finished network for container %s, IP=%s", cont_id, ip)