Exemplo n.º 1
0
class DnsSrvDiscoveryTest(TestCase):

    num_nodes = 3

    def setUp(self):
        zone_file = '''
crate.internal.               600   IN   SOA   localhost localhost ( 2007120710 1d 2h 4w 1h )
crate.internal.               400   IN   NS    localhost
crate.internal.               600   IN   A     127.0.0.1'''

        transport_ports = [bind_port() for _ in range(self.num_nodes)]
        for port in transport_ports:
            zone_file += '''
_test._srv.crate.internal.    600   IN   SRV   1 10 {port} 127.0.0.1.'''.format(port=port)

        dns_port = bind_port()
        self.dns_server = DNSServer(ZoneResolver(zone_file), port=dns_port)
        self.dns_server.start_thread()

        self.nodes = nodes = []
        for i in range(self.num_nodes):
            settings = {
                         'node.name': f'node-{i}',
                         'cluster.name': 'crate-dns-discovery',
                         'psql.port': 0,
                         'transport.tcp.port': transport_ports[i],
                         "discovery.seed_providers": "srv",
                         "discovery.srv.query": "_test._srv.crate.internal.",
                         "discovery.srv.resolver": "127.0.0.1:" + str(dns_port)
                     }
            if i is 0:
                settings['cluster.initial_master_nodes'] = f'node-{i}'
            node = CrateNode(
                crate_dir=crate_path(),
                version=(4, 0, 0),
                settings=settings,
                env={
                    'CRATE_HEAP_SIZE': '256M'
                }
            )
            node.start()
            nodes.append(node)

    def tearDown(self):
        for node in self.nodes:
            node.stop()
        self.dns_server.server.server_close()
        self.dns_server.stop()

    def test_nodes_discover_each_other(self):
        with connect(self.nodes[0].http_url) as conn:
            c = conn.cursor()
            c.execute('''select count(*) from sys.nodes''')
            result = c.fetchone()
        self.assertEqual(result[0], self.num_nodes, 'Nodes must be able to join')
Exemplo n.º 2
0
class PACDNSServer():
    def __init__(self, server, port=53, queue=None, ifname='eth0'):
        resolver = PACDNSResolver(server, port, timeout=5, queue=queue, ifname=ifname)
        handler = DNSHandler
        logger = DNSLogger("request", False)
        self.udp_server = DNSServer(resolver, logger=logger, handler=handler)

    def start(self, no_exit=False):
        self.udp_server.start_thread()
        while no_exit and self.udp_server.isAlive():
            time.sleep(1)
Exemplo n.º 3
0
def serveDNS(hostaddr):
    dnsport = 53
    resolver = InterceptResolver('8.8.8.8',
                                 dnsport,
                                 '60s',
                                 hostaddr)
    try:
        udp_server = DNSServer(resolver,
                           port=dnsport,
                           address=hostaddr,
                           logger = DNSLogger("-send,-recv,-request,-reply,-truncated,-error", False))
    except Exception as e:
        raise
    
    udp_server.start_thread()
    
    try:
        while udp_server.isAlive():
            time.sleep(1)
    except KeyboardInterrupt:
        sys.exit()
Exemplo n.º 4
0
def main():
    loadconfig()
    
    proxy_server = ThreadingTCPServer(('', 1081), ProxyServer)
    thread = threading.Thread(target=proxy_server.serve_forever)
    thread.daemon = True
    thread.start()
    print 'proxy running'

    resolver = DNSProxyResolver(DefaultDNS, 53, 10)
    logger = DNSLogger(log='-log_request, -log_reply', prefix=False)
    dns_server = DNSServer(resolver, port=5353, address='127.0.0.1', logger=logger, handler=DNSHandler)
    dns_server.start_thread()
    print 'dns running'
    
    try:
        while True:
            time.sleep(600)
            sys.stderr.flush()
            sys.stdout.flush()
    except socket.error, e:
        logging.error(e)
Exemplo n.º 5
0
    def handle(self, *args, **options):
        # map django command verbosity to logging options
        logger = DNSLogger(log={
            '0': '-request,-reply,-truncated,-error',
            '1': '',
            '2': '+data',
            '3': '+recv,+send,+data'
        }[options['verbosity']])

        udp_server = DNSServer(
            resolver=InterceptingResolver(),
            address=options['address'],
            port=options['port'],
            logger=logger
        )
        udp_server.start_thread()

        try:
            while udp_server.isAlive():
                time.sleep(1)
        except KeyboardInterrupt:
            udp_server.stop()
Exemplo n.º 6
0
def serveDNS(logger, status_ctrl, main_frame):
    
    resolver = InterceptResolver('8.8.8.8',
                                 53,
                                 '60s',
                                 status_ctrl,
                                 main_frame)
    
    DNSHandler.log = { 
        'log_request',      # DNS Request
        'log_reply',        # DNS Response
        'log_truncated',    # Truncated
        'log_error',        # Decoding error
    }

    config = wx.ConfigBase.Get()
    host = config.Read("host") or socket.gethostbyname(socket.gethostname())
    dnsport = config.Read("dnsport") or "53"
    try:
        udp_server = DNSServer(resolver,
                           port=int(dnsport),
                           address=host,
                           logger=logger)
    except Exception as e:
        evt = custom_events.wxStatusEvent(message='Error starting DNS proxy: %s' % e)
        wx.PostEvent(status_ctrl,evt)
        return

    udp_server.start_thread()

    evt = custom_events.wxStatusEvent(message="proxy started")            
    wx.PostEvent(status_ctrl,evt)

    try:
        while udp_server.isAlive():
            time.sleep(1)
    except KeyboardInterrupt:
        sys.exit()
Exemplo n.º 7
0
class ParentalControls(BaseResolver):

    """
        Intercepting resolver 
        
        Proxy requests to upstream server optionally intercepting requests
        matching local records
    """

    def __init__(self):
        self.log = logging.getLogger('dnspc.dnspc.ParentalControls')
        self.rules = []
        self.hosts = []
        self.LOCAL_IP = settings.DNS['LOCAL_IP']
        self.LOCAL_PORT = settings.DNS['LOCAL_PORT']
        self.UP_IP = settings.DNS['UP_IP']
        self.UP_PORT = settings.DNS['UP_PORT']
        self.TCP = settings.DNS['TCP']
        self.TTL = parse_time(settings.DNS['TTL'])
        self.store ={
            'rules': settings.DATA['RULES'],
            'hosts': settings.DATA['HOSTS']
        }
        self.load_rules()
        self.load_hosts()

    ## Rules
    def load_rules(self):
        stored_rules = self.store['rules'].loadRecords()
        uids = [r['_uid'] for r in self.rules]
        for sr in stored_rules:
            if sr['_uid'] in uids:
                continue
            rule = PCRule(**sr)
            self.rules.append(rule)
        self.log.debug("WTF:rules: {}".format(self.rules))
    def update_rule(self,rule):
        uid = rule._uid
        idxs = [i for i,c in enumerate(self.rules) if c._uid == uid]
        if len(idxs) == 0:
            self.rules.append(rule)
        else:
            self.rules[idxs[0]] = rule
        return rule

    def save_rule(self,d=None,**kwargs):
        #print "save_rule({})".format(kwargs)
        ## Remove angularjs artifacts:
        kwargs.pop('$$hashKey',None)
        saved_rule = self.store['rules'].editRecord(kwargs)
        self.log.debug("WTF: saved_rule: {}".format(saved_rule))
        rule = PCRule(**saved_rule)
        ## Not sure if I should update the rule, or just reload from disk.
        self.update_rule(rule)
        return rule

    def del_rule(self,uid):
        ''' del_rule(uid) returns:
             None: uid did not appear in list.
             True: success
            False: failure
        '''
        #print "del_rule({})".format(uid)
        #pp([x._serialize() for x in self.rules])
        self.store['rules'].deleteRecord({'_uid':uid})
        if uid not in [x._uid for x in self.rules]:
            return None
        self.rules = [x for x in self.rules if x._uid != uid]
        if uid in [x._uid for x in self.rules]:
            return False
        return True

    def get_rules(self):
        return self.rules

    def get_matching_rules(self,src_ip,dst_str):
        rs = [ r for r in self.rules if r.is_match(src_ip,dst_str) ]
        return rs

    ## Hosts
    def load_hosts(self):
        stored_hosts = self.store['hosts'].loadRecords()
        uids = [r['_uid'] for r in self.hosts]
        for sr in stored_hosts:
            if sr['_uid'] in uids:
                continue
            rule = PCHost(**sr)
            self.hosts.append(rule)
    def update_host(self,host):
        uid = host._uid
        idxs = [i for i,c in enumerate(self.hosts) if c._uid == uid]
        if len(idxs) == 0:
            self.hosts.append(host)
        else:
            self.hosts[idxs[0]] = host
        return host

    def save_host(self,d=None,**kwargs):
        #print "save_host({})".format(kwargs)
        ## Key generated by filestore.
        ## Can't risk overlap.
        #key = self._genkey(self.hosts)
        #print "WTF: Created key:",key
        kwargs.pop('$$hashKey',None)
        saved_host = self.store['hosts'].editRecord(kwargs)
        self.log.debug("WTF: saved_host: {}".format(saved_host))
        host = PCHost(**saved_host)
        self.update_host(host)
        #pp(self.hosts)
        return host

    def del_host(self,uid):
        ''' del_host(uid) returns:
             None: uid did not appear in list.
             True: success
            False: failure
        '''
        #print "del_host({})".format(uid)
        #pp([x._serialize() for x in self.hosts])
        self.store['hosts'].deleteRecord({'_uid':uid})
        if uid not in [x._uid for x in self.hosts]:
            return None
        self.hosts = [x for x in self.hosts if x._uid != uid]
        if uid in [x._uid for x in self.hosts]:
            return False
        return True

    def get_hosts(self):
        return self.hosts

    def _genkey(self,st):
        #print "WTF: _genkey()"
        key = int(time.strftime('%Y%U%w000'))
        #print "WTF: My key:",key
        keys = [r._uid for r in st]
        #print "WTF: keys:",keys
        #while len([1 for r in st if int(r['_uid']) == key]) > 0:
        while key in keys:
            key = key + 1
        return key

    ## DNS Server Methods
    def start(self):
        handler = DNSHandler
        # log options: "recv,send,request,reply,truncated,error,data"
        # log defaults: "request,reply,truncated,error"
        # It's just too much stuff!
        logger = DNSLogger("truncated,error",True)
        self.log.info("Starting UDP server")
        if 'udp_server' not in dir(self):
            self.udp_server = DNSServer(self,
                            port=self.LOCAL_PORT,
                            address=self.LOCAL_IP,
                            logger=logger,
                            handler=handler)
        self.udp_server.start_thread()
        if self.TCP:
            self.log.info("Starting TCP server")
            if 'tcp_server' not in dir(self):
                self.tcp_server = DNSServer(self,
                                port=self.LOCAL_PORT,
                                address=self.LOCAL_IP,
                                tcp=True,
                                logger=logger,
                                handler=handler)
            self.tcp_server.start_thread()

    def stop(self):
        self.log.debug( dir(self) )
        if 'udp_server' in dir(self):
            self.log.debug( "    Stopping UDP server." )
            self.udp_server.stop()
        if 'tcp_server' in dir(self) and self.TCP:
            self.log.debug( "    Stopping TCP server." )
            self.tcp_server.stop()

    def resolve(self,request,handler):
        client_ip = handler.client_address[0]
        #print "Request from IP: {}".format(client_ip)
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]
        reply = request.reply()
        self.log.debug("{} request for {} by {}".format(qtype,qname,client_ip))
        #print "query: {}".format(qname)
        #print "query: {}".format(qname.matchGlob("*.yahoo.com"))
        # Try to resolve locally unless on skip list
        rules = self.get_matching_rules(client_ip,qname)
        self.log.debug("Matched rules: {}".format(rules))
        if any(rules):
            ## Collecting info on match for logging
            match_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            match_name = client_ip
            match_hosts = [h.name for h in self.hosts if h.ip == client_ip]
            if any(match_hosts):
                match_name = ",".join(match_hosts)
            for rule in rules:
                if rule.action == 'monitor':
                    monitor.info({'time':match_time,'match_name':match_name,'client_ip':client_ip,'qname':str(qname)})
                if rule.action == 'redirect':
                    self.log.debug( "[{}] REDIRECT {}-->{} to {}".format(match_time,match_name,qname,rule.redirect) )
                    redir = rule.redirect
                    reply.add_answer(*RR.fromZone("{} 3600 IN A {}".format(qname,redir)))
                    return reply
                if rule.action == 'block':
                    self.log.debug( "[{}] BLOCKED {}({})-->{}".format(match_time,match_name,client_ip,qname) )
                    return reply
                if rule.action == 'allow':
                    self.log.debug( "[{}] ALLOWED {}({})-->{}".format(match_time,match_name,client_ip,qname) )
        ## If no match or action == 'allow', then proxy the request to IP_UP
        if handler.protocol == 'udp':
            proxy_r = request.send(self.UP_IP,self.UP_PORT)
        else:
            proxy_r = request.send(self.UP_IP,self.UP_PORT,tcp=True)
        reply = DNSRecord.parse(proxy_r)
        return reply
Exemplo n.º 8
0
    resolver = FixedResolver(args.response)
    logger = DNSLogger(args.log, args.log_prefix)

    print("Starting Fixed Resolver (%s:%d) [%s]" %
          (args.address or "*", args.port, "UDP/TCP" if args.tcp else "UDP"))

    for rr in resolver.rrs:
        print("    | ", rr.toZone().strip(), sep="")
    print()

    if args.udplen:
        DNSHandler.udplen = args.udplen

    udp_server = DNSServer(resolver,
                           port=args.port,
                           address=args.address,
                           logger=logger)
    udp_server.start_thread()

    if args.tcp:
        tcp_server = DNSServer(resolver,
                               port=args.port,
                               address=args.address,
                               tcp=True,
                               logger=logger)
        tcp_server.start_thread()

    while udp_server.isAlive():
        time.sleep(1)
Exemplo n.º 9
0
class DnsServer(BaseCommand):
    name = "dns-server"
    aliases = ["dns"]
    description = "run dns server"
    add_log_level = True
    add_debug = True

    def __init__(self, *args, **kwargs):
        self.api_client = None
        self.resolver = None
        self.udp_server = None
        self.tcp_server = None
        super().__init__(*args, **kwargs)

    @classmethod
    def parser(cls, parser):
        parser.add_argument(
            "-a",
            "--api-url",
            default="http://127.0.0.1:8080",
            action="store",
            help="api url",
        )
        parser.add_argument("-t",
                            "--api-token",
                            action="store",
                            help="api token")
        parser.add_argument("-p",
                            "--port",
                            action="store",
                            type=int,
                            default=53,
                            help="listen port")
        parser.add_argument("-l",
                            "--listen",
                            action="store",
                            default="127.0.0.1",
                            help="bind address")
        parser.add_argument("--no-sync",
                            action="store_true",
                            help="sync api token back to database")

        parser.add_argument(
            "-r",
            "--refresh-ttl",
            type=int,
            default=3600,
            action="store",
            help="time to wait before polling for new records",
        )
        return parser

    async def run(self):

        # TODO: thread issues?
        self.api_client = ApiClient(self.get_api_url(), self.get_api_token())

        if not self.api_client.wait_for_up():
            logger.critical("could not connect to api. quitting")
            self.exit(1)

        if self.option("no_sync"):
            logger.info("skipping syncing api token")
        else:
            self.api_client.sync()

        self.boot()

        self.start_servers()

        try:
            count = 0
            while self.udp_server.isAlive():
                if count > 0 and count % self.option("refresh_ttl") == 0:
                    if self.api_client.refresh_zones_if_needed():
                        logger.critical(
                            "API Client found new or changed zones. Stopping servers..."
                        )
                        # TODO: figure out why "stop" does not release the address
                        self.stop_servers()

                        sleep(1)

                        stop_count = 0
                        logger.critical("Waiting for UDP Server to stop...")
                        while self.udp_server.thread and self.udp_server.isAlive(
                        ):
                            if stop_count > 30:
                                logger.critical(
                                    "UDP Server did not stop while reloading zones"
                                )
                                raise Exception(
                                    "UDP Server threads went rogue during zone reload"
                                )
                            logger.info(
                                "Waiting for DNS Server to stop before reloading zones"
                            )
                            stop_count = stop_count + 1
                            sleep(1)
                        stop_count = 0
                        logger.critical("Waiting for TCP Server to stop...")
                        while self.tcp_server.thread and self.tcp_server.isAlive(
                        ):
                            if stop_count > 30:
                                logger.critical(
                                    "TCP Server did not stop while reloading zones"
                                )
                                raise Exception(
                                    "TCP Server threads went rogue during zone reload"
                                )
                            logger.info(
                                "Waiting for DNS Server to stop before reloading zones"
                            )
                            stop_count = stop_count + 1
                            sleep(1)
                        logger.critical("Rebooting server with fresh zones...")
                        self.boot()
                        self.start_servers()

                count = count + 1
                sleep(1)
        except KeyboardInterrupt:
            pass

    def get_api_url(self):
        if os.environ.get("API_URL", None):
            return os.environ.get("API_URL")
        return self.option("api_url")

    def get_api_token(self):
        if os.environ.get("API_TOKEN", None):
            return os.environ.get("API_TOKEN")
        if self.option("api_token", None):
            return self.option("api_token")
        logger.critical("api token required")
        self.exit(1)

    def get_port(self):
        return self.option("port")

    def get_listen(self):
        return self.option("listen")

    def boot(self):
        port = self.get_port()
        listen = self.get_listen()

        self.resolver = Resolver(self.api_client)
        self.udp_server = DNSServer(
            self.resolver,
            address=listen,
            port=port,
            handler=DNSHandler,
            logger=DNSLogger(self.api_client),
        )
        self.tcp_server = DNSServer(
            self.resolver,
            address=listen,
            port=port,
            tcp=True,
            handler=DNSHandler,
            logger=DNSLogger(self.api_client),
        )

        logger.info("starting DNS server on port %d", port)

    def start_servers(self):
        self.udp_server.start_thread()
        self.tcp_server.start_thread()

    def stop_servers(self):
        self.udp_server.stop()
        self.udp_server.server.socket.close()
        self.udp_server.server.server_close()
        self.tcp_server.stop()
        self.tcp_server.server.socket.close()
        self.tcp_server.server.server_close()
Exemplo n.º 10
0
def main():
    signal.signal(signal.SIGTERM, handle_sig)

    parser = argparse.ArgumentParser(description='LocalTLS')
    parser.add_argument('--domain',
                        required=True,
                        help="Your domain or subdomain.")
    parser.add_argument(
        '--soa-master',
        help="Primary master name server for SOA record. You should fill this."
    )
    parser.add_argument(
        '--soa-email',
        help=
        "Email address for administrator for SOA record. You should fill this."
    )
    parser.add_argument('--ns-servers',
                        help="List of ns servers, separated by comma")
    parser.add_argument('--dns-port', default=53, help="DNS server port")
    parser.add_argument(
        '--domain-ipv4',
        default='',
        help="The IPV4 for the naked domain. If empty, use this machine's.")
    parser.add_argument(
        '--domain-ipv6',
        default='',
        help="The IPV6 for the naked domain. If empty, use this machine's.")
    parser.add_argument('--only-private-ips',
                        action='store_true',
                        default=False,
                        help="Resolve only IPs in private ranges.")
    parser.add_argument('--dns-fallback',
                        default='1.1.1.1',
                        help="DNS fallback server. Default: 1.1.1.1")
    parser.add_argument(
        '--http-port',
        help="HTTP server port. If not set, no HTTP server is started")
    parser.add_argument('--http-index-file',
                        default='index.html',
                        help="HTTP index.html file.")
    parser.add_argument('--log-level',
                        default='ERROR',
                        help="INFO|WARNING|ERROR|DEBUG")
    args = parser.parse_args()

    # The primary addresses
    confs.LOCAL_IPV4 = args.domain_ipv4 if args.domain_ipv4 else get_ipv4()
    confs.LOCAL_IPV6 = args.domain_ipv6 if args.domain_ipv6 else get_ipv6()
    try:
        ipaddress.ip_address(confs.LOCAL_IPV4)
    except:
        logger.critical('Invalid IPV4 %s', LOCAL_IPV4)
        sys.exit(1)
    try:
        if confs.LOCAL_IPV6:
            ipaddress.ip_address(confs.LOCAL_IPV6)
    except:
        logger.critical('Invalid IPV6 %s', LOCAL_IPV6)
        sys.exit(1)
    logger.setLevel(args.log_level)

    confs.ONLY_PRIVATE_IPS = args.only_private_ips
    confs.BASE_DOMAIN = args.domain
    confs.SOA_MNAME = args.soa_master
    confs.SOA_RNAME = args.soa_email
    if not confs.SOA_MNAME or not confs.SOA_RNAME:
        logger.error('Setting SOA is strongly recommended')

    if args.ns_servers:
        confs.NS_SERVERS = args.ns_servers.split(',')

    # handle local messages to add TXT records
    threadMessage = threading.Thread(target=messageListener)
    threadMessage.start()

    # open the DNS server
    port = int(args.dns_port)
    upstream = args.dns_fallback
    resolver = Resolver(upstream)
    if args.log_level == 'debug':
        logmode = "+request,+reply,+truncated,+error"
    else:
        logmode = "-request,-reply,-truncated,+error"
    dnslogger = DNSLogger(log=logmode, prefix=False)
    udp_server = DNSServer(resolver, port=port, logger=dnslogger)
    tcp_server = DNSServer(resolver, port=port, tcp=True, logger=dnslogger)

    logger.critical(
        'starting DNS server on %s/%s on port %d, upstream DNS server "%s"',
        confs.LOCAL_IPV4, confs.LOCAL_IPV6, port, upstream)
    udp_server.start_thread()
    tcp_server.start_thread()

    # open the HTTP server
    if args.http_port:
        logger.critical('Starting httpd...')
        threadHTTP = threading.Thread(target=httpserver.run,
                                      kwargs={
                                          "port": int(args.http_port),
                                          "index": args.http_index_file
                                      })
        threadHTTP.start()

    try:
        while udp_server.isAlive():
            sleep(1)
    except KeyboardInterrupt:
        pass
Exemplo n.º 11
0
import dnslib
import time


class HardcodedResolver:
    ANSWER = "192.168.0.1"

    def resolve(self, request, handler):
        reply = request.reply()
        if request.questions[0].qname == QUESTION_ADDRESS:
            fake_rr = RR(rname=QUESTION_ADDRESS,
                         ttl=5,
                         rdata=A(HardcodedResolver.ANSWER))
            reply.add_answer(fake_rr)
        else:
            reply.header.rcode = dnslib.RCODE.REFUSED
        return reply


resolver = HardcodedResolver()

logger = DNSLogger(prefix=False)

server = DNSServer(resolver,
                   port=PORT,
                   address=ADDRESS,
                   logger=logger,
                   tcp=False)
server.start_thread()

time.sleep(100.0)
Exemplo n.º 12
0
class SCIONDnsServer(SCIONElement):
    """
    SCION DNS Server. Responsible for starting the DNS resolver threads, and
    frequently updating the shared instance data from ZK.

    :cvar float SYNC_TIME: How frequently (in seconds) to update the shared
                           instance data from ZK.
    :cvar list SRV_TYPES: Service types to monitor/export
    """
    SERVICE_TYPE = DNS_SERVICE
    SYNC_TIME = 1.0
    SRV_TYPES = (BEACON_SERVICE, CERTIFICATE_SERVICE,
                 DNS_SERVICE, PATH_SERVICE, SIBRA_SERVICE)

    def __init__(self, server_id, conf_dir, setup=False, prom_export=None):  # pragma: no cover
        """
        :param str server_id: server identifier.
        :param str conf_dir: configuration directory.
        :param str prom_export: prometheus export address.
        :param bool setup: should setup() be called?
        """
        super().__init__(server_id, conf_dir, prom_export=prom_export)
        self.domain = DNSLabel(self.topology.dns_domain)
        self.lock = threading.Lock()
        self.services = {}
        if setup:
            self.setup()

    def setup(self):
        """
        Set up various servers and connections required.
        """
        self.resolver = ZoneResolver(self.lock, self.domain)
        self.udp_server = DNSServer(self.resolver, port=SCION_DNS_PORT,
                                    address=str(self.addr.host),
                                    server=SCIONDnsUdpServer,
                                    logger=SCIONDnsLogger())
        self.tcp_server = DNSServer(self.resolver, port=SCION_DNS_PORT,
                                    address=str(self.addr.host),
                                    server=SCIONDnsTcpServer,
                                    logger=SCIONDnsLogger())
        self.name_addrs = "\0".join([self.id, str(SCION_DNS_PORT),
                                     str(self.addr.host)])
        self.zk = Zookeeper(self.topology.isd_as, DNS_SERVICE, self.name_addrs,
                            self.topology.zookeepers)
        self._parties = {}
        self._setup_parties()

    def _setup_parties(self):
        """
        Join all the necessary ZK parties.
        """
        logging.debug("Joining parties")
        for type_ in self.SRV_TYPES:
            prefix = "/%s/%s" % (self.addr.isd_as, type_)
            autojoin = False
            # Join only the DNS service party, for the rest we just want to
            # setup the party so we can monitor the members.
            if type_ == DNS_SERVICE:
                autojoin = True
            self._parties[type_] = self.zk.retry(
                "Joining %s party" % type_, self.zk.party_setup, prefix=prefix,
                autojoin=autojoin)

    def _sync_zk_state(self):
        """
        Update shared instance data from ZK.
        """
        # Clear existing state
        self.services = {}

        try:
            self.zk.wait_connected(timeout=10.0)
        except ZkNoConnection:
            logging.warning("No connection to Zookeeper, can't update services")
            return

        # Retrieve alive instance details from ZK for each service.
        for srv_type in self.SRV_TYPES:
            srv_domain = self.domain.add(srv_type)
            self.services[srv_domain] = []
            party = self._parties[srv_type]
            try:
                srvs = party.list()
            except ZkNoConnection:
                # If the connection drops, don't update
                return
            for i in srvs:
                self._parse_srv_inst(i, srv_domain)

        # Update DNS zone data
        with self.lock:
            self.resolver.services = self.services

    def _parse_srv_inst(self, inst, srv_domain):
        """
        Parse a server instance block into name/port/addresses,
        and add them to the services list.

        :param str inst: Server instance block (null-seperated strings)
        :param dnslib.DNSLabel srv_domain: service domain
        """
        name, port, *addresses = inst.split("\0")
        self.services[srv_domain].extend(addresses)

    def handle_request(self, packet, sender, from_local_socket=True):
        raise NotImplementedError

    def run(self):
        """
        Run SCION Dns server.
        """
        self._sync_zk_state()
        self.udp_server.start_thread()
        self.tcp_server.start_thread()
        while self.udp_server.isAlive() and self.tcp_server.isAlive():
            self._sync_zk_state()
            sleep(self.SYNC_TIME)
Exemplo n.º 13
0
def main():
    global OPTIONS, ARGS

    parser = OptionParser()

    parser.add_option("-b", "--bind", dest = "bind", \
                      type = "string", default = "127.0.0.7:53", \
                      help = "set bind address/port to IP[:PORT]. " \
                      "Default value is `127.0.0.7:53'.", \
                      metavar = "IP[:PORT]")
    parser.add_option("-t", "--timeout", dest = "timeout", \
                      type = "int", default = "5", \
                      help = "set DNS resolving timeout to SECONDS", \
                      metavar = "SECONDS")
    parser.add_option("-r", "--retry", dest = "retry", \
                      type = "int", default = "3", \
                      help = "set retry count to COUNT", metavar = "COUNT")
    parser.add_option("-i", "--invalid-resolve", dest = "invalid_resolve", \
                      type = "string", default = r"10\.10\.34\.\d+", \
                      help = "REGEX is a an IP address or a regular " \
                      "expression that will not be prefered on DNS " \
                      "resolving. Default value is `10.10.34.\\d+'.", \
                      metavar = "REGEX")
    parser.add_option("--request-bind", dest = "request_bind", \
                      type = "string", default = "", \
                      help = "bind to IP address before sending DNS " \
                      "requests.", metavar = "IP")
    parser.add_option("-q", "--quiet", dest = "quiet", \
                      action = "store_true", default = False, \
                      help = "do not print any log")
    
    parser.set_usage("%s [OPTION]... DNS_SERVER[:PORT]..." % \
                     sys.argv[0])
    parser.set_description(__doc__)

    OPTIONS, ARGS = parser.parse_args()

    if len(ARGS) < 1:
        parser.print_help()
        exit(1)

    def get_address_port(arg):
        address_port = arg if ":" in arg else "%s:53" % arg
        address_port = address_port.split(":")
        return address_port[0], int(address_port[1])

    bind_address, bind_port = get_address_port(OPTIONS.bind)
    dns_servers = [get_address_port(arg) for arg in ARGS]

    resolver = ProxyResolver(dns_servers, request_bind_address = \
                             (OPTIONS.request_bind or None))
    logger = DNSLogger("request,reply,truncated,error", False) \
             if not OPTIONS.quiet else \
             DNSLogger("-request,-reply,-truncated,-error,-log_recv," \
                       "-log_send,-log_data", False)
    udp_server = DNSServer(resolver,
                           port = bind_port,
                           address = bind_address,
                           logger = logger if not OPTIONS.quiet else None,
                           handler = DNSHandler,
                           server = UDPServer)

    udp_server.start_thread()

    try:
        while udp_server.isAlive():
            time.sleep(1)
    except KeyboardInterrupt:
        if not OPTIONS.quiet:
            print("Shutting down the server with user request...")
        udp_server.stop()
        exit(0)
Exemplo n.º 14
0
class DNS(object):
    def __init__(self):
        self.default_ip = get_default_ip()
        self.resolver = None
        self.server = None
        self.base_zone_data = None
        self.reset()

    def wait_for_query(self, record_type, record_name, timeout):
        self.resolver.wait_for_query(record_type, record_name, timeout)

    def set_expected_query(self, record_type, record_names):
        self.resolver.set_expected_query(record_type, record_names)

    def is_query_received(self):
        return self.resolver.is_query_received()

    def load_zone(self, api_version, api_protocol, api_authorization, zone_name, port_base):
        zone_file = open(zone_name).read()
        template = Template(zone_file)
        zone_data = template.render(ip_address=self.default_ip, api_ver=api_version, api_proto=api_protocol,
                                    api_auth=str(api_authorization).lower(), domain=CONFIG.DNS_DOMAIN,
                                    port_base=port_base)
        self.resolver = WatchingResolver(self.base_zone_data + zone_data)
        self.stop()
        print(" * Loading DNS zone file '{}' with api_ver={}".format(zone_name, api_version))
        self.start()

    def reset(self):
        zone_file = open("test_data/core/dns_base.zone").read()
        template = Template(zone_file)

        extra_services = {}
        if CONFIG.ENABLE_AUTH:
            auth_proto = "https" if CONFIG.ENABLE_HTTPS else "http"
            extra_services["auth"] = {
                "host": CONFIG.AUTH_SERVER_HOSTNAME,
                "ip": CONFIG.AUTH_SERVER_IP,
                "port": CONFIG.AUTH_SERVER_PORT,
                "txt": ["api_ver=v1.0", "api_proto={}".format(auth_proto), "pri=0"]
            }
        if CONFIG.ENABLE_MQTT_BROKER:
            extra_services["mqtt"] = {
                "host": CONFIG.MQTT_BROKER_HOSTNAME,
                "ip": CONFIG.MQTT_BROKER_IP,
                "port": CONFIG.MQTT_BROKER_PORT,
                "txt": ["api_proto=mqtt", "api_auth=false"]
            }

        self.base_zone_data = template.render(ip_address=self.default_ip, domain=CONFIG.DNS_DOMAIN,
                                              extra_services=extra_services)
        self.resolver = WatchingResolver(self.base_zone_data)
        self.stop()
        print(" * Loading DNS zone base file")
        self.start()

    def start(self):
        if not self.server:
            print(" * Starting DNS server on {}:53".format(self.default_ip))
            try:
                self.server = DNSServer(self.resolver, port=53, address=self.default_ip)
                self.server.start_thread()
            except Exception as e:
                print(" * ERROR: Unable to bind to port 53. DNS server could not start: {}".format(e))

    def stop(self):
        if self.server:
            print(" * Stopping DNS server on {}:53".format(self.default_ip))
            self.server.stop()
            self.server = None
Exemplo n.º 15
0
    try:
        resolver = AvahiBrowser()

        logger = DNSLogger(prefix=False)
        server = DNSServer(
            resolver,
            port=8053,
            address='0.0.0.0',
            # tcp=True,
            logger=logger)

        resolver.connect()

        # scanner.browse_domain("local", "_ssh._tcp")
        resolver.browse_domain('local')
        server.start_thread()
        # server.start()

    except dbus.DBusException as e:
        print("Failed to connect to Avahi, is it running?: {}".format(e))
        sys.exit(1)

    loop = gobject.MainLoop()

    run_forever = True
    if run_forever:
        loop.run()
    else:
        main_context = loop.get_context()

        changed = True
Exemplo n.º 16
0
    print("Starting Zone Resolver (%s:%d) [%s]" % (
                        args.address or "*",
                        args.port,
                        "UDP/TCP" if args.tcp else "UDP"))

    for rr in resolver.zone:
        print("    | ",rr[2].toZone(),sep="")
    print()

    if args.udplen:
        DNSHandler.udplen = args.udplen

    udp_server = DNSServer(resolver,
                           port=args.port,
                           address=args.address,
                           logger=logger)
    udp_server.start_thread()

    if args.tcp:
        tcp_server = DNSServer(resolver,
                               port=args.port,
                               address=args.address,
                               tcp=True,
                               logger=logger)
        tcp_server.start_thread()

    while udp_server.isAlive():
        time.sleep(1)

Exemplo n.º 17
0
########################
# DNS
########################
print("DNS ....")

# start dns
class RecordResolver:
    answers = ["*. 60 A {}".format(args.record)]
    def resolve(self,request,handler):
        reply = request.reply()
        [reply.add_answer(*RR.fromZone(a)) for a in self.answers]
        return reply
resolver = RecordResolver()
dns = DNSServer(resolver,port=10053,address="0.0.0.0" )#, logger=DNSLogger("-request,-reply,-truncated"))
dns.start_thread()

#######################
# HTTP 
#######################
print("HTTP ....")
http01 = http.server.HTTPServer(('0.0.0.0', 5002), http.server.SimpleHTTPRequestHandler)
threading.Thread(target=http01.serve_forever).start()

class httpShutHandler(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        global ALIVE
        ALIVE=False
        try:
            os.system(r'ps o pid,comm | \
                     grep python | \