Пример #1
0
    def generateConf(node):
        confstr_list =  ["""\
! auto-generated by pmacctd NetFlow9 service (monitoring.py)

!pidfile: /var/run/pmacctd_nf9.pid

daemonize: true

"""]
        for intf in node.netifs():
            confstr_list.extend(['interface: ', intf.name, '\n'])

        confstr_list.append(
"""
!aggregate: src_host, dst_host, src_port, dst_port, proto, tos
plugins: nfprobe

""")

        # add any nfprobe9sink which is on our AS to the list of collectors
        service_helpers.nodewalker(node, node, confstr_list,
                NetFlow9ProbeServicePMAcct.nodewalker_callback)

        confstr_list.append(
"""
nfprobe_version: 9

nfprobe_timeouts: tcp=120:tcp.rst=4:tcp.fin=10:udp=10:icmp=10:general=120:expint=3:maxlife=3600
""")

        return ''.join(confstr_list)
Пример #2
0
 def generateHostsIf(node, verbose=False):
     confstr_list =  []
     if not verbose:
         service_helpers.nodewalker(node, node, confstr_list,
                 ICMPProbeService.nodewalker_if_callback)
     else:
         service_helpers.nodewalker(node, node, confstr_list,
                 ICMPProbeService.nodewalker_if_verbose_callback)
     return ''.join(confstr_list)
Пример #3
0
    def generateDBAuthoritativeFile(cls, node, zone, nameservers_cb,
            delegation_servers_cb=None, hosts_cb=None):
        servers, zone_servers = cls.getServers(cls, node, zone, nameservers_cb)
        tmpservers = []
        for server, addr, server_zone in servers:
            if server_zone == '.':
                tmpservers.append(('%s.' % server, addr, server_zone))
            else:
                tmpservers.append(('%s.%s' % (server, server_zone), addr, server_zone))
        servers = tmpservers
        if zone == '.':
            zone_servers = [('%s.' % server, addr) for server, addr in zone_servers]
        else:
            zone_servers = [('%s.%s' % (server, zone), addr) for server, addr in zone_servers]
        #print(('[==DEBUG==] servers: %s' % servers))
        #print(('[==DEBUG==] zone_servers: %s' % zone_servers))

        rawzonecontents = cls.compileZoneFile(cls, list([(x[0], x[1], zone) for x in zone_servers]))[0]
        #print(('[DEBUG] generateDBAuthoritativeFile(node="%s", zone="%s"): zone_servers: %s' %
        #        (node, zone, zone_servers)))
        SOAHeader = cls.generateSOAHeader(cls, zone_servers, zone)
        #print(('[DEBUG] SOAHeader: %s' % SOAHeader))
        zonecontents = '%s\n%s' % (SOAHeader, rawzonecontents)
        #print(('[DEBUG] zonecontents: %s' % zonecontents))

        if not delegation_servers_cb is None:
            delegation_servers = []
            service_helpers.nodewalker(node, node, delegation_servers,
                    delegation_servers_cb)
            delegation_servers_map = {}
            for server, addr, server_zone in delegation_servers:
                if server_zone == '.':
                    servername = ('%s.' % server)
                else:
                    servername = ('%s.%s' % (server, server_zone))
                if not server_zone in delegation_servers_map:
                    delegation_servers_map[server_zone] = []
                delegation_servers_map[server_zone].append((servername, addr))
            delegation_records = []
            for server_zone, servers in delegation_servers_map.items():
                delegation_records.append(cls.generateDelegationRecord(cls, servers, server_zone))

            zonecontents = '%s\n%s' % (zonecontents, '\n\n'.join(delegation_records))

        if not hosts_cb is None:
            hosts = []
            service_helpers.nodewalker(node, node, hosts,
                     hosts_cb)
            # remove nameservers as they have already been added
            # TODO: remove nameservers as they have already been added -- hosts = [(server_name, v6addr, zone) for server_name, v6addr, zone ]
            host_records = cls.compileZoneFile(cls, None, hosts)[1]
            #print(('[DDEBUGG] host_records: %s' % str(host_records)))
            zonecontents = '%s\n%s' % (zonecontents, host_records)

        if len(servers) > 0:
            cls.writeZoneFile(cls, node, zone, zonecontents)
Пример #4
0
    def getServers(cls, node, zone, nodewalker_cb):
        # add any authoritative dns server to the list of resolvers for that AS,
        # if we are not an authoritative dns server for the same AS
        servers = []
        service_helpers.nodewalker(node, node, servers, nodewalker_cb)

        # servers managing virtual zone
        zone_servers = []
        for servername, ipaddr, server_zone in servers:
            #print(('[DEBUG] candidate: server: %s, zone: %s' % (servername, server_zone)))
            if server_zone == zone:
                #print(('[DEBUG] adding to zone: "%s" server: "%s" (%s)' %
                #        (server_zone, servername, ipaddr)))
                zone_servers.append((servername, ipaddr))
        return servers, zone_servers
Пример #5
0
    def generateResolvconf(cls, node, services):
        confstr_list = []

        if service_flags.DNSResolver in node.services:
            # if we are a DNS server, add ::1, 127.0.0.1 to resolv.conf
            if node.enable_ipv6:
                confstr_list.append('nameserver ::1\n')
            if node.enable_ipv4:
                confstr_list.append('nameserver 127.0.0.1\n')
        else:
            print('[DNSResolvconf] generating for node: %s' % node.name)
            # add any dns server which is on our AS to the list of resolvers
            list_len = len(confstr_list)
            service_helpers.nodewalker(node, node, confstr_list,
                    cls.nodewalker_Resolver_only_callback)

            print('[DNSResolvconf] found %d resolvers' % len(confstr_list))

            # if no resolvers could be found, also include authoritative AS dns
            if list_len == len(confstr_list):
                list_len = len(confstr_list)
                service_helpers.nodewalker(node, node, confstr_list,
                        cls.nodewalker_Resolver_and_ASAuth_only_callback)
                print('[DNSResolvconf] found %d resolvers and AS auth servers' % len(confstr_list))
                # if no resolvers could be found, also include authoritative AS and root dns
                if list_len == len(confstr_list):
                    service_helpers.nodewalker(node, node, confstr_list,
                            cls.nodewalker_all_DNS_Resolver_callback)
                    print('[DNSResolvconf] found %d resolvers, AS auth and root servers' % len(confstr_list))
        confstr_list.append('search virtual\ndomain virtual\n')

        return ''.join(confstr_list)
Пример #6
0
    def getAndGeneratePTRZonesASAuthServer(cls, node):
        """ returns a list of all reverse zones a root dns server serves """
        # find dns as authoritative servers
        # (server_name, server_addr, zone)
        as_auth_servers = []
        service_helpers.nodewalker(node, node, as_auth_servers,
                cls.nodewalker_root_dns_find_all_auth_servers_callback)
        as_auth_servers = [('%s.%s' % (server_name, zone), server_addr, zone) \
                for server_name, server_addr, zone in as_auth_servers]
        # zone = "AS%s.virtual." % str(netid)

        zonenames = []

        if hasattr(node, 'netid') and not node.netid is None:
            netid = node.netid
        else:
            # TODO: netid 0 is invalid
            netid = 0
        asn = netid

        for ipversion in node.getIPversions():
            # collect loopback address space
            loopback_net = Loopback.getLoopbackNet_per_net(\
                    node.session.sessionid, netid, ipversion)
            print(('[DEBUG] loopback_net IPv%d: %s' % (ipversion, loopback_net)))

            # collect interface address space
            interface_net = Interface.getInterfaceNet_per_net(\
                    node.session.sessionid, netid, ipversion)
            print(('[DEBUG] interface_net IPv%d: %s' % (ipversion, interface_net)))

            if ipversion == 4:
                auth_servers = [(server_name, server_addr) \
                        for server_name, server_addr, zone in as_auth_servers \
                        if zone == "AS%s.virtual." % str(netid) and \
                        isIPv4Address(server_addr)]
            elif ipversion == 6:
                auth_servers = [(server_name, server_addr) \
                        for server_name, server_addr, zone in as_auth_servers \
                        if zone == "AS%s.virtual." % str(netid) and \
                        isIPv6Address(server_addr)]
            else:
                raise ValueError

            for asn_net in loopback_net, interface_net:
                zonename = cls.getPTRZoneNameFromPrefix(cls, asn_net)
                print(('[DEBUG] zonename: %s' % zonename))

                ORIGINHeader = '$ORIGIN %s\n' % zonename
                print(('[DEBUG] ORIGINHeader: %s' % ORIGINHeader))

                SOAHeader = cls.generateSOAHeader(cls, auth_servers, zonename)
                print(('[DEBUG] SOAHeader:\n%s' % SOAHeader))

                zoneentries = []

                # get host list of this AS
                # TODO: iterating over all nodes for interface and
                # loopback address space is expensive. and we are only talking
                # about IPv4 or IPv6 at the moment.
                # is there a better way of doing this?
                hosts = []
                service_helpers.nodewalker(node, node, hosts,
                        cls.nodewalker_asroot_dns_find_hosts_in_as_callback)
                for hostname, asn_addr, zone in hosts:
                    if ipversion == 4 and not isIPv4Address(asn_addr):
                        continue
                    if ipversion == 6 and not isIPv6Address(asn_addr):
                        continue

                    if ipversion == 4:
                        asn_addr = IPv4Addr(asn_addr)
                    elif ipversion == 6:
                        asn_addr = IPv6Addr(asn_addr)
                    else:
                        raise ValueError

                    if asn_addr < asn_net.minaddr() or \
                            asn_addr > asn_net.maxaddr():
                        continue

                    # set prefix length. just to be sure
                    asn_addr.set_prefixlen(asn_net.prefixlen)
                    asn_ptr_name = cls.getPTR_CNAME_FromAddr(cls, asn_addr)

                    print(('[DEBUG] ASN PTR addr (IPv%d): %s' %
                            (ipversion, str(asn_addr))))

                    print(('[DEBUG] adding: "%s IN PTR %s.AS%s.virtual.' %
                            (asn_ptr_name, hostname, str(netid))))
                    zoneentries.append(('%s IN PTR %s.AS%s.virtual.' %
                            (asn_ptr_name, hostname, str(netid))))

                print(('[DEBUG] PTR records: %s' % (zoneentries)))

                zonecontents = '%s\n%s\n%s\n' % (ORIGINHeader, SOAHeader,
                        '\n'.join(zoneentries))
                cls.writeZoneFile(cls, node, zonename, zonecontents)
                print(('[DEBUG] adding ptrzone: %s' % zonename))
                zonenames.append(zonename)

        return zonenames
Пример #7
0
    def getAndGeneratePTRZonesRootServer(cls, node):
        """ returns a list of all reverse zones a root dns server serves """

        # find dns root servers
        # (server_name, server_addr)
        rootservers = []
        service_helpers.nodewalker(node, node, rootservers,
                cls.nodewalker_find_root_dns_callback)
        rootservers = [('%s.' % server_name, server_addr) \
                for server_name, server_addr in rootservers]
        # find dns as authoritative servers
        # (server_name, server_addr, zone)
        as_auth_servers = []
        service_helpers.nodewalker(node, node, as_auth_servers,
                cls.nodewalker_root_dns_find_all_auth_servers_callback)
        as_auth_servers = [('%s.%s' % (server_name, zone), server_addr, zone) \
                for server_name, server_addr, zone in as_auth_servers]

        zonenames = []

        SOAHeader = cls.generateSOAHeader(cls, rootservers, '.')
        print(('[DEBUG] SOAHeader:\n%s' % SOAHeader))

        for ipversion in node.getIPversions():
            # collect loopback address space
            loopback_net = Loopback.getLoopbackNet(ipversion)
            print(('[DEBUG] loopback_net IPv%d: %s' % (ipversion, loopback_net)))

            # collect interface address space
            interface_net = Interface.getInterfaceNet(ipversion)
            print(('[DEBUG] interface_net IPv%d: %s' % (ipversion, interface_net)))

            # get all deployed ASN's
            asns = list(NetIDNodeMap.mapping[node.session.sessionid].keys())
            print(('[DEBUG] deployed ASN\'s: %s' % asns))
            for net in loopback_net, interface_net:
                zonename = cls.getPTRZoneNameFromPrefix(cls, net)
                net_prefixlen = net.prefixlen
                print(('[DEBUG] zonename: %s' % zonename))

                ORIGINHeader = '$ORIGIN %s\n' % zonename
                print(('[DEBUG] ORIGINHeader: %s' % ORIGINHeader))

                zoneentries = []
                for asn in asns:
                    # get AS address space
                    if net == loopback_net:
                        asn_net = Loopback.getLoopbackNet_per_net(\
                                node.session.sessionid, asn, ipversion)
                    elif net == interface_net:
                        asn_net = Interface.getInterfaceNet_per_net(\
                                node.session.sessionid, asn, ipversion)

                    # find authoritative AS dns servers
                    # zone == "AS%s.virtual." % str(netid)
                    for server_name, server_addr, zone in as_auth_servers:
                        server_asn = zone.lstrip('AS')
                        server_asn = int(server_asn[:server_asn.find('.')])

                        # not the correct asn
                        if not asn == server_asn:
                            continue

                        # not our IP version
                        if ipversion == 4 and not isIPv4Address(server_addr):
                            continue
                        if ipversion == 6 and not isIPv6Address(server_addr):
                            continue

                        print(('[DEBUG] server_name: %s, server_addr: %s, zone: %s' %
                                (server_name, server_addr, zone)))

                        if ipversion == 4:
                            # get host list of this AS
                            # TODO: iterating over all nodes for each AS for interface and
                            # loopback address space is expensive. and we are only talking
                            # about IPv4 at the moment. is there a better way of doing this?
                            hosts = []
                            # TODO: tmp. setting another netid of a node is a dirty hack
                            tmpnetid = node.netid
                            node.netid = server_asn
                            service_helpers.nodewalker(node, node, hosts,
                                    cls.nodewalker_asroot_dns_find_hosts_in_as_callback)
                            node.netid = tmpnetid
                            for hostname, asn_addr, zone in hosts:
                                if not isIPv4Address(asn_addr):
                                    continue

                                asn_addr = IPv4Addr(asn_addr)

                                print(('[DEBUG] asn_addr(%s) in asn_net(%s)' %
                                        (str(asn_addr), str(asn_net))))

                                if asn_addr < asn_net.minaddr() or \
                                        asn_addr > asn_net.maxaddr():
                                    continue

                                # set prefix length of the supernet
                                asn_addr.set_prefixlen(net_prefixlen)
                                asn_ptr_name = cls.getPTR_CNAME_FromAddr(cls, asn_addr)

                                #print(('[DEBUG] deployed ASN network (IPv%d): %s' %
                                #        (ipversion, str(asn_net))))
                                print(('[DEBUG] ASN PTR addr (IPv%d): %s' %
                                        (ipversion, str(asn_addr))))

                                print(('[DEBUG] adding: "%s IN NS %s"' %
                                        (asn_ptr_name, server_name)))
                                zoneentries.append(('%s IN NS %s' %
                                        (asn_ptr_name, server_name)))
                        elif ipversion == 6:
                            asn_ptr_name = cls.getPTRZoneNameFromPrefix(cls, asn_net)
                            print(('[DEBUG] adding: "%s IN NS %s"' %
                                    (asn_ptr_name, server_name)))
                            zoneentries.append(('%s IN NS %s' %
                                    (asn_ptr_name, server_name)))

                print(('[DEBUG] subnet name servers: %s' % (zoneentries)))

                zonecontents = '%s\n%s\n%s\n' % (ORIGINHeader, SOAHeader,
                        '\n'.join(zoneentries))
                cls.writeZoneFile(cls, node, zonename, zonecontents)
                print(('[DEBUG] adding ptrzone to zonenames: %s' % zonename))
                zonenames.append(zonename)

        return zonenames
Пример #8
0
    def generatequaggaconfig(cls, node):
        v6cfg = []
        v6prefixes = []

        if not node.enable_ipv4 and not node.enable_ipv6:
            return ''

        cfg = '!\n! BGP configuration\n!\n'
        cfg += 'log file /tmp/quagga-bgp-%s.log\n' % node.name
        cfg += 'router bgp %s\n' % node.netid
        cfg += '  bgp router-id %s\n' % cls.routerid(node)
        cfg += '  redistribute kernel\n'
        cfg += '  redistribute static\n'

        cfg += '!\n'

        if hasattr(node, 'netid') and not node.netid is None:
            netid = node.netid
        else:
            # TODO: netid 0 is invalid
            netid = 0

        # configure EBGP connections:
        if service_flags.EGP in node.services:
            tmpcfg, tmpv6cfg = cls.configure_EGP(node)
            cfg += tmpcfg
            v6cfg.extend(tmpv6cfg)

        # configure IBGP connections
        confstr_list = [cfg]
        # full mesh
        service_helpers.nodewalker(node, node, confstr_list,
                cls.nodewalker_ibgp_find_neighbors_callback)
        cfg = ''.join(confstr_list)

        if node.enable_ipv4 and service_flags.EGP in node.services:
            interface_net = Interface.getInterfaceNet_per_net(\
                    node.session.sessionid, netid, 4)
            loopback_net = Loopback.getLoopbackNet_per_net(\
                    node.session.sessionid, netid, 4)
            cfg += '  network %s\n' % str(loopback_net)
            cfg += '  network %s\n' % str(interface_net)
            cfg += '  aggregate-address %s summary-only\n' % str(loopback_net)
            cfg += '  aggregate-address %s summary-only\n' % str(interface_net)

        if node.enable_ipv6:
            v6_ibgp_neighbor_list = []
            service_helpers.nodewalker(node, node, v6_ibgp_neighbor_list,
                    cls.nodewalker_ibgp_find_neighbor_addrs_v6_callback)
            cfg += '  address-family ipv6\n'
            # activate IBGP neighbors
            cfg += ''.join([('    neighbor %s activate\n') % \
                    (str(remote_addr).split('/')[0]) \
                    for local_addr, remote_addr in v6_ibgp_neighbor_list])
            # activate EBGP neighbors
            cfg += ''.join(v6cfg)
            if service_flags.EGP in node.services:
                # announce networks
                interface_net = Interface.getInterfaceNet_per_net(\
                        node.session.sessionid, netid, 6)
                loopback_net = Loopback.getLoopbackNet_per_net(\
                        node.session.sessionid, netid, 6)
                cfg += '    network %s\n' % str(loopback_net)
                cfg += '    network %s\n' % str(interface_net)
                cfg += '    aggregate-address %s summary-only\n' % str(loopback_net)
                cfg += '    aggregate-address %s summary-only\n' % str(interface_net)
            adj_addrs = cls.collect_adjacent_loopback_addrs_v6(cls, node)
            for adj_addr in adj_addrs:
                cfg += '    network %s/128\n' % str(adj_addr)
            cfg += '\n  exit-address-family\n'

        return cfg
Пример #9
0
 def generateHosts(node):
     confstr_list =  []
     service_helpers.nodewalker(node, node, confstr_list,
             DNSProbeService.nodewalker_callback)
     return ''.join(confstr_list)
Пример #10
0
    def generateStartScript(cls, node):
        """ enable Netflow probe on peering links """

        config_list = []

        if not service_flags.EGP in node.services:
            config_list.append('# this is no border-router. disabling Netflow\n')
            return ''.join(config_list)

        config_list.extend([
                '#!/bin/sh\n',
                '# auto-generated by %s service (monitoring.py)\n\n' % cls._name
                ])
        base_sflowd_argv = ['/usr/local/sbin/softflowd']

        if node.enable_ipv6:
            # monitor IPv6
            base_sflowd_argv.append(' -6')

        # export NetFlow9
        base_sflowd_argv.append(' -v9')

        # transport layer protocol for exporting packets: UDP
        base_sflowd_argv.append(' -Pudp')

        # Set flow tracking level (default: full)
        base_sflowd_argv.append(' -Tfull')

        # Track up to 65536 flows
        base_sflowd_argv.append(' -m65536 ')

        # flow timeout definitions
        base_sflowd_argv.append((' -ttcp=120 -ttcp.rst=4 -ttcp.fin=10'
                            ' -tudp=10 -ticmp=10 -tgeneral=120 -tmaxlife=600'))

        # check every three seconds for expired flows
        base_sflowd_argv.append(' -texpint=3')

        # add any nfprobe9sink which is on our AS to the list of collectors
        collectors = []
        service_helpers.nodewalker(node, node, collectors,
                NetFlow9ProbeServiceSoftflowd.nodewalker_callback)

        for collector in collectors:
            base_sflowd_argv.append(' -n %s:2055' % collector)

        for localnetif in node.netifs():
            # do not ever include control interfaces in anything
            if hasattr(localnetif, 'control') and localnetif.control == True:
                continue

            sflowd_argv = []

            for idx, net_netif in list(localnetif.net._netif.items()):
                candidate_node = net_netif.node

                # skip our own interface
                if localnetif == net_netif:
                    continue

                # found peering link
                # enable netflow on this interface
                if not node.netid == net_netif.node.netid and \
                        service_flags.EGP in net_netif.node.services:

                    # get SNMP idx of this interface
                    result, stdouterr = node.cmdresult(
                            ['/opt/BENOCS/bin/ifindex', str(localnetif.name)])

                    if result != 0:
                        node.warn(('Could not determine SNMP interface number '
                                'for interface: %s - error: %s' % (
                                str(localnetif.name),
                                str(stdouterr))))
                        sflowd_argv.append((' -i %s' % str(localnetif.name)))
                    else:
                        stdouterr = stdouterr.decode().strip()
                        sflowd_argv.append((' -i %s:%s' % (str(stdouterr),
                                str(localnetif.name))))
                    sflowd_argv.append((' -p /var/run/softflowd.%s.pid' %
                            (str(localnetif.name))))
                    sflowd_argv.append((' -c /var/run/softflowd.%s.ctl' %
                            (str(localnetif.name))))

                    # although, these options erase themself, somehow it won't start otherwise
                    sflowd_argv.append(' -D')
                    #/usr/local/sbin/softflowd -6 -i 255:eth2 -n 172.16.56.11:2055 -Pudp -v9 -ttcp=3 -ttcp.fin=3 -tmaxlife=5 -p /var/run/softflowd.eth2.pid  -c /var/run/softflowd.eth2.ctl -D &

                    # TODO: make this work when multiple collectors are present
                    if len(collectors) > 0:
                        config_list.extend(['bash startprobe.sh ', '"', ''.join(base_sflowd_argv),
                                ''.join(sflowd_argv), '" ', collectors[0], ' ',
                                str(node.getLoopbackIPv4()), ' &', '\n'])
                        #config_list.extend(['bash startprobe.sh ', '"', ''.join(base_sflowd_argv),
                        #        ''.join(sflowd_argv), '" ', collectors[0], ' &', '\n'])

                    # skip checking of other nodes on this link. they wouldn't
                    # change any behavior, anyway. continue with next local
                    # interface
                    break

        return ''.join(config_list)