Exemplo n.º 1
0
    def test_backend_service(self):
        """Test backend_service.Key."""
        url_1 = ('https://www.googleapis.com/compute/v1/'
                 'projects/foo/global/backendServices/bar')
        url_2 = ('https://www.googleapis.com/compute/v1/'
                 'projects/foo/regions/bar/backendServices/baz')
        obj_1 = backend_service.BackendService(project_id='foo', name='bar')
        obj_2 = backend_service.BackendService(project_id='foo',
                                               region='bar',
                                               name='baz')
        key_1 = key.Key(backend_service.KEY_OBJECT_KIND, {
            'project_id': 'foo',
            'name': 'bar',
            'region': None
        })
        key_2 = key.Key(backend_service.KEY_OBJECT_KIND, {
            'project_id': 'foo',
            'name': 'baz',
            'region': 'bar'
        })
        self.assertEqual(key_1, obj_1.key)
        self.assertEqual(key_1, backend_service.Key.from_url(url_1))
        self.assertEqual(key_2, obj_2.key)
        self.assertEqual(key_2, backend_service.Key.from_url(url_2))

        url_invalid_1 = ('https://www.googleapis.com/compute/v1/'
                         'projects/foo')
        url_invalid_2 = ('https://www.googleapis.com/compute/v1/'
                         'backendServices/foo')
        self.assertRaises(ValueError, backend_service.Key.from_url,
                          url_invalid_1)
        self.assertRaises(ValueError, backend_service.Key.from_url,
                          url_invalid_2)
Exemplo n.º 2
0
 def test_direct_access_violation(self):
     rule = ire.Rule('my rule', 0, [], [], '^.*')
     resource_rule = ire.ResourceRules(self.org789,
                                       rules=set([rule]),
                                       applies_to='self_and_children')
     direct_source = 'some-tag'
     service = backend_service.BackendService(project_id=self.project1.id,
                                              name='bs1')
     iap_resource = iap_scanner.IapResource(backend_service=service,
                                            alternate_services=set(),
                                            direct_access_sources=set(
                                                [direct_source]),
                                            iap_enabled=True)
     results = list(resource_rule.find_mismatches(service, iap_resource))
     expected_violations = [
         ire.RuleViolation(resource_type='backend_service',
                           resource_name='bs1',
                           resource_id=service.resource_id,
                           rule_name=rule.rule_name,
                           rule_index=rule.rule_index,
                           violation_type='IAP_VIOLATION',
                           alternate_services_violations=[],
                           direct_access_sources_violations=[direct_source],
                           iap_enabled_violation=False),
     ]
     self.assertEquals(expected_violations, results)
Exemplo n.º 3
0
 def test_no_violations(self):
     rule = ire.Rule('my rule', 0, [], [], '^.*$')
     resource_rule = ire.ResourceRules(self.org789,
                                       rules=set([rule]),
                                       applies_to='self_and_children')
     service = backend_service.BackendService(project_id=self.project1.id,
                                              name='bs1')
     iap_resource = iap_scanner.IapResource(backend_service=service,
                                            alternate_services=set(),
                                            direct_access_sources=set(),
                                            iap_enabled=True)
     results = list(resource_rule.find_mismatches(service, iap_resource))
     self.assertEquals([], results)
Exemplo n.º 4
0
 def test_violations_iap_disabled(self):
     """If IAP is disabled, don't report other violations."""
     rule = ire.Rule('my rule', 0, [], [], '^.*')
     resource_rule = ire.ResourceRules(self.org789,
                                       rules=set([rule]),
                                       applies_to='self_and_children')
     service = backend_service.BackendService(project_id=self.project1.id,
                                              name='bs1')
     alternate_service = backend_service.Key.from_args(
         project_id=self.project1.id, name='bs2')
     iap_resource = iap_scanner.IapResource(
         backend_service=service,
         alternate_services=set([alternate_service]),
         direct_access_sources=set(['some-tag']),
         iap_enabled=False)
     results = list(resource_rule.find_mismatches(service, iap_resource))
     expected_violations = []
     self.assertEquals(expected_violations, results)
Exemplo n.º 5
0
    def setUp(self):
        self.fake_utcnow = datetime(year=1900,
                                    month=1,
                                    day=1,
                                    hour=0,
                                    minute=0,
                                    second=0,
                                    microsecond=0)

        # patch the daos
        self.org_patcher = mock.patch(
            'google.cloud.security.common.data_access.'
            'org_resource_rel_dao.OrgResourceRelDao')
        self.mock_org_rel_dao = self.org_patcher.start()
        self.mock_org_rel_dao.return_value = FakeOrgDao()

        self.project_patcher = mock.patch(
            'google.cloud.security.common.data_access.'
            'project_dao.ProjectDao')
        self.mock_project_dao = self.project_patcher.start()
        self.mock_project_dao.return_value = FakeProjectDao()

        self.fake_scanner_configs = {'output_path': 'gs://fake/output/path'}
        self.scanner = iap_scanner.IapScanner(
            {}, {}, '',
            get_datafile_path(__file__, 'iap_scanner_test_data.yaml'))
        self.scanner.scanner_configs = self.fake_scanner_configs
        self.scanner._get_backend_services = lambda: self.backend_services.values(
        )
        self.scanner._get_firewall_rules = lambda: self.firewall_rules.values()
        self.scanner._get_instances = lambda: self.instances.values()
        self.scanner._get_instance_groups = lambda: self.instance_groups.values(
        )
        self.scanner._get_instance_group_managers = lambda: self.instance_group_managers.values(
        )
        self.scanner._get_instance_templates = lambda: self.instance_templates.values(
        )

        self.backend_services = {
            # The main backend service.
            'bs1':
            backend_service_type.BackendService(
                project_id='foo',
                name='bs1',
                backends=json.dumps([
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_managed')
                    },
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_unmanaged')
                    },
                ]),
                iap=json.dumps({'enabled': True}),
                port=80,
                port_name='http',
            ),
            # Another backend service that connects to the same backend.
            'bs1_same_backend':
            backend_service_type.BackendService(
                project_id='foo',
                name='bs1_same_backend',
                backends=json.dumps([
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_managed')
                    },
                ]),
                port=80,
            ),
            # A backend service with a different port (so, not an alternate).
            'bs1_different_port':
            backend_service_type.BackendService(
                project_id='foo',
                name='bs1_different_port',
                backends=json.dumps([
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_managed')
                    },
                ]),
                port=81,
            ),
            # Various backend services that should or shouldn't be alts.
            'bs1_same_instance':
            backend_service_type.BackendService(
                project_id='foo',
                name='bs1_same_instance',
                backends=json.dumps([
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_same_instance')
                    },
                ]),
                port=80,
            ),
            'bs1_different_network':
            backend_service_type.BackendService(
                project_id='foo',
                name='bs1_different_network',
                backends=json.dumps([
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_different_network')
                    },
                ]),
                port=80,
            ),
            'bs1_different_instance':
            backend_service_type.BackendService(
                project_id='foo',
                name='bs1_different_instance',
                backends=json.dumps([
                    {
                        'group': ('https://www.googleapis.com/compute/v1/'
                                  'projects/foo/regions/wl-redqueen1/'
                                  'instanceGroups/ig_different_instance')
                    },
                ]),
                port=80,
            ),
        }
        self.firewall_rules = {
            # Doesn't apply because of IPProtocol mismatch.
            'proto_mismatch':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='proto_mismatch',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['proto_mismatch']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'udp',
                }]),
            ),
            # Preempted by allow.
            'deny_applies_all_preempted':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='deny_applies_all_preempted',
                firewall_rule_priority=60000,
                firewall_rule_network='global/networks/default',
                firewall_rule_source_ranges=json.dumps(['applies_all']),
                firewall_rule_denied=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Applies to all ports, tags.
            'applies_all':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='applies_all',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_ranges=json.dumps(['10.0.2.0/24']),
                firewall_rule_source_tags=json.dumps(['applies_all']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Applies to only port 8080.
            'applies_8080':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='applies_8080',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['applies_8080']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                    'ports': [8080],
                }]),
            ),
            # Applies to a multi-port range.
            'applies_8081_8083':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='applies_8081_8083',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['applies_8081_8083']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                    'ports': ['8081-8083'],
                }]),
            ),
            # Doesn't apply because of direction mismatch.
            'direction':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='direction',
                firewall_rule_direction='EGRESS',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['direction']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Doesn't apply because of network mismatch.
            'network':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='network',
                firewall_rule_network='global/networks/social',
                firewall_rule_source_tags=json.dumps(['network']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Doesn't apply because of tags.
            'tag_mismatch':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='tag_mismatch',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['tag_mismatch']),
                firewall_rule_target_tags=json.dumps(
                    ['im_gonna_pop_some_tags']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Tag-specific rule *does* apply.
            'tag_match':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='tag_match',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['tag_match']),
                firewall_rule_target_tags=json.dumps(['tag_i1']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Preempted by deny rule.
            'preempted':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='preempted',
                firewall_rule_network='global/networks/default',
                firewall_rule_source_tags=json.dumps(['preempted']),
                firewall_rule_allowed=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
            # Preempted by deny rule.
            'preempted_deny':
            firewall_rule_type.FirewallRule(
                project_id='foo',
                firewall_rule_name='preempted_deny',
                firewall_rule_priority=1,
                firewall_rule_network='global/networks/default',
                firewall_rule_source_ranges=json.dumps(['preempted']),
                firewall_rule_denied=json.dumps([{
                    'IPProtocol': 'tcp',
                }]),
            ),
        }
        self.instances = {
            'i1':
            instance_type.Instance(
                project_id='foo',
                name='i1',
                tags=json.dumps({'items': ['tag_i1']}),
                zone='wl-redqueen1-a',
            ),
            'i2':
            instance_type.Instance(
                project_id='foo',
                name='i2',
                tags=json.dumps([]),
                zone='wl-redqueen1-a',
            ),
        }
        self.instance_groups = {
            # Managed
            'ig_managed':
            instance_group_type.InstanceGroup(
                project_id='foo',
                name='ig_managed',
                network='global/networks/default',
                region='wl-redqueen1',
                instance_urls=json.dumps([
                    ('https://www.googleapis.com/compute/v1/'
                     'projects/foo/zones/wl-redqueen1-a/instances/i1')
                ]),
            ),
            # Unmanaged; overrides port mapping
            'ig_unmanaged':
            instance_group_type.InstanceGroup(
                project_id='foo',
                name='ig_unmanaged',
                network='global/networks/default',
                region='wl-redqueen1',
                instance_urls=json.dumps([]),
                named_ports=json.dumps([{
                    'name': 'foo',
                    'port': 80
                }, {
                    'name': 'http',
                    'port': 8080
                }]),
            ),
            # Unmanaged; same instance as ig_managed
            'ig_same_instance':
            instance_group_type.InstanceGroup(
                project_id='foo',
                name='ig_same_instance',
                network='global/networks/default',
                region='wl-redqueen1',
                instance_urls=json.dumps([
                    ('https://www.googleapis.com/compute/v1/'
                     'projects/foo/zones/wl-redqueen1-a/instances/i1')
                ]),
            ),
            # Unmanaged; different network than ig_managed
            'ig_different_network':
            instance_group_type.InstanceGroup(
                project_id='foo',
                name='ig_different_network',
                network='global/networks/nondefault',
                region='wl-redqueen1',
                instance_urls=json.dumps([
                    ('https://www.googleapis.com/compute/v1/'
                     'projects/foo/zones/wl-redqueen1-a/instances/i1')
                ]),
            ),
            # Unmanaged; different instance than ig_managed
            'ig_different_instance':
            instance_group_type.InstanceGroup(
                project_id='foo',
                name='ig5',
                network='global/networks/default',
                region='wl-redqueen1',
                instance_urls=json.dumps([
                    ('https://www.googleapis.com/compute/v1/'
                     'projects/foo/zones/wl-redqueen1-a/instances/i2')
                ]),
            ),
        }
        self.instance_group_managers = {
            'igm1':
            instance_group_manager_type.InstanceGroupManager(
                project_id='foo',
                name='igm1',
                instance_group=
                ('https://www.googleapis.com/compute/v1/'
                 'projects/foo/regions/wl-redqueen1/instanceGroups/ig_managed'
                 ),
                instance_template=(
                    'https://www.googleapis.com/compute/v1/'
                    'projects/foo/global/instanceTemplates/it1'),
                region='wl-redqueen1',
            ),
        }
        self.instance_templates = {
            'it1':
            instance_template_type.InstanceTemplate(
                project_id='foo',
                name='it1',
                properties=json.dumps({
                    'tags': {
                        'items': ['tag_it1']
                    },
                }),
            ),
        }
        self.data = iap_scanner._RunData(
            self.backend_services.values(),
            self.firewall_rules.values(),
            self.instances.values(),
            self.instance_groups.values(),
            self.instance_group_managers.values(),
            self.instance_templates.values(),
        )