Beispiel #1
0
def check_permission(permission=None, direction=None):

    global authorized_ips

    observations = []
    for cidrip in permission.get('IpRanges'):
        ipv4 = IPNetwork(cidrip.get('CidrIp'))

        if ipv4.is_private():
            ipv4_public_status = "private"
        else:
            ipv4_public_status = "public"

        description = cidrip.get('Description')
        ipv4_present = False
        for ip in authorized_ips:
            if ipv4 in IPNetwork(ip):
                ipv4_present = True
                break
        if not ipv4_present:
            observations.append(
                "Unauthorised {} IPv4 : '{}' with description '{}' found in {} !!"
                .format(ipv4_public_status, ipv4, description, direction))
    for cidripv6 in permission.get('Ipv6Ranges'):
        ipv6 = IPNetwork(cidripv6.get('CidrIpv6'))

        if ipv6.is_private():
            ipv6_public_status = "private"
        else:
            ipv6_public_status = "public"

        description = cidripv6.get('Description')
        ipv6_present = False

        for ip in authorized_ips:
            if ipv6 in IPNetwork(ip):
                ipv6_present = True
                break

        if not ipv6_present:
            observations.append(
                "Unauthorised {} IPv6 : '{}' with description '{}' found in {} !!"
                .format(ipv6_public_status, ipv6, description, direction))
    unauthorised_port_finding = check_unauthorised_ports(permission=permission,
                                                         direction=direction)
    if unauthorised_port_finding:
        observations.append(unauthorised_port_finding)
    return observations
Beispiel #2
0
def providers_by_ips(ips):
    """
    Формирование словаря Компаний и количества IP-адресов.

    Учитываются локальные адреса:
    IPv4: 10.0.0.0/8
          172.16.0.0/12
          192.168.0.0/16
    IPv6: fc00::/7

    Валидация IP-адреса.

    ARGUMENTS:
        :param list ips:
        :return: dict
    """
    companies = defaultdict(int)
    for ip in set(ips):
        try:
            ip = IPNetwork(ip)
            local = ip.is_private()
            name_company = "Local IP" if local else get_provider(ip.ip)
        except AddrFormatError:
            name_company = "Invalid IP"
        companies[name_company] += 1
    return companies
Beispiel #3
0
def add(caller_id, address, mask):
    networks = []
    for net in AvailableNetwork.objects.all():
        networks.append(net.to_ipnetwork())
    networks.sort()

    # Find duplicate
    ipnet = IPNetwork('%s/%d' % (address, mask))
    for i in xrange(len(networks)):
        if ipnet.prefixlen > networks[i].prefixlen and ipnet > networks[
                i].previous() and ipnet < networks[i].next():
            raise CMException('network_exists')
        elif ipnet.prefixlen < networks[i].prefixlen and ipnet.previous(
        ) < networks[i] and ipnet.next() > networks[i]:
            raise CMException('network_exists')

    # Add new network
    new_net = AvailableNetwork()
    new_net.address = ipnet.network
    new_net.mask = mask

    if ipnet.is_private():
        new_net.state = available_network_states['ok']
    else:
        new_net.state = available_network_states['locked']

    new_net.save()
Beispiel #4
0
def hostname_resolves(hostname):
    resolved_ips = []

    logger.debug("Hostname to resolve: %s", str(hostname))

    try:
        ips = socket.getaddrinfo(hostname, None)
        for ip in ips:
            if ip[4][0] not in resolved_ips:
                net = IPNetwork(ip[4][0])
                if net.is_private() or net.is_link_local():
                    logger.warning("Tried to resolve local IP: %s, ignoring!", ip[4][0])
                    continue
                else:
                    resolved_ips.append(ip[4][0])

        if len(resolved_ips) > 0:
            logger.debug("Resolved IPs: %s", ', '.join(resolved_ips))
            return resolved_ips
        else:
            logger.warning("No IPs resolved from query: %s", hostname)
            abort(400)

    except socket.gaierror:
        logger.debug("Failed to resolve IP address from: %s", hostname)
        abort(400)
Beispiel #5
0
def add(caller_id, address, mask):
    networks = []
    for net in AvailableNetwork.objects.all():
        networks.append(net.to_ipnetwork())
    networks.sort()

    # Find duplicate
    ipnet = IPNetwork('%s/%d' % (address, mask))
    for i in xrange(len(networks)):
        if ipnet.prefixlen > networks[i].prefixlen and ipnet > networks[i].previous() and ipnet < networks[i].next():
            raise CMException('network_exists')
        elif ipnet.prefixlen < networks[i].prefixlen and ipnet.previous() < networks[i] and ipnet.next() > networks[i]:
            raise CMException('network_exists')

    # Add new network
    new_net = AvailableNetwork()
    new_net.address = ipnet.network
    new_net.mask = mask

    if ipnet.is_private():
        new_net.state = available_network_states['ok']
    else:
        new_net.state = available_network_states['locked']

    new_net.save()
Beispiel #6
0
def test_customer_bogon_routes(bf, customer_list):
    """Check that no BOGON routes are accepted from customers"""
    bf.asserts.current_assertion = 'Assert no BOGON prefixes accepted from customers'

    df = bf.q.routes(
        rib='bgp').answer().frame()  #retrieve BGP RIB for all devices
    bogons = []

    for customer in customer_list:
        for _, row in df.iterrows():
            if (row['Node'] == customer['Node']) & (
                    row['Next_Hop_IP'] == customer['Remote_IP']
            ):  #found routes learnt from customer
                z = IPNetwork(row['Network'])
                if (z.is_reserved() or z.is_private() or z.is_loopback()
                        or z.is_link_local() or z.is_multicast()):
                    bogons.append(
                        f"Prefix {row['Network']} from {customer['Remote_IP']} on {customer['Node']} should not be accepted"
                    )

    test = (len(bogons) == 0)
    pass_message = "No BOGON prefixes accepted from customers\n"
    fail_message = f"List of BOGON prefixes accepted from customers\n\n{bogons}"

    record_results(bf, test, pass_message, fail_message)
Beispiel #7
0
def _verify_network(name, network):
    """
    Verifies syntax of a specific network.

    :param str name: Name of network
    :param dict network: the network
    :return: Number of errors, Number of warnings
    :rtype: tuple(int, int)
    """
    num_warnings = 0
    num_errors = 0

    for key, value in network.items():
        # Subnet verification
        if "subnet" not in value:
            logging.warning("No subnet specified for %s %s", name, key)
            num_warnings += 1
        else:
            try:
                subnet = IPNetwork(value["subnet"])
            except AddrFormatError:
                logging.error("Invalid format for subnet '%s'",
                              str(value["subnet"]))
                num_errors += 1
            else:
                if subnet.is_reserved() \
                        or subnet.is_multicast() \
                        or subnet.is_loopback():
                    logging.error("%s %s is in a invalid IP address space",
                                  name, key)
                    num_errors += 1
                elif not subnet.is_private():
                    logging.warning("Non-private subnet used for %s %s", name,
                                    key)
                    num_warnings += 1

        # VLAN verification
        if "vlan" in value:
            if name == "unique-networks" and int(value["vlan"]) >= 2000:
                logging.error("VLAN must be less than 2000 for network %s",
                              key)
                num_errors += 1
            elif name == "generic-networks":
                logging.error(
                    "VLAN specification is not allowed "
                    "for network %s", key)
                num_errors += 1

        # Increment verification
        if "increment" in value:
            if name == "unique-networks":
                logging.error("Increment cannot be used for network %s", key)
                num_errors += 1
            elif not isinstance(value["increment"], bool):
                logging.error("Increment must be a boolean for network %s",
                              key)
                num_errors += 1
    return num_errors, num_warnings
def check_permission(permission=None):

    office_ips = []

    permissions = dict()
    permissions["ips"] = []
    for cidrip in permission.get('IpRanges'):
        p =dict()
        ipv4 = IPNetwork(cidrip.get('CidrIp'))
        p["ip"] = ipv4.__str__()
        if p["ip"] in office_ips:
            p["ip_status"] = "Office IP IPv4"
        elif ipv4.is_private():
            p["ip_status"] = "Private IPv4"
        else:
            p["ip_status"] = "Public IPv4"
        p["description"] = cidrip.get('Description')
        permissions["ips"].append(p)

    for cidripv6 in permission.get('Ipv6Ranges'):
        p = dict()
        ipv6 = IPNetwork(cidripv6.get('CidrIpv6'))
        p["ip"] = ipv6.__str__()
        if p["ip"] in office_ips:
            p["ip_status"] = "Office IP IPv6"
        elif ipv6.is_private():
            p["ip_status"] = "Private IPv6"
        else:
            p["ip_status"] = "Public IPv6"

        p["description"] = cidripv6.get('Description')
        permissions["ips"].append(p)

    if permissions["ips"]:
        permissions["ports"] = normalize_ports(permission=permission)
        if not permissions["ports"]: # In case of icmp
            return
    else:
        # If the permission has mapped security groups , it is of no interest to us
        return

    return permissions
Beispiel #9
0
def _normalize_cidr(raw_cidr):
    try:
        network = IPNetwork(raw_cidr)
        cidr = str(network)
    except AddrFormatError:
        raise exception.Conflict(reason="Invalid network address format")

    if not network.is_private():
        raise exception.Conflict(reason="Invalid network address. Must be RFC1918 compliant")

    return cidr
Beispiel #10
0
def get_nmap_port(query, netmask=32):
    """
    Scans host or whole subnet for hosts and their open ports. Uses NMAP's **-T4 -F** params to probe hosts.
    Probing is done from Hosting machine and therefore not suitable for scanning local network ranges.

    :param query: IP address or hostname
    :param netmask: (Optional) If you want to scan the whole range of hosts

    **Example:**

        $ GET ``/api/nmap/199.16.156.102/30``

        Returns::


            {
              "hosts": [
                {
                  "host": "199.16.156.102",
                  "status": {
                    "addresses": {
                      "ipv4": "199.16.156.102"
                    },
                    "hostnames": [],
                    "status": {
                      "reason": "syn-ack",
                      "state": "up"
                    },
                    "tcp": {
                      "80": {
                        "conf": "3",
                        "cpe": "",
                        "extrainfo": "",
                        "name": "http",
                        "product": "",
                        "reason": "syn-ack",
                        "state": "open",
                        "version": ""
                      },
                      "443": {
                        "conf": "3",
                        "cpe": "",
                        "extrainfo": "",
                        "name": "https",
                        "product": "",
                        "reason": "syn-ack",
                        "state": "open",
                        "version": ""
                      },
                      "8888": {
                        "conf": "3",
                        "cpe": "",
                        "extrainfo": "",
                        "name": "sun-answerbook",
                        "product": "",
                        "reason": "syn-ack",
                        "state": "open",
                        "version": ""
                      }
                    },
                    "vendor": {}
                  }
                },
                {
                  "host": "199.16.156.103",
                  "status": {
                    "addresses": {
                      "ipv4": "199.16.156.103"
                    },
                    "hostnames": [],
                    "status": {
                      "reason": "syn-ack",
                      "state": "up"
                    },
                    "tcp": {
                      "80": {
                        "conf": "3",
                        "cpe": "",
                        "extrainfo": "",
                        "name": "http",
                        "product": "",
                        "reason": "syn-ack",
                        "state": "open",
                        "version": ""
                      },
                      "443": {
                        "conf": "3",
                        "cpe": "",
                        "extrainfo": "",
                        "name": "https",
                        "product": "",
                        "reason": "syn-ack",
                        "state": "open",
                        "version": ""
                      },
                      "8888": {
                        "conf": "3",
                        "cpe": "",
                        "extrainfo": "",
                        "name": "sun-answerbook",
                        "product": "",
                        "reason": "syn-ack",
                        "state": "open",
                        "version": ""
                      }
                    },
                    "vendor": {}
                  }
                }
              ],
              "status": "ok"
            }
    """
    try:
        nm = nmap.PortScanner()
        hosts = dict()

        hosts['hosts'] = []
        if netmask == "":
            to_query = query
        else:
            to_query = query + "/" + str(netmask)

        logger.debug(to_query)

        try:
            net = IPNetwork(to_query)
        except AddrFormatError:
            abort(400)

        if net.is_link_local() or net.is_private():  # Won't scan server's local network
            abort(400)

        nm.scan(hosts=to_query, arguments='-T4 -F')
        hosts_list = [(x, nm[x]) for x in nm.all_hosts()]

        logger.debug(hosts_list)

        for host, status in hosts_list:
            hosts['hosts'].append({'host': host,
                                   'status': status})

        return jsonify({'status': "ok",
                        'hosts': hosts['hosts']})

    except nmap.PortScannerError:
        return error_response("NMAP error, cannot scan", 500)
Beispiel #11
0
def get_nmap_network(query, netmask=""):
    """
    Shows IP's that are pingable and those that are not. Accepts netmask to define the whole range for scan.
    Uses NMAP's **-sP** to probe hosts. Probing is done from Hosting machine and therefore not suitable for
    scanning local network ranges. Useful when checking how many IP's you have left in a particular netmask.

    :param query: IP address or hostname
    :param netmask: (Optional) If you want to scan the whole range of hosts

    **Example:**

        $ GET ``/api/host/199.16.156.102/29``

        ::


            {
              "down": [
                "199.16.156.100",
                "199.16.156.101",
                "199.16.156.96",
                "199.16.156.97",
                "199.16.156.98",
                "199.16.156.99"
              ],
              "hosts": [
                {
                  "host": "199.16.156.100",
                  "hostname": [],
                  "status": "down"
                },
                {
                  "host": "199.16.156.101",
                  "hostname": [],
                  "status": "down"
                },
                {
                  "host": "199.16.156.102",
                  "hostname": [],
                  "status": "up"
                },
                {
                  "host": "199.16.156.103",
                  "hostname": [],
                  "status": "up"
                },
                {
                  "host": "199.16.156.96",
                  "hostname": [],
                  "status": "down"
                },
                {
                  "host": "199.16.156.97",
                  "hostname": [],
                  "status": "down"
                },
                {
                  "host": "199.16.156.98",
                  "hostname": [],
                  "status": "down"
                },
                {
                  "host": "199.16.156.99",
                  "hostname": [],
                  "status": "down"
                }
              ],
              "status": "ok",
              "up": [
                "199.16.156.102",
                "199.16.156.103"
              ]
            }

    """
    try:
        nm = nmap.PortScanner()
        hosts = dict()

        hosts['hosts'] = []
        hosts['up'] = []
        hosts['down'] = []

        if netmask == "":
            to_query = query
        else:
            to_query = query + "/" + netmask

        logger.debug(to_query)

        try:
            net = IPNetwork(to_query)
        except AddrFormatError:
            abort(400)

        if net.is_link_local() or net.is_private():  # Won't scan server's local network
            abort(400)

        nm.scan(hosts=to_query, arguments='-sn -v')

        hosts_list = [(x, nm[x]) for x in nm.all_hosts()]

        logger.debug(hosts_list)

        for host, status in hosts_list:
            hosts['hosts'].append({'host': host,
                                   'status': status['status']['state'],
                                   'hostname': status['hostnames']})

            if status['status']['state'] == 'up':
                hosts['up'].append(host)

            if status['status']['state'] == 'down':
                hosts['down'].append(host)

        return jsonify({'status': "ok",
                        'hosts': hosts['hosts'],
                        'up': hosts['up'],
                        'down': hosts['down']})

    except nmap.PortScannerError:
        return error_response("Nmap error, can't scan", 500)
Beispiel #12
0
def get_ipcalc_network(query, netmask=""):
    """
    IP calculator tool: supports IPv6 and IPv4 networks. For list of values see below.

    IP list is optional since it will return many IPs for some subnets,
    if you need to show ip list you will have to append ``?iplist`` to your get request.

    **PLEASE NOTE:** iplist will print only 65536 addresses which is /16 in IPv4 subnetting or /112 in IPv6 subnetting.
    If you try to get more you will get an error.

    :param query: IP address or hostname
    :param netmask: (Optional) If you want the whole range of hosts

    **Example:**

        When getting single host

        $ GET ``/api/ipcalc/199.16.156.102/30``

        ::


            {
              "results": {
                "broadcast": "199.16.156.103",
                "cidr": "199.16.156.100/30",
                "first_host": "199.16.156.101",
                "hostmask": "0.0.0.3",
                "ip_bits": "11000111.00010000.10011100.01100110",
                "ip_version": 4,
                "is_linklocal": false,
                "is_loopback": false,
                "is_multicast": false,
                "is_private": false,
                "is_public": true,
                "is_reserved": false,
                "is_unicast": true,
                "last_host": "199.16.156.102",
                "netmask": "255.255.255.252",
                "netmask_bits": "11111111.11111111.11111111.11111100",
                "network": "199.16.156.100",
                "network_bits": "11000111.00010000.10011100.01100100",
                "num_addresses": 4,
                "prefixlen": 30,
                "supernet": [
                  "0.0.0.0/0",
                  "128.0.0.0/1",
                  "192.0.0.0/2",
                  "192.0.0.0/3",
                  "192.0.0.0/4",
                  "192.0.0.0/5",
                  "196.0.0.0/6",
                  "198.0.0.0/7",
                  "199.0.0.0/8",
                  "199.0.0.0/9",
                  "199.0.0.0/10",
                  "199.0.0.0/11",
                  "199.16.0.0/12",
                  "199.16.0.0/13",
                  "199.16.0.0/14",
                  "199.16.0.0/15",
                  "199.16.0.0/16",
                  "199.16.128.0/17",
                  "199.16.128.0/18",
                  "199.16.128.0/19",
                  "199.16.144.0/20",
                  "199.16.152.0/21",
                  "199.16.156.0/22",
                  "199.16.156.0/23",
                  "199.16.156.0/24",
                  "199.16.156.0/25",
                  "199.16.156.64/26",
                  "199.16.156.96/27",
                  "199.16.156.96/28",
                  "199.16.156.96/29"
                ],
                "to_ipv6": "::ffff:199.16.156.102/126"
              },
              "status": "ok"
            }

    """

    if netmask is not "":
        ip = query + '/' + netmask
    else:
        ip = query

    try:
        net = IPNetwork(ip)
    except AddrFormatError:
        abort(400)

    results = dict()
    results['broadcast'] = str(net.broadcast)
    results['network'] = str(net.network)
    results['netmask'] = str(net.netmask)
    results['cidr'] = str(net.cidr)
    results['num_addresses'] = net.size
    results['hostmask'] = str(net.hostmask)
    results['is_loopback'] = net.is_loopback()
    results['is_unicast'] = net.is_unicast()
    results['is_multicast'] = net.is_multicast()
    results['is_private'] = net.is_private()
    results['is_reserved'] = net.is_reserved()
    results['is_linklocal'] = net.is_link_local()
    results['is_public'] = net.is_unicast() and not net.is_private()
    results['prefixlen'] = net.prefixlen
    results['ip_version'] = net.version
    results['ip_bits'] = net.ip.bits()
    results['network_bits'] = net.network.bits()
    results['netmask_bits'] = net.netmask.bits()
    results['supernet'] = [str(supernet) for supernet in net.supernet()]

    if net.version == 4:
        results['to_ipv6'] = str(net.ipv6())

        if request.query_string == 'iplist':
            if net.size <= 65536:
                results['ip_list'] = [str(ip) for ip in list(net)]
            else:
                return error_response("Too many IPs to list (limit is 65536), "
                                      "use smaller subnet or remove '?iplist' from query.", 400)

        if net.broadcast is not None:
            results['first_host'] = str(net.network + 1)
            results['last_host'] = str(net.broadcast - 1)
        else:
            results['first_host'] = str(net.ip)
            results['last_host'] = str(net.ip)

    elif net.version == 6:
        try:
            results['to_ipv4'] = str(net.ipv4())
        except AddrConversionError:
            results['to_ipv4'] = None

        if request.query_string == 'iplist':
            if net.size <= 65536:
                results['ip_list'] = [str(ip) for ip in list(net)]
            else:
                return error_response("Too many IPs to list (limit is 65536), "
                                      "use smaller subnet or remove '?iplist' from query.", 400)

    return jsonify({'status': "ok",
                    'results': results})