예제 #1
0
def get_ad_users_json(container, azure_json_path):
    """Pass in the container name and path to a JSON dump of AD users, return parsed JSON.
    """
    connect_string = os.environ.get("AZURE_CONNECTION_STRING", None)
    if not connect_string:
        return None
    store = AzureBlobStorage(connect_string, container)
    return json.loads(store.get_content(azure_json_path))
    def handle(self, *args, **options):
        logger = logging.getLogger('organisation')
        logger.info('Generating diff between Ascender and on-premise AD data')
        discrepancies = ascender_onprem_ad_data_diff()
        f = NamedTemporaryFile()
        f.write(json.dumps(discrepancies, indent=4).encode('utf-8'))

        logger.info('Uploading diff JSON to Azure blob storage')
        connect_string = os.environ.get('AZURE_CONNECTION_STRING')
        store = AzureBlobStorage(connect_string, options['container'])
        store.upload_file(options['path'], f.name)

        logger.info('Completed')
예제 #3
0
    def handle(self, *args, **options):
        logger = logging.getLogger('organisation')
        logger.info(
            'Generating discrepancies between department user and Ascender data'
        )
        users = DepartmentUser.objects.all()
        spreadsheet = department_user_ascender_discrepancies(BytesIO(), users)
        f = NamedTemporaryFile()
        f.write(spreadsheet.getbuffer())

        logger.info('Uploading discrepancies to Azure blob storage')
        connect_string = os.environ.get('AZURE_CONNECTION_STRING')
        store = AzureBlobStorage(connect_string, options['container'])
        store.upload_file(options['path'], f.name)

        logger.info('Completed')
예제 #4
0
class TestResourceRepositoryClient(TestResourceRepositoryClientMixin,
                                   unittest.TestCase):
    storage = AzureBlobStorage(settings.AZURE_CONNECTION_STRING,
                               settings.AZURE_CONTAINER)

    resource_base_path = "resourcerepository"

    def create_resource_repository(self):
        return ResourceRepository(self.storage,
                                  self.resource_name,
                                  resource_base_path=self.resource_base_path,
                                  archive=self.archive,
                                  metaname="metadata",
                                  cache=self.cache,
                                  logical_delete=self.logical_delete)

    def populate_test_datas(self):
        resource_ids = [("/test/2018_05_02_test2.txt", ),
                        ("test2/2019_06_02_test4.txt", ),
                        ("2018_05_01_test1.txt", ),
                        ("test/2020_07_01_test5.txt", ),
                        ("test/2019_06_01_test3.txt", ),
                        ("test2/2020_07_02_test6.txt", )]
        testdatas = {}
        for resource_id in resource_ids:
            testdatas[resource_id] = self.populate_test_data(resource_id)

        return testdatas
예제 #5
0
def host_dependencies():
    # Download the list of Nginx host proxy targets.
    connect_string = env('AZURE_CONNECTION_STRING')
    store = AzureBlobStorage(connect_string, 'analytics')
    store.download('nginx_host_proxy_targets.json',
                   '/tmp/nginx_host_proxy_targets.json')
    f = open('/tmp/nginx_host_proxy_targets.json')
    targets = json.loads(f.read())
    host_ct = ContentType.objects.get(app_label='status', model='host')

    # Production / Production (legacy) systems only.
    for it in ITSystem.objects.filter(link__isnull=False,
                                      status__in=[0, 2]).exclude(link=''):
        # Remove any existing IT System Host dependencies.
        for dep in it.dependencies.filter(content_type=host_ct):
            it.dependencies.remove(dep)

        if it.extra_data is None:
            it.extra_data = {}
            it.save()
            continue

        if 'url_synonyms' not in it.extra_data or not it.extra_data[
                'url_synonyms']:
            # Skip this IT System (no known URL or synonyms).
            continue

        # Create/update Host dependencies for IT systems as 'proxy targets'.
        target = None
        for syn in it.extra_data['url_synonyms']:
            for t in targets:
                if syn == t['host']:
                    target = t
                    break
            if target:
                for p in target["proxy_pass"]:
                    u = urlparse(p)
                    host = u.netloc.split(':')[0]
                    if Host.objects.filter(name=host).exists():
                        h = Host.objects.filter(name=host).first()
                        host_dep, created = Dependency.objects.get_or_create(
                            content_type=host_ct,
                            object_id=h.pk,
                            category='Proxy target',
                        )
                        # Add the dependency to the IT System.
                        it.dependencies.add(host_dep)
예제 #6
0
def get_resource_consume_client():
    """
    Return the blob resource client
    """
    global _resource_consume_client
    if _resource_consume_client is None:
        _resource_consume_client = ResourceConsumeClient(
            AzureBlobStorage(settings.NGINX_STORAGE_CONNECTION_STRING,
                             settings.NGINX_CONTAINER),
            settings.NGINX_RESOURCE_NAME, settings.RESOURCE_CLIENTID)
    return _resource_consume_client
예제 #7
0
def get_blob_resource(reuse=True):
    """
    Return the blob resource client
    """
    global _blob_resource
    if _blob_resource is None or not reuse:
        _blob_resource = ResourceRepository(AzureBlobStorage(
            settings.AZURE_CONNECTION_STRING, settings.AZURE_CONTAINER),
                                            settings.RESOURCE_NAME,
                                            archive=False)
    return _blob_resource
예제 #8
0
def get_resource_repository():
    """
    Return the blob resource client
    """
    global _resource_repository
    if _resource_repository is None:
        _resource_repository = GroupResourceRepository(
            AzureBlobStorage(settings.AZURE_CONNECTION_STRING,settings.AZURE_CONTAINER),
            settings.DOCKER_RESOURCE_NAME,
            archive=False
        )
    return _resource_repository
예제 #9
0
def signal_sciences_feed_csv(feed_str, corp_name, timestamp, upload=True):
    """For a given passed-in Signal Sciences feed string, summarise it to a CSV for analysis.
    Upload the CSV to Azure blob storage.
    """
    filename = 'sigsci_request_tags_{}_{}.csv'.format(corp_name, timestamp)
    tf = open('/tmp/{}'.format(filename), 'w')
    writer = csv.writer(tf)
    feed_json = json.loads(feed_str)

    for entry in feed_json:
        for tag in entry['tags']:
            writer.writerow(
                [entry['timestamp'], entry['serverName'], tag['type']])

    tf.close()

    if upload:
        connect_string = env('AZURE_CONNECTION_STRING')
        store = AzureBlobStorage(connect_string, 'http-requests-tagged')
        store.upload_file(filename, tf.name)

    return
예제 #10
0
def signal_sciences_upload_feed(from_datetime=None,
                                minutes=None,
                                compress=False,
                                upload=True,
                                csv=False):
    """For the given datetime and duration, download the Signal Sciences feed and upload the data
    to Azure blob storage (optionally compress the file using gzip).
    Optionally also upload a CSV summary of tagged requests to blob storage.
    """
    if not from_datetime or not minutes:
        return False
    feed_str = signal_sciences_extract_feed(from_datetime, minutes)
    corp_name = env('SIGSCI_CORP_NAME', 'dbca')

    if upload and csv:
        signal_sciences_feed_csv(feed_str, corp_name,
                                 from_datetime.isoformat())

    if compress:
        # Conditionally gzip the file.
        filename = 'sigsci_feed_{}_{}.json.gz'.format(
            corp_name, from_datetime.strftime('%Y-%m-%dT%H%M%S'))
        tf = gzip.open('/tmp/{}'.format(filename), 'wb')
        tf.write(feed_str.encode('utf-8'))
    else:
        filename = 'sigsci_feed_{}_{}.json'.format(
            corp_name, from_datetime.strftime('%Y-%m-%dT%H%M%S'))
        tf = open('/tmp/{}'.format(filename), 'w')
        tf.write(feed_str)
    tf.close()

    if upload:
        # Upload the returned feed data to blob storage.
        connect_string = env('AZURE_CONNECTION_STRING')
        store = AzureBlobStorage(connect_string, 'signalsciences')
        store.upload_file(filename, tf.name)

    return filename
예제 #11
0
def get_resource_repository():
    """
    Return the blob resource client
    """
    global _resource_repository
    if _resource_repository is None:
        _resource_repository = IndexedGroupResourceRepository(
            AzureBlobStorage(settings.AZURE_CONNECTION_STRING,
                             settings.AZURE_CONTAINER),
            settings.LOGGEDPOINT_RESOURCE_NAME,
            get_metaname,
            archive=False,
            index_metaname=index_metaname)
    return _resource_repository
예제 #12
0
def get_blob_resource(reuse=True):
    """
    Return the blob resource client
    """
    global _blob_resource
    if _blob_resource is None or not reuse:
        _blob_resource = ResourceRepository(
            AzureBlobStorage(settings.AZURE_CONNECTION_STRING,
                             settings.AZURE_CONTAINER),
            settings.RESOURCE_NAME,
            archive=False,
            resource_base_path="{}/{}".format(settings.RESOURCE_NAME,
                                              settings.RANCHER_CLUSTER),
            logical_delete=True)
    return _blob_resource
class TestResourceRepository(TestResourceRepositoryMixin, unittest.TestCase):
    storage = AzureBlobStorage(settings.AZURE_CONNECTION_STRING,
                               settings.AZURE_CONTAINER)
    resource_base_path = "resourcerepository"

    def create_resource_repository(self):
        return ResourceRepository(self.storage,
                                  self.resource_name,
                                  resource_base_path=self.resource_base_path,
                                  archive=self.archive,
                                  metaname="metadata",
                                  cache=self.cache,
                                  logical_delete=self.logical_delete)

    def get_test_data_keys(self):
        return [("/test/2018_05_02_test2.txt", ),
                ("test2/2019_06_02_test4.txt", ), ("2018_05_01_test1.txt", ),
                ("test/2020_07_01_test5.txt", ),
                ("test/2019_06_01_test3.txt", ),
                ("test2/2020_07_02_test6.txt", )]
예제 #14
0
def itsystem_risks_traffic(it_systems=None):
    """Set automatic risk assessment for IT system web apps based on the mean of daily HTTP requests.
    """
    if not it_systems:
        it_systems = ITSystem.objects.all()
    # Download the report of HTTP requests.
    connect_string = env('AZURE_CONNECTION_STRING')
    store = AzureBlobStorage(connect_string, 'analytics')
    store.download('host_requests_7_day_count.csv',
                   '/tmp/host_requests_7_day_count.csv')
    counts = csv.reader(open('/tmp/host_requests_7_day_count.csv'))
    next(counts)  # Skip the header.
    report = {}
    for row in counts:
        try:
            report[row[0]] = int(row[1])
        except:
            # Sometimes the report contains junk rows; just ignore these.
            pass
    itsystem_ct = ContentType.objects.get(app_label='registers',
                                          model='itsystem')

    for it in it_systems:
        # First, check if an auto assessment has been created OR if not assessment exists.
        # If so, carry on. If not, skip automated assessment (assumes that a manual assessment exists,
        # which we don't want to overwrite).
        if (RiskAssessment.objects.filter(
                content_type=itsystem_ct,
                object_id=it.pk,
                category='Traffic',
                notes__contains='[AUTOMATED ASSESSMENT]').exists()
                or not RiskAssessment.objects.filter(
                    content_type=itsystem_ct,
                    object_id=it.pk,
                    category='Traffic').exists()):
            if 'url_synonyms' not in it.extra_data or not it.extra_data[
                    'url_synonyms']:
                # Skip this IT System (no known URL or synonyms).
                continue

            # Get/create a Traffic risk
            risk = RiskAssessment.objects.filter(content_type=itsystem_ct,
                                                 object_id=it.pk,
                                                 category='Traffic').first()
            if not risk:
                risk = RiskAssessment(content_type=itsystem_ct,
                                      object_id=it.pk,
                                      category='Traffic')

            # Total the count of HTTP requests to all URI synonyms for this system.
            request_count = 0
            for syn in it.extra_data['url_synonyms']:
                if syn in report and report[syn]:
                    request_count += report[syn]

            requests_mean = request_count / 7  # Daily average request count.
            if requests_mean:
                risk = RiskAssessment.objects.filter(
                    content_type=itsystem_ct,
                    object_id=it.pk,
                    category='Traffic').first()
                if not risk:
                    risk = RiskAssessment(content_type=itsystem_ct,
                                          object_id=it.pk,
                                          category='Traffic')
                if requests_mean >= 10000:
                    risk.rating = 3
                    risk.notes = '[AUTOMATED ASSESSMENT] High traffic of daily HTTP requests'
                elif requests_mean >= 1000:
                    risk.rating = 2
                    risk.notes = '[AUTOMATED ASSESSMENT] Moderate traffic of daily HTTP requests'
                elif requests_mean >= 100:
                    risk.rating = 1
                    risk.notes = '[AUTOMATED ASSESSMENT] Low traffic of daily HTTP requests'
                else:
                    risk.rating = 0
                    risk.notes = '[AUTOMATED ASSESSMENT] Minimal traffic of daily HTTP requests'
                risk.save()
            else:  # Volume of HTTP traffic is too small to assess.
                # If any Traffic risk exists, delete it.
                if RiskAssessment.objects.filter(content_type=itsystem_ct,
                                                 object_id=it.pk,
                                                 category='Traffic').exists():
                    risk = RiskAssessment.objects.filter(
                        content_type=itsystem_ct,
                        object_id=it.pk,
                        category='Traffic').first()
                    risk.delete()
예제 #15
0
def itsystem_risks_access(it_systems=None):
    """Set automatic risk assessment for IT system web apps based on whether they require SSO on the root location.
    """
    if not it_systems:
        it_systems = ITSystem.objects.all()

    # Download the list of Nginx host proxy targets.
    connect_string = env('AZURE_CONNECTION_STRING')
    store = AzureBlobStorage(connect_string, 'analytics')
    store.download('nginx_host_proxy_targets.json',
                   '/tmp/nginx_host_proxy_targets.json')
    f = open('/tmp/nginx_host_proxy_targets.json')
    targets = json.loads(f.read())
    itsystem_ct = ContentType.objects.get(app_label='registers',
                                          model='itsystem')

    for it in it_systems:
        # First, check if an auto assessment has been created OR if no assessment exists.
        # If so, carry on. If not, skip automated assessment (assumes that a manual assessment exists,
        # which we don't want to overwrite).
        if (RiskAssessment.objects.filter(
                content_type=itsystem_ct,
                object_id=it.pk,
                category='Access',
                notes__contains='[AUTOMATED ASSESSMENT]').exists() or
                not RiskAssessment.objects.filter(content_type=itsystem_ct,
                                                  object_id=it.pk,
                                                  category='Access').exists()):
            if 'url_synonyms' not in it.extra_data or not it.extra_data[
                    'url_synonyms']:
                # Skip this IT System (no known URL or synonyms).
                continue

            target = None

            # Get/create an access risk
            risk = RiskAssessment.objects.filter(content_type=itsystem_ct,
                                                 object_id=it.pk,
                                                 category='Access').first()
            if not risk:
                risk = RiskAssessment(content_type=itsystem_ct,
                                      object_id=it.pk,
                                      category='Access')

            for syn in it.extra_data['url_synonyms']:
                for t in targets:
                    if syn == t['host']:
                        target = t
                        break
                if target:
                    if 'sso_locations' in target:
                        if '/' in target['sso_locations'] or '^~ /' in target[
                                'sso_locations'] or '= /' in target[
                                    'sso_locations']:
                            risk.rating = 0
                            risk.notes = '[AUTOMATED ASSESSMENT] Web application root location requires SSO'
                        else:
                            risk.rating = 1
                            risk.notes = '[AUTOMATED ASSESSMENT] Web application locations configured to require SSO'
                    else:
                        if 'custom/dpaw_subnets' in target['includes']:
                            risk.rating = 1
                            risk.notes = '[AUTOMATED ASSESSMENT] Web application root location does not require SSO, but is restricted to internal subnets'
                        else:
                            risk.rating = 2
                            risk.notes = '[AUTOMATED ASSESSMENT] Web application root location does not require SSO and is not restricted to internal subnets'
                    risk.save()
                else:
                    # If any access risk exists, delete it.
                    if RiskAssessment.objects.filter(
                            content_type=itsystem_ct,
                            object_id=it.pk,
                            category='Access').exists():
                        risk = RiskAssessment.objects.filter(
                            content_type=itsystem_ct,
                            object_id=it.pk,
                            category='Access').first()
                        risk.delete()