예제 #1
0
 def __init__(self, routes, origin, ttl):
     self.origin = DNSLabel(origin)
     self.ttl = parse_time(ttl)
     self.routes = {}
     for r in routes:
         route, _, cmd = r.partition(":")
         if route.endswith('.'):
             route = DNSLabel(route)
         else:
             route = self.origin.add(route)
         self.routes[route] = cmd
예제 #2
0
 def __init__(self,zone,origin="",ttl=0):
     self.l = WordLexer(zone)
     self.l.commentchars = ';'
     self.l.nltok = ('NL',None)
     self.l.spacetok = ('SPACE',None)
     self.i = iter(self.l)
     if type(origin) is DNSLabel:
         self.origin = origin
     else:
         self.origin= DNSLabel(origin)
     self.ttl = ttl
     self.label = DNSLabel("")
     self.prev = None
예제 #3
0
 def load_domain_rules(self):
     with open(self.domains_rules_filename, 'r') as fh:
         for line in fh.readlines():
             line = line.strip()
             if len(line) > 6:
                 domain, rule = line.split(',', 2)
                 if rule in self.DOMAIN_STATES:
                     self.domain_rules[DNSLabel(domain)] = rule
                     #print("Added domain rule: %s %s" % (domain, rule))
                 if rule == self.DOMAIN_REQUESTED:
                     request_label = self.add_request(
                         domain, DNSLabel(domain))
                     print("To approve %s, please query %s" %
                           (domain, str(request_label)))
예제 #4
0
    def resolve(self, request, handler):
        reply = request.reply(
        )  # the object that this function will return in the end, with modifications
        qname = request.q.qname  # the domain that was looked up

        burrow_log("Request for " + str(DNSLabel(qname.label[-5:])), 0)

        # First, we make sure the domain ends in burrow.tech.
        # If not, we return an NXDOMAIN result.
        if not qname.matchSuffix("burrow.tech"):
            reply.header.rcode = RCODE.NXDOMAIN
            return reply

        # Next, we try to look up the domain in our list of fixed test records.
        found_fixed_rr = False
        for rr in self.fixedrrs:
            a = copy.copy(rr)
            if (a.rname == qname):
                found_fixed_rr = True
                LOG("Found a fixed record for " + str(a.rname))
                reply.add_answer(a)
        if found_fixed_rr:
            return reply

        # Alright, if we've gotten here it must be a Transmission API message!
        assert (not found_fixed_rr)
        response_dict = self.handle_transmission_api_message(qname)
        zone = generate_TXT_zone(str(qname), dict_to_attributes(response_dict))
        rrs = RR.fromZone(zone)
        for rr in rrs:
            reply.add_answer(rr)
        return reply
예제 #5
0
class ShellResolver(BaseResolver):
    """
        Example dynamic resolver. 
        Maps DNS labels to shell commands and returns result as TXT record
        (Note: No context is passed to the shell command)
    """
    def __init__(self,routes,origin,ttl):
        self.origin = DNSLabel(origin)
        self.ttl = parse_time(ttl)
        self.routes = {}
        for r in routes:
            route,_,cmd = r.partition(":")
            if route.endswith('.'):
                route = DNSLabel(route)
            else:
                route = self.origin.add(route)
            self.routes[route] = cmd

    def resolve(self,request,handler):
        reply = request.reply()
        qname = request.q.qname
        cmd = self.routes.get(qname)
        if cmd:
            output = getoutput(cmd).encode()
            reply.add_answer(RR(qname,QTYPE.TXT,ttl=self.ttl,
                                rdata=TXT(output[:254])))
        else:
            reply.header.rcode = RCODE.NXDOMAIN
        return reply
예제 #6
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname

        if static_entries.get(str(qname)):
            # print("Got from static entries")
            for response in static_entries[str(qname)]:
                if request.q.qtype == response.rtype:
                    reply.add_answer(response)
            return reply

        if any([str(qname).endswith(d) for d in mdns_domains]):
            # print("Querying mDNS")
            return self.resolve_mdns(request, handler)

        for f, repl in alternative_nonlocal_domains.items():
            # print("Asking for {} v. {}".format(qname, f))
            if qname.matchSuffix(f):
                print("Matched suffix. Rewriting query from {} to {}".format(
                    f, repl))
                request.q.qname = DNSLabel(repl).add(qname.stripSuffix(f))
                print("Now querying for: {}".format(request.q.qname))
                return self.resolve_mdns(request, handler, rewrite=qname)

        # print("Querying upstream DNS")
        return self.resolve_fwd(request, handler)
예제 #7
0
class ShellResolver(BaseResolver):
    """
        Example dynamic resolver.
        Maps DNS labels to shell commands and returns result as TXT record
        (Note: No context is passed to the shell command)

        Shell commands are passed in a a list in <label>:<cmd> format - eg:

            [ 'uptime.abc.com.:uptime', 'ls:ls' ]

        Would respond to requests to 'uptime.abc.com.' with the output
        of the 'uptime' command.

        For non-absolute labels the 'origin' parameter is prepended

    """
    def __init__(self, routes, origin, ttl):
        self.origin = DNSLabel(origin)
        self.ttl = parse_time(ttl)
        self.routes = {}
        for r in routes:
            route, _, cmd = r.partition(":")
            if route.endswith('.'):
                route = DNSLabel(route)
            else:
                route = self.origin.add(route)
            self.routes[route] = cmd

    def resolve(self, request, handler):
        print("resolver:" + "-" * 40)
        reply = request.reply()
        qname = request.q.qname
        ia = ip_address(handler.client_address[0])
        cmd = self.routes.get(qname)
        if cmd:
            output = getoutput(cmd).encode()
            reply.add_answer(
                RR(qname, QTYPE.TXT, ttl=self.ttl, rdata=TXT(output[:254])))
        else:
            rqt = QTYPE.TXT
            rqd = TXT(f"{str(ia)}")
            if request.q.qtype in [QTYPE.A, QTYPE.AAAA, QTYPE.PTR]:
                QTR = {QTYPE.A: "A", QTYPE.AAAA: "AAAA", QTYPE.PTR: "PTR"}
                qt = QTR[request.q.qtype]
                if ia.version is 6 and request.q.qtype == QTYPE.AAAA:
                    rqt = request.q.qtype
                    rqd = AAAA(str(ia))
                elif ia.version is 4 and request.q.qtype == QTYPE.A:
                    rqt = request.q.qtype
                    rqd = A(str(ia))
                elif request.q.qtype == QTYPE.PTR:
                    rqt = request.q.qtype
                    rqd = PTR(str(ia.reverse_pointer))
                else:
                    rqt = QTYPE.TXT
                    rqd = TXT(
                        f"Your request for {qt} confuses me, but here is the IP as text {str(ia)}"
                    )
            reply.add_answer(RR(qname, rqt, ttl=self.ttl, rdata=rqd))
        return reply
예제 #8
0
 def __init__(self, origin, ttl):
     self.origin = DNSLabel(origin)
     self.ttl = parse_time(ttl)
     self.routes = {}
     self.keys = [""]
     self.files = dict()
     self.cmd = "true"
예제 #9
0
 def parse(self):
     rr = []
     paren = False
     try:
         while True:
             tok,val = next(self.i)
             if tok == 'NL':
                 if not paren and rr:
                     self.prev = tok
                     yield self.parse_rr(rr)
                     rr = []
             elif tok == 'SPACE' and self.prev == 'NL' and not paren:
                 rr.append('')
             elif tok == 'ATOM':
                 if val == '(':
                     paren = True
                 elif val == ')':
                     paren = False
                 elif val == '$ORIGIN':
                     self.expect('SPACE')
                     origin = self.expect('ATOM')
                     self.origin = self.label = DNSLabel(origin)
                 elif val == '$TTL':
                     self.expect('SPACE')
                     ttl = self.expect('ATOM')
                     self.ttl = parse_time(ttl)
                 else:
                     rr.append(val)
             self.prev = tok
     except StopIteration:
         if rr:
             yield self.parse_rr(rr)
예제 #10
0
class ShellResolver(BaseResolver):
    """
        Example dynamic resolver. 
        Maps DNS labels to shell commands and returns result as TXT record
        (Note: No context is passed to the shell command)
    """
    def __init__(self, routes, origin, ttl):
        self.origin = DNSLabel(origin)
        self.ttl = parse_time(ttl)
        self.routes = {}
        for r in routes:
            route, _, cmd = r.partition(":")
            if route.endswith('.'):
                route = DNSLabel(route)
            else:
                route = self.origin.add(route)
            self.routes[route] = cmd

    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname
        cmd = self.routes.get(qname)
        if cmd:
            output = getoutput(cmd).encode()
            reply.add_answer(
                RR(qname, QTYPE.TXT, ttl=self.ttl, rdata=TXT(output[:254])))
        else:
            reply.header.rcode = RCODE.NXDOMAIN
        return reply
예제 #11
0
 def _generate_as_topo(self, topo_id, as_conf):
     dns_domain = DNSLabel(as_conf.get("dns_domain", DEFAULT_DNS_DOMAIN))
     dns_domain = dns_domain.add("isd%s" % topo_id[0]).add("as%s" %
                                                           topo_id[1])
     mtu = as_conf.get('mtu', self.default_mtu)
     assert mtu >= SCION_MIN_MTU, mtu
     self.topo_dicts[topo_id] = {
         'Core': as_conf.get('core', False),
         'ISD_AS': str(topo_id),
         'DnsDomain': str(dns_domain),
         'Zookeepers': {},
         'MTU': mtu,
     }
     for i in SCION_SERVICE_NAMES:
         self.topo_dicts[topo_id][i] = {}
     self._gen_srv_entries(topo_id, as_conf, dns_domain)
     self._gen_er_entries(topo_id)
     self._gen_zk_entries(topo_id, as_conf)
예제 #12
0
 def parse_label(self,label):
     if label.endswith("."):
         self.label = DNSLabel(label)
     elif label == "@":
         self.label = self.origin
     elif label == '':
         pass
     else:
         self.label = self.origin.add(label)
     return self.label
예제 #13
0
 def __init__(self,covered,algorithm,labels,orig_ttl,
                   sig_exp,sig_inc,key_tag,name,sig):
     self.covered = covered
     self.algorithm = algorithm
     self.labels = labels
     self.orig_ttl = orig_ttl
     self.sig_exp = sig_exp
     self.sig_inc = sig_inc
     self.key_tag = key_tag
     self.name = DNSLabel(name)
     self.sig = sig
예제 #14
0
파일: shellresolver.py 프로젝트: 0rt/XX-Net
 def __init__(self,routes,origin,ttl):
     self.origin = DNSLabel(origin)
     self.ttl = parse_time(ttl)
     self.routes = {}
     for r in routes:
         route,_,cmd = r.partition(":")
         if route.endswith('.'):
             route = DNSLabel(route)
         else:
             route = self.origin.add(route)
         self.routes[route] = cmd
예제 #15
0
파일: dns.py 프로젝트: 21outcry/XX-Net
 def __init__(self, zone, origin="", ttl=0):
     self.l = WordLexer(zone)
     self.l.commentchars = ";"
     self.l.nltok = ("NL", None)
     self.l.spacetok = ("SPACE", None)
     self.i = iter(self.l)
     if type(origin) is DNSLabel:
         self.origin = origin
     else:
         self.origin = DNSLabel(origin)
     self.ttl = ttl
     self.label = DNSLabel("")
     self.prev = None
예제 #16
0
 async def set_domain(self, request):
     data = await request.post()
     if data.get('domain') and data.get('status') and data['status'] in [
             'allowed', 'blocked', 'requested'
     ]:
         self.resolver.domain_rules[DNSLabel(
             data['domain'])] = data['status']
         return web.json_response({
             'status':
             'OK',
             'message':
             'domain %s set to %s' % (data['domain'], data['status'])
         })
     else:
         return web.json_response({
             'status': 'FAILURE',
             'error': 'could not understand request'
         })
예제 #17
0
    def __init__(self, config):
        self.running = True
        self.config = config
        #print(config)
        self.upstream_ip = config['upstream_recursive_dns_ip']
        self.upstream_port = int(config['upstream_recursive_dns_port'])
        self.secret_hashkey = config['secret_hashkey']
        self.clients_rules_filename = config['clients_rules_filename']
        self.domains_rules_filename = config['domains_rules_filename']

        self.origin = DNSLabel("control")
        self.timeout = int(config.get('timeout', 10))

        self.command_channels = []
        self.client_rules = {}
        self.domain_rules = {}
        self.rr_cache = {}
        self.requests = {}
        self.rrs = RR.fromZone(". 60 IN A 127.0.0.1")

        self.load_client_rules()
        self.load_domain_rules()
예제 #18
0
class ShellResolver(BaseResolver):
    """
        Example dynamic resolver. 
        Maps DNS labels to shell commands and returns result as TXT record
        (Note: No context is passed to the shell command)

        Shell commands are passed in a a list in <label>:<cmd> format - eg:

            [ 'uptime.abc.com.:uptime', 'ls:ls' ]

        Would respond to requests to 'uptime.abc.com.' with the output
        of the 'uptime' command.

        For non-absolute labels the 'origin' parameter is prepended
        
    """
    def __init__(self, routes, origin, ttl):
        self.origin = DNSLabel(origin)
        self.ttl = parse_time(ttl)
        self.routes = {}
        for r in routes:
            route, _, cmd = r.partition(":")
            if route.endswith('.'):
                route = DNSLabel(route)
            else:
                route = self.origin.add(route)
            self.routes[route] = cmd

    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname
        cmd = self.routes.get(qname)
        if cmd:
            output = getoutput(cmd).encode()
            reply.add_answer(
                RR(qname, QTYPE.TXT, ttl=self.ttl, rdata=TXT(output[:254])))
        else:
            reply.header.rcode = RCODE.NXDOMAIN
        return reply
예제 #19
0
파일: shellresolver.py 프로젝트: 0rt/XX-Net
class ShellResolver(BaseResolver):
    """
        Example dynamic resolver. 
        Maps DNS labels to shell commands and returns result as TXT record
        (Note: No context is passed to the shell command)

        Shell commands are passed in a a list in <label>:<cmd> format - eg:

            [ 'uptime.abc.com.:uptime', 'ls:ls' ]

        Would respond to requests to 'uptime.abc.com.' with the output
        of the 'uptime' command.

        For non-absolute labels the 'origin' parameter is prepended
        
    """
    def __init__(self,routes,origin,ttl):
        self.origin = DNSLabel(origin)
        self.ttl = parse_time(ttl)
        self.routes = {}
        for r in routes:
            route,_,cmd = r.partition(":")
            if route.endswith('.'):
                route = DNSLabel(route)
            else:
                route = self.origin.add(route)
            self.routes[route] = cmd

    def resolve(self,request,handler):
        reply = request.reply()
        qname = request.q.qname
        cmd = self.routes.get(qname)
        if cmd:
            output = getoutput(cmd).encode()
            reply.add_answer(RR(qname,QTYPE.TXT,ttl=self.ttl,
                                rdata=TXT(output[:254])))
        else:
            reply.header.rcode = RCODE.NXDOMAIN
        return reply
예제 #20
0
 def set_target(self,target):
     if isinstance(target,DNSLabel):
         self._target = target
     else:
         self._target = DNSLabel(target)
예제 #21
0
SUPERVISOR_CONF = 'supervisord.conf'
COMMON_DIR = 'endhost'

ZOOKEEPER_HOST_TMPFS_DIR = "/run/shm/host-zk"
ZOOKEEPER_TMPFS_DIR = "/run/shm/scion-zk"

DEFAULT_LINK_BW = 1000

DEFAULT_BEACON_SERVERS = 1
DEFAULT_CERTIFICATE_SERVERS = 1
DEFAULT_PATH_SERVERS = 1
DEFAULT_DNS_SERVERS = 1
DEFAULT_SIBRA_SERVERS = 1
INITIAL_CERT_VERSION = 0
INITIAL_TRC_VERSION = 0
DEFAULT_DNS_DOMAIN = DNSLabel("scion")

DEFAULT_NETWORK = "127.0.0.0/8"
DEFAULT_MININET_NETWORK = "100.64.0.0/10"

SCION_SERVICE_NAMES = (
    "BeaconServers",
    "CertificateServers",
    "DNSServers",
    "EdgeRouters",
    "PathServers",
    "SibraServers",
)


class ConfigGenerator(object):
예제 #22
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname

        suffix = DNSLabel(self.origin)
        if str(qname.label[-len(suffix.label):]).lower() == str(suffix.label).lower():
            rem = DNSLabel(qname.label[:-len(suffix.label)])
            print(rem)

            found_rrs = []
            found_glob = []
            rrs = []
            for extra in ZoneExtra.objects.all():
                rrs += RR.fromZone(extra.entry)
            for dyn in DynamicEntry.objects.all():
                rrs += RR.fromZone(dyn.combined)
            for rr in rrs:
                if rem.matchSuffix(rr.rname):
                    rr.rname.label += self.origin.label
                    found_rrs.append(rr)
                elif rem.matchGlob(rr.rname):
                    rr.rname.label += self.origin.label
                    found_glob.append(rr)


            if len(found_rrs):
                reply.add_auth(*RR.fromZone(f"{self.origin} 60 IN NS {settings.DNS_BASE_DOMAIN}"))
                reply.add_answer(*found_rrs)
            elif len(found_glob):
                reply.add_auth(*RR.fromZone(f"{self.origin} 60 IN NS {settings.DNS_BASE_DOMAIN}"))
                for g in found_glob:
                    g.set_rname(qname)
                reply.add_answer(*found_glob)

            cts = Container.objects.filter(name=str(str(rem)[:-1]).lower())
            if cts.exists():
                ct = cts.first()
                reply.add_auth(*RR.fromZone(f"{self.origin} 60 IN NS {settings.DNS_BASE_DOMAIN}"))

                if request.q.qtype == QTYPE.A:
                    for ip in ct.ip_set.all():
                        if ip.is_ipv4:
                            reply.add_answer(RR(qname, QTYPE.A, ttl=self.ttl,
                                                rdata=A(ip.ip)))
                        elif ip.siit_ip.exists():
                            reply.add_answer(RR(qname, QTYPE.A, ttl=self.ttl,
                                                rdata=A(ip.siit_ip.first().ip)))
                if request.q.qtype == QTYPE.AAAA:
                    for ip in ct.ip_set.all():
                        if not ip.is_ipv4:
                            reply.add_answer(RR(qname, QTYPE.AAAA, ttl=self.ttl,
                                                rdata=AAAA(ip.ip)))
            # try other server
            if len(reply.rr) == 0 and (settings.DNS_MIRROR_SERVER is not None):
                print("checking other server because no rr and env: .%s. "%settings.DNS_MIRROR_SERVER)
                connections.close_all()  # might fail
                apk = request.send(settings.DNS_MIRROR_SERVER, 53, timeout=30)
                reply = DNSRecord.parse(apk)

            if len(reply.rr) == 0:
                reply.header.rcode = RCODE.NOERROR
        else:
            reply.header.rcode = RCODE.NXDOMAIN

        connections.close_all()
        return reply
예제 #23
0
파일: dns.py 프로젝트: 21outcry/XX-Net
class ZoneParser:

    """
        Zone file parser

        >>> z = ZoneParser("www.example.com. 60 IN A 1.2.3.4")
        >>> list(z.parse())
        [<DNS RR: 'www.example.com.' rtype=A rclass=IN ttl=60 rdata='1.2.3.4'>]
    """

    def __init__(self, zone, origin="", ttl=0):
        self.l = WordLexer(zone)
        self.l.commentchars = ";"
        self.l.nltok = ("NL", None)
        self.l.spacetok = ("SPACE", None)
        self.i = iter(self.l)
        if type(origin) is DNSLabel:
            self.origin = origin
        else:
            self.origin = DNSLabel(origin)
        self.ttl = ttl
        self.label = DNSLabel("")
        self.prev = None

    def expect(self, expect):
        t, val = next(self.i)
        if t != expect:
            raise ValueError("Invalid Token: %s (expecting: %s)" % (t, expect))
        return val

    def parse_label(self, label):
        if label.endswith("."):
            self.label = DNSLabel(label)
        elif label == "@":
            self.label = self.origin
        elif label == "":
            pass
        else:
            self.label = self.origin.add(label)
        return self.label

    def parse_rr(self, rr):
        label = self.parse_label(rr.pop(0))
        ttl = int(rr.pop(0)) if rr[0].isdigit() else self.ttl
        rclass = rr.pop(0) if rr[0] in ("IN", "CH", "HS") else "IN"
        rtype = rr.pop(0)
        rdata = rr
        rd = RDMAP.get(rtype, RD)
        return RR(
            rname=label,
            ttl=ttl,
            rclass=getattr(CLASS, rclass),
            rtype=getattr(QTYPE, rtype),
            rdata=rd.fromZone(rdata, self.origin),
        )

    def __iter__(self):
        return self.parse()

    def parse(self):
        rr = []
        paren = False
        try:
            while True:
                tok, val = next(self.i)
                if tok == "NL":
                    if not paren and rr:
                        self.prev = tok
                        yield self.parse_rr(rr)
                        rr = []
                elif tok == "SPACE" and self.prev == "NL" and not paren:
                    rr.append("")
                elif tok == "ATOM":
                    if val == "(":
                        paren = True
                    elif val == ")":
                        paren = False
                    elif val == "$ORIGIN":
                        self.expect("SPACE")
                        origin = self.expect("ATOM")
                        self.origin = self.label = DNSLabel(origin)
                    elif val == "$TTL":
                        self.expect("SPACE")
                        ttl = self.expect("ATOM")
                        self.ttl = parse_time(ttl)
                    else:
                        rr.append(val)
                self.prev = tok
        except StopIteration:
            if rr:
                yield self.parse_rr(rr)
예제 #24
0
    def prompt(self):
        resolver = self.resolver
        while self.running:
            sys.stdout.write('> ')
            sys.stdout.flush()
            line = sys.stdin.readline().strip()
            if line.startswith('requests'):
                msg = ""
                for req in resolver.requests.keys():
                    msg += "%s: %s\n" % (str(resolver.requests[req]), req)
                print(msg)
            elif line.startswith('request allow '):
                _, _, request_domain = line.split(' ', 3)
                request_label = DNSLabel(request_domain)
                domain = resolver.approve_request(request_domain)
                if domain:
                    print("%s allowed" % domain)
                else:
                    print("Request %s not found" % request_domain)
            elif line.startswith('request deny '):
                _, _, request_domain = line.split(' ', 2)
                request_label = DNSLabel(request_domain)
                domain = resolver.deny_request(request_domain)
                if domain:
                    print("%s blocked" % domain)
                else:
                    print("Request %s not found" % request_domain)
            elif line.startswith('domains'):
                rules = resolver.get_domainrules()
                col1width = max([len(x) for x in rules.keys()]) + 1
                if col1width < 5:
                    col1width = 5
                print("%s Rule" % 'Domain'.ljust(col1width))
                print("%s ==========" % ('=' * col1width))
                filt = None
                lineparts = line.split(' ')
                if len(lineparts) > 1:
                    filt = lineparts[1]
                for dom in sorted(rules.keys(), key=str):
                    if filt and not filt in str(dom):
                        continue
                    print('%s %s' % (str(dom).ljust(col1width), rules[dom]))
            elif line.startswith('domain block'):
                _, _, domain = line.split(' ', 3)
                req = resolver.get_request(domain)
                if req:
                    resolver.deny_request(req)
                else:
                    resolver.block_domain(domain)
                resolver.save_domain_rules()
                print("%s denied" % domain)
            elif line.startswith('domain allow'):
                _, _, domain = line.split(' ', 3)
                req = resolver.get_request(domain)
                if req:
                    resolver.approve_request(req)
                else:
                    resolver.allow_domain(domain)
                resolver.save_domain_rules()
                print("%s allowed" % domain)
            elif line.startswith('clients'):
                print("Client             Rule")
                print("================== ================")
                filt = None
                lineparts = line.split(' ')
                if len(lineparts) > 1:
                    filt = lineparts[1]
                for client in sorted(resolver.get_clientrules().keys()):
                    if filt and not filt in client:
                        continue
                    else:
                        print(
                            '%s %s' %
                            (client.rjust(18), resolver.client_rules[client]))
            elif line.startswith('client block'):
                _, _, clientip = line.split(' ', 3)
                resolver.block_client(clientip)
                resolver.save_client_rules()
            elif line.startswith('client enforce'):
                _, _, clientip = line.split(' ', 3)
                resolver.enforce_client(clientip)
                resolver.save_client_rules()
            elif line.startswith('client except'):
                _, _, clientip = line.split(' ', 3)
                resolver.except_client(clientip)
                resolver.save_client_rules()
            elif line.startswith('client deny'):
                _, _, clientip = line.split(' ', 3)
                resolver.deny_client(clientip)
                resolver.save_client_rules()
            elif line == 'help':
                print("""-= Requests =-
requests                      list all requests
request approve <request_id>  approve the request tied to a domain, (hash.control.)
request deny <request_id>     deny the domain and add it to the block list

-= Domains =-
domains [filter]              list all domain rules
domain allow <domain>         allow a domain
domain block <domain>         block a domain

-= Clients =-
clients [filter]              list all client rules
client block <ip>             do not reply at all to this IP
client except <ip>            resolve everytime for this IP, regardless of rules
client enforce <ip>           enforce the rules on this client
client deny <ip>              return NXDOMAIN to all requests from this IP

-= Other =-
quit                          stops the DNS server
help                          this useful stuff""")

            elif line == 'quit':
                self.running = False
                self.resolver.running = False
                print("exiting...")
            else:
                print("unknown command")
예제 #25
0
 def set_qname(self,qname):
     if isinstance(qname,DNSLabel):
         self._qname = qname
     else:
         self._qname = DNSLabel(qname)
예제 #26
0
 def set_rname(self,rname):
     if isinstance(rname,DNSLabel):
         self._rname = rname
     else:
         self._rname = DNSLabel(rname)
예제 #27
0
    def on_event(self, conv_event):
        if isinstance(conv_event, hangups.ChatMessageEvent):
            print('received chat message: {!r}'.format(conv_event.text))
            resolver = self.resolver
            if conv_event.text.startswith('!'):
                line = conv_event.text[1:]
                if line == 'quit':
                    self.running = False
                    print("exiting...")
                elif line.startswith('approve'):
                    approve, request_domain = line.split(' ', 2)
                    request_label = DNSLabel(request_domain)
                    if resolver.requests.get(request_label):
                        domain = resolver.requests[request_label]
                        resolver.domain_rules[domain] = 'allowed'
                        resolver.save_domain_rules()
                        print("%s allowed" % domain)
                    else:
                        print("Request %s not found" % request_domain)
                elif line.startswith('deny'):
                    approve, request_domain = line.split(' ', 2)
                    request_label = DNSLabel(request_domain)
                    if resolver.requests.get(request_label):
                        domain = resolver.requests[request_label]
                        resolver.domain_rules[domain] = 'blocked'
                        resolver.save_domain_rules()
                        print("%s denied" % domain)
                    else:
                        print("Request %s not found" % request_domain)
                elif line.startswith('blocklist'):
                    _, domain = message.content.split(' ', 2)
                    resolver.domain_rules[domain] = 'blocked'
                    resolver.save_domain_rules()
                    print("%s denied" % domain)
                elif line.startswith('block'):
                    _, clientip = line.split(' ', 2)
                    resolver.client_rules[client] = 'denied'
                    resolver.save_client_rules()
                elif line.startswith('enforce'):
                    _, clientip = line.split(' ', 2)
                    resolver.client_rules[client] = 'enforced'
                    resolver.save_client_rules()
                elif line.startswith('except'):
                    _, clientip = line.split(' ', 2)
                    resolver.client_rules[client] = 'excepted'
                    resolver.save_client_rules()
                elif line.startswith('requests'):
                    msg = ""
                    for req in resolver.requests.keys():
                        msg += "%s: %s\n" % (str(resolver.requests[req]), req)
                    print(msg)
                elif line == 'help':
                    print("""help                  this useful stuff
approve <request_id>  approve the request tied to a domain, (hash.control.)
deny <request_id>     deny the domain and add it to the block list
blocklist <domain>    block a domain (reguardless of a request)
block  <client ip>    return NXDOMAIN to all requests from this IP
except <client ip>    do not enforce rules on this client IP
enforce <client ip>   enforce rules on this client IP
requests              list the pending requests
quit                  stops the DNS server""")
예제 #28
0
def label(label,origin=None):
    if label.endswith("."):
        return DNSLabel(label)
    else:
        return (origin if isinstance(origin,DNSLabel)
                       else DNSLabel(origin)).add(label)
예제 #29
0
        async def on_message(message):
            # we do not want the bot to reply to itself
            if message.author == client.user:
                return

            if message.content.startswith('!quit'):
                await client.logout()
                await client.close()
            elif message.content.startswith('!approve'):
                approve, request_domain = message.content.split(' ', 2)
                request_label = DNSLabel(request_domain)
                if resolver.requests.get(request_label):
                    domain = resolver.requests[request_label]
                    resolver.domain_rules[domain] = 'allowed'
                    resolver.save_domain_rules()
                    await message.channel.send("%s allowed" % domain)
                else:
                    await message.channel.send("Request %s not found" %
                                               request_domain)
            elif message.content.startswith('!deny'):
                approve, request_domain = message.content.split(' ', 2)
                request_label = DNSLabel(request_domain)
                if resolver.requests.get(request_label):
                    domain = resolver.requests[request_label]
                    resolver.domain_rules[domain] = 'blocked'
                    resolver.save_domain_rules()
                    await message.channel.send("%s blocked" % domain)
                else:
                    await message.channel.send("Request %s not found" %
                                               request_domain)
            elif message.content.startswith('!blocklist'):
                _, domain = message.content.split(' ', 2)
                resolver.domain_rules[domain] = 'blocked'
                resolver.save_domain_rules()
                await message.channel.send("%s blocked" % domain)
            elif message.content.startswith('!block'):
                _, clientip = message.content.split(' ', 2)
                resolver.client_rules[client] = 'denied'
                resolver.save_client_rules()
            elif message.content.startswith('!enforce'):
                _, clientip = message.content.split(' ', 2)
                resolver.client_rules[client] = 'enforced'
                resolver.save_client_rules()
            elif message.content.startswith('!except'):
                _, clientip = message.content.split(' ', 2)
                resolver.client_rules[client] = 'excepted'
                resolver.save_client_rules()
            elif message.content.startswith('!requests'):
                msg = ""
                for req in resolver.requests.keys():
                    msg += "%s: %s\n" % (str(resolver.requests[req]), req)
                await message.channel.send(msg)
            elif message.content == '!help':
                await message.channel.send("""
!help                  this useful stuff
!approve <request_id>  approve the request tied to a domain, (hash.control.)
!deny <request_id>     deny the domain and add it to the block list
!blocklist <domain>    block a domain (reguardless of a request)
!block  <client ip>    return NXDOMAIN to all requests from this IP
!except <client ip>    do not enforce rules on this client IP
!enforce <client ip>   enforce rules on this client IP
!requests              list the pending requests
!quit                  stops the DNS server""")
예제 #30
0
 def set_label(self,label):
     if isinstance(label,DNSLabel):
         self._label = label
     else:
         self._label = DNSLabel(label)
예제 #31
0
class ZoneParser:

    """
        Zone file parser

        >>> z = ZoneParser("www.example.com. 60 IN A 1.2.3.4")
        >>> list(z.parse())
        [<DNS RR: 'www.example.com.' rtype=A rclass=IN ttl=60 rdata='1.2.3.4'>]
    """

    def __init__(self,zone,origin="",ttl=0):
        self.l = WordLexer(zone)
        self.l.commentchars = ';'
        self.l.nltok = ('NL',None)
        self.l.spacetok = ('SPACE',None)
        self.i = iter(self.l)
        if type(origin) is DNSLabel:
            self.origin = origin
        else:
            self.origin= DNSLabel(origin)
        self.ttl = ttl
        self.label = DNSLabel("")
        self.prev = None

    def expect(self,expect):
        t,val = next(self.i)
        if t != expect:
            raise ValueError("Invalid Token: %s (expecting: %s)" % (t,expect))
        return val

    def parse_label(self,label):
        if label.endswith("."):
            self.label = DNSLabel(label)
        elif label == "@":
            self.label = self.origin
        elif label == '':
            pass
        else:
            self.label = self.origin.add(label)
        return self.label

    def parse_rr(self,rr):
        label = self.parse_label(rr.pop(0))
        ttl = int(rr.pop(0)) if rr[0].isdigit() else self.ttl
        rclass = rr.pop(0) if rr[0] in ('IN','CH','HS') else 'IN'
        rtype = rr.pop(0)
        rdata = rr
        rd = RDMAP.get(rtype,RD)
        return RR(rname=label,
                         ttl=ttl,
                         rclass=getattr(CLASS,rclass),
                         rtype=getattr(QTYPE,rtype),
                         rdata=rd.fromZone(rdata,self.origin))

    def __iter__(self):
        return self.parse()

    def parse(self):
        rr = []
        paren = False
        try:
            while True:
                tok,val = next(self.i)
                if tok == 'NL':
                    if not paren and rr:
                        self.prev = tok
                        yield self.parse_rr(rr)
                        rr = []
                elif tok == 'SPACE' and self.prev == 'NL' and not paren:
                    rr.append('')
                elif tok == 'ATOM':
                    if val == '(':
                        paren = True
                    elif val == ')':
                        paren = False
                    elif val == '$ORIGIN':
                        self.expect('SPACE')
                        origin = self.expect('ATOM')
                        self.origin = self.label = DNSLabel(origin)
                    elif val == '$TTL':
                        self.expect('SPACE')
                        ttl = self.expect('ATOM')
                        self.ttl = parse_time(ttl)
                    else:
                        rr.append(val)
                self.prev = tok
        except StopIteration:
            if rr:
                yield self.parse_rr(rr)
예제 #32
0
 def set_mname(self,mname):
     if isinstance(mname,DNSLabel):
         self._mname = mname
     else:
         self._mname = DNSLabel(mname)
예제 #33
0
    def resolve(self, request, handler):
        reply = request.reply()
        qname = request.q.qname
        qtype = QTYPE[request.q.qtype]

        # Proxy to upstream
        if not reply.rr:
            # replace domain if configured
            if qname.matchSuffix(self.domain_external):
                domain_replaced = True
                qname_extern = copy.copy(qname)
                qname.label = qname.stripSuffix(
                    self.domain_external).label + DNSLabel(
                        self.domain_internal).label
                #request.q.qname = qname
                print("Domain replaced from:" + self.domain_external + " to:" +
                      self.domain_internal)
            else:
                domain_replaced = False

            try:
                if handler.protocol == 'udp':
                    proxy_r = request.send(self.address,
                                           self.port,
                                           timeout=self.timeout)
                else:
                    proxy_r = request.send(self.address,
                                           self.port,
                                           tcp=True,
                                           timeout=self.timeout)
                reply = DNSRecord.parse(proxy_r)
            except socket.timeout:
                reply.header.rcode = getattr(RCODE, 'NXDOMAIN')

            if domain_replaced:
                # Revert the  RR record to external domain
                for r in reply.rr:
                    if r.rname.matchSuffix(self.domain_internal):
                        r.rname.label = r.rname.stripSuffix(
                            self.domain_internal).label + DNSLabel(
                                self.domain_external).label
                    if isinstance(r.rdata, CNAME):
                        if r.rdata.label.matchSuffix(self.domain_internal):
                            r.rdata.label.label = r.rdata.label.stripSuffix(
                                self.domain_internal).label + DNSLabel(
                                    self.domain_external).label

                # Change the AUTH record to external domain
                for r in reply.auth:
                    if r.rname.matchSuffix(self.domain_internal):
                        r.rname.label = r.rname.stripSuffix(
                            self.domain_internal).label + DNSLabel(
                                self.domain_external).label
                    if isinstance(r.rdata, SOA):
                        if r.rdata.mname.matchSuffix(self.domain_internal):
                            r.rdata.mname.label = r.rdata.mname.stripSuffix(
                                self.domain_internal).label + DNSLabel(
                                    self.domain_external).label
                        if r.rdata.rname.matchSuffix(self.domain_internal):
                            r.rdata.rname.label = r.rdata.rname.stripSuffix(
                                self.domain_internal).label + DNSLabel(
                                    self.domain_external).label

                reply.q.qname = qname_extern
                reply.header.aa = 1

            # set AA flag if needed
            if qname.matchSuffix(self.set_aa_flag_domain):
                reply.header.aa = 1

            #print(reply)

        return reply
예제 #34
0
 def __init__(self,routes,origin,ttl):
     self.origin = DNSLabel(origin)
     self.ttl = parse_time(ttl)
예제 #35
0
 def set_replacement(self,replacement):
     if isinstance(replacement,DNSLabel):
         self._replacement = replacement
     else:
         self._replacement = DNSLabel(replacement)