Ejemplo n.º 1
0
    def get(self, zone_id):
        zone = DNSZone.get(zone_id)

        if not zone:
            return self.make_response(
                'Unable to find the zone requested, might have been removed',
                HTTP.NOT_FOUND)

        return self.make_response({'zone': zone.to_json()})
Ejemplo n.º 2
0
    def get(self):
        self.reqparse.add_argument('page', type=int, default=1, required=True)
        self.reqparse.add_argument('count', type=int, default=25)
        args = self.reqparse.parse_args()

        total, zones = DNSZone.search(limit=args['count'], page=args['page'])
        return self.make_response({
            'zones': [x.to_json(with_records=False) for x in zones],
            'zoneCount':
            total
        })
Ejemplo n.º 3
0
    def get(self):
        zones = DNSZone.get_all()

        output = []
        for zoneID in zones:
            zone = DNSZone.get(zoneID)
            output.append({
                'zone': zoneID,
                'data': [x.to_json() for x in zone.records]
            })

        total = len(output)
        output = [{'zones': output, 'zoneCount': total}]

        response = Response(response=b64encode(
            bytes(json.dumps(output, indent=4, cls=InquisitorJSONEncoder),
                  'utf-8')))
        response.content_type = 'application/octet-stream'
        response.status_code = HTTP.OK

        return response
Ejemplo n.º 4
0
    def get(self, zone_id):
        self.reqparse.add_argument('page', type=int, default=1, required=True)
        self.reqparse.add_argument('type', type=str, default=None)
        self.reqparse.add_argument('count', type=int, default=25)

        args = self.reqparse.parse_args()
        zone = DNSZone.get(zone_id)
        start_offset = ((args['page'] - 1) * args['count'])
        end_offset = start_offset + args['count']

        return self.make_response({
            'recordCount':
            len(zone.records),
            'records':
            zone.records[start_offset:end_offset]
        })
Ejemplo n.º 5
0
    def update_route53(self):
        """Update list of Route53 DNS Zones and their records for the account

        Returns:
            `None`
        """
        self.log.debug('Updating Route53 information for {}'.format(self.account))

        # region Update zones
        existing_zones = DNSZone.get_all(self.account)
        zones = self.__fetch_route53_zones()
        for resource_id, data in zones.items():
            if resource_id in existing_zones:
                zone = DNSZone.get(resource_id)
                if zone.update(data):
                    self.log.debug('Change detected for Route53 zone {}/{}'.format(
                        self.account,
                        zone.name
                    ))
                    zone.save()
            else:
                tags = data.pop('tags')
                DNSZone.create(
                    resource_id,
                    account_id=self.account.account_id,
                    properties=data,
                    tags=tags
                )

                self.log.debug('Added Route53 zone {}/{}'.format(
                    self.account,
                    data['name']
                ))

        db.session.commit()

        zk = set(zones.keys())
        ezk = set(existing_zones.keys())

        for resource_id in ezk - zk:
            zone = existing_zones[resource_id]

            db.session.delete(zone.resource)
            self.log.debug('Deleted Route53 zone {}/{}'.format(
                self.account.account_name,
                zone.name.value
            ))
        db.session.commit()
        # endregion

        # region Update resource records
        try:
            for zone_id, zone in DNSZone.get_all(self.account).items():
                existing_records = {rec.id: rec for rec in zone.records}
                records = self.__fetch_route53_zone_records(zone.get_property('zone_id').value)

                for data in records:
                    if data['id'] in existing_records:
                        record = existing_records[data['id']]
                        if record.update(data):
                            self.log.debug('Changed detected for DNSRecord {}/{}/{}'.format(
                                self.account,
                                zone.name,
                                data['name']
                            ))
                            record.save()
                    else:
                        record = DNSRecord.create(
                            data['id'],
                            account_id=self.account.account_id,
                            properties={k: v for k, v in data.items() if k != 'id'},
                            tags={}
                        )
                        self.log.debug('Added new DNSRecord {}/{}/{}'.format(
                            self.account,
                            zone.name,
                            data['name']
                        ))
                        zone.add_record(record)
                db.session.commit()

                rk = set(x['id'] for x in records)
                erk = set(existing_records.keys())

                for resource_id in erk - rk:
                    record = existing_records[resource_id]
                    zone.delete_record(record)
                    self.log.debug('Deleted Route53 record {}/{}/{}'.format(
                        self.account.account_name,
                        zone_id,
                        record.name
                    ))
                db.session.commit()
        except:
            raise
Ejemplo n.º 6
0
    def run(self, *args, **kwargs):
        """Update the cache of all DNS entries and perform checks

        Args:
            *args: Optional list of arguments
            **kwargs: Optional list of keyword arguments

        Returns:
            None
        """
        try:
            zones = list(DNSZone.get_all().values())
            buckets = {k.lower(): v for k, v in S3Bucket.get_all().items()}
            dists = list(CloudFrontDist.get_all().values())
            ec2_public_ips = [x.public_ip for x in EC2Instance.get_all().values() if x.public_ip]
            beanstalks = {x.cname.lower(): x for x in BeanStalk.get_all().values()}

            existing_issues = DomainHijackIssue.get_all()
            issues = []

            # List of different types of domain audits
            auditors = [
                ElasticBeanstalkAudit(beanstalks),
                S3Audit(buckets),
                S3WithoutEndpointAudit(buckets),
                EC2PublicDns(ec2_public_ips),
            ]

            # region Build list of active issues
            for zone in zones:
                for record in zone.records:
                    for auditor in auditors:
                        if auditor.match(record):
                            issues.extend(auditor.audit(record, zone))

            for dist in dists:
                for org in dist.origins:
                    if org['type'] == 's3':
                        bucket = self.return_resource_name(org['source'], 's3')

                        if bucket not in buckets:
                            key = '{} ({})'.format(bucket, dist.type)
                            issues.append({
                                'key': key,
                                'value': 'S3Bucket {} doesnt exist on any known account. Referenced by {} on {}'.format(
                                    bucket,
                                    dist.domain_name,
                                    dist.account,
                                )
                            })
            # endregion

            # region Process new, old, fixed issue lists
            old_issues = {}
            new_issues = {}
            fixed_issues = []

            for data in issues:
                issue_id = get_resource_id('dhi', ['{}={}'.format(k, v) for k, v in data.items()])

                if issue_id in existing_issues:
                    issue = existing_issues[issue_id]

                    if issue.update({'state': 'EXISTING', 'end': None}):
                        db.session.add(issue.issue)

                    old_issues[issue_id] = issue

                else:
                    properties = {
                        'issue_hash': issue_id,
                        'state': 'NEW',
                        'start': datetime.now(),
                        'end': None,
                        'source': data['key'],
                        'description': data['value']
                    }
                    new_issues[issue_id] = DomainHijackIssue.create(issue_id, properties=properties)
            db.session.commit()

            for issue in list(existing_issues.values()):
                if issue.id not in new_issues and issue.id not in old_issues:
                    fixed_issues.append(issue.to_json())
                    db.session.delete(issue.issue)
            # endregion

            # Only alert if its been more than a day since the last alert
            alert_cutoff = datetime.now() - timedelta(hours=self.alert_frequency)
            old_alerts = []
            for issue_id, issue in old_issues.items():
                if issue.last_alert and issue.last_alert < alert_cutoff:
                    if issue.update({'last_alert': datetime.now()}):
                        db.session.add(issue.issue)

                    old_alerts.append(issue)

            db.session.commit()

            self.notify(
                [x.to_json() for x in new_issues.values()],
                [x.to_json() for x in old_alerts],
                fixed_issues
            )
        finally:
            db.session.rollback()
Ejemplo n.º 7
0
    def process_zones(self, zones, account):
        self.log.info('Processing DNS records for {}'.format(
            account.account_name))

        # region Update zones
        existing_zones = DNSZone.get_all(account)
        for data in zones:
            if data['zone_id'] in existing_zones:
                zone = DNSZone.get(data['zone_id'])
                if zone.update(data):
                    self.log.debug('Change detected for DNS zone {}/{}'.format(
                        account.account_name, zone.name))
                    db.session.add(zone.resource)
            else:
                DNSZone.create(data['zone_id'],
                               account_id=account.account_id,
                               properties={
                                   k: v
                                   for k, v in data.items()
                                   if k not in ('records', 'zone_id', 'tags')
                               },
                               tags=data['tags'])

                self.log.debug('Added DNS zone {}/{}'.format(
                    account.account_name, data['name']))

        db.session.commit()

        zk = set(x['zone_id'] for x in zones)
        ezk = set(existing_zones.keys())

        for resource_id in ezk - zk:
            zone = existing_zones[resource_id]

            # Delete all the records for the zone
            for record in zone.records:
                db.session.delete(record.resource)

            db.session.delete(zone.resource)
            self.log.debug('Deleted DNS zone {}/{}'.format(
                account.account_name, zone.name.value))
        db.session.commit()
        # endregion

        # region Update resource records
        for zone in zones:
            try:
                existing_zone = DNSZone.get(zone['zone_id'])
                existing_records = {
                    rec.id: rec
                    for rec in existing_zone.records
                }

                for data in zone['records']:
                    if data['id'] in existing_records:
                        record = existing_records[data['id']]
                        if record.update(data):
                            self.log.debug(
                                'Changed detected for DNSRecord {}/{}/{}'.
                                format(account.account_name, zone.name,
                                       data['name']))
                            db.session.add(record.resource)
                    else:
                        record = DNSRecord.create(
                            data['id'],
                            account_id=account.account_id,
                            properties={
                                k: v
                                for k, v in data.items()
                                if k not in ('records', 'zone_id')
                            },
                            tags={})
                        self.log.debug('Added new DNSRecord {}/{}/{}'.format(
                            account.account_name, zone['name'], data['name']))
                        existing_zone.add_record(record)
                db.session.commit()

                rk = set(x['id'] for x in zone['records'])
                erk = set(existing_records.keys())

                for resource_id in erk - rk:
                    record = existing_records[resource_id]
                    db.session.delete(record.resource)
                    self.log.debug('Deleted DNSRecord {}/{}/{}'.format(
                        account.account_name, zone['zone_id'], record.name))
                db.session.commit()
            except:
                self.log.exception(
                    'Error while attempting to update records for {}/{}'.
                    format(
                        account.account_name,
                        zone['zone_id'],
                    ))
                db.session.rollback()