def tearDown(self): try: Host('test-common-api-user').delete() Host('test-api-user').delete() session.logout() except SystemExit: pass
def disconnect(self): """ Disconnect session from SMC after ansible run """ try: session.logout() except SMCException: pass
def smc_configuration(engine_name, public_ip, private_ip, public_network): session_login() vpn_name, tunnel_1, tunnel_2 = get_vpn(public_ip) network_name = f'awsnetwork-{public_network}' try: Network.create(name=network_name, ipv4_network=public_network) except CreateElementFailed as err: logging.info(err) l3fw_policy('transit_gw_policy') policy = firewall_rule('transit_gw_policy') add_tunnel_to_engine(engine_name, '2000', tunnel_1.get('outside_ip'), tunnel_1.get('inside_ip_cidr'), 'tunnelA') add_tunnel_to_engine(engine_name, '2001', tunnel_2.get('outside_ip'), tunnel_2.get('inside_ip_cidr'), 'tunnelB') try: remote_gateway_first = external_gateway( name=f'{vpn_name}-{1}', endpoint_name='endpoint_1', address=tunnel_1.get('outside_ip'), network_name=network_name ) # site-to-site vpn connection VPN ID include number at the end except CreateElementFailed as err: logging.info(err) try: remote_gateway_second = external_gateway( name=f'{vpn_name}-{2}', endpoint_name='endpoint_2', address=tunnel_2.get('outside_ip'), network_name=network_name ) # site-to-site vpn connection VPN ID include number at the end except CreateElementFailed as err: logging.info(err) bgp_elements( 64512, vpn_name, tunnel_1.get('gateway'), tunnel_2.get('gateway'), engine_name ) # transit gateway : Amazon ASN inside ip is from tunnel of vpn - the /30 add_dynamic_routing_antispoofing(engine_name) vpn_endpoint = Engine(engine_name).vpn_endpoint.get_contains(private_ip) vpn_endpoint.update(enabled=True) vpn_create_ipsec(engine_name, 2000, tunnel_1.get('pre_shared_key'), vpn_name, 1, remote_gateway_first) vpn_create_ipsec(engine_name, 2001, tunnel_2.get('pre_shared_key'), vpn_name, 2, remote_gateway_second) policy.upload(engine_name) session.logout()
def destroy(namespace): resource_client = client() if resource_client.resource_groups.check_existence( namespace.resource_group): poller = resource_client.resource_groups.delete( # AzureOperationPoller namespace.resource_group) session.login() try: Layer3Firewall(namespace.resource_group).delete() except (ElementNotFound, DeleteElementFailed) as e: logger.error('Problem deleting engine: {}'.format(e)) session.logout() return poller.result(timeout=10)
def test_login_credentials_in_constructor(self, m): """ Log in using credentials in the constructor. Double check the sesison object to make sure settings are set. """ m.register_uri('GET', '/api', json=self.version_dict()) # Initial connect # Get entry points m.register_uri('GET', '/6.1/api', json=self.entry_point_dict()) m.register_uri('POST', '/6.1/login', status_code=200) session.login(url='http://1.1.1.1:8082', api_key='12345', api_version=6.1, timeout=60, domain='mydomain') self.assertEqual(session.url, 'http://1.1.1.1:8082') self.assertEqual(session.api_version, 6.1) self.assertEqual(session.timeout, 60) self.assertEqual(session.api_key, '12345') self.assertEqual(session.domain, 'mydomain') # Fail the logout, nothing should be returned unless logging m.register_uri('PUT', '/6.1/logout', status_code=400) self.assertIsNone(session.logout())
def remove_smc_engines(engine_name, public_ip, private_ip): session_login() MASK = '255.255.255.0' engine = Engine(engine_name) routes = RouteVPN.objects.all() gateways_to_delete = [] for route in list(routes): route_name = route.name if engine_name in route_name: RouteVPN().get(route_name).delete() gateways_to_delete.append((route_name.split(engine_name)[-1])[1:]) engine.delete() for gw in gateways_to_delete: ExternalGateway.get(gw).delete() public_base = MyIPv4(public_ip) & MyIPv4(MASK) public_network = string_to_ip(str(public_base) + '/24') Network.get(f'awsnetwork-{public_network}').delete() session.logout()
def test_session_login_pass_from_file(self, mock_open, m): """ Test a valid login session through smc.api.session. Login will be done through the login file method of session.login(alt_filepath='foo'). Verify the session afterwards. """ cfg = ("[smc]\n" "smc_address=1.1.1.1\n" "smc_apikey=12345\n" "timeout=60\n" "api_version=6.1\n" "domain=mydomain") mock_open.return_value = io.StringIO(u'{}'.format(cfg)) entry_points = self.entry_point_dict() m.register_uri('GET', '/api', json=self.version_dict()) m.register_uri('GET', '/6.1/api', json=entry_points) m.register_uri('POST', '/6.1/login', status_code=200) session.login(alt_filepath='foo') # Session object now has everything we need self.assertIsInstance(session.entry_points, _EntryPoint) self.assertEqual(session.api_key, '12345') self.assertIsInstance(session.connection, SMCAPIConnection) self.assertEqual(session.timeout, 60) self.assertEqual(session.url, 'http://1.1.1.1:8082') self.assertEqual(session.api_version, 6.1) self.assertEqual(session.domain, 'mydomain') # Entry points should match self.assertEqual( entry_points.get('entry_point')[0].get('href'), session.entry_points.get('logout')) # Get an entry point that doesn't exist self.assertRaises(UnsupportedEntryPoint, lambda: session.entry_points.get('foo')) # Entry points by name; without href,rel,method entry_rel = [p.get('rel') for p in entry_points.get('entry_point')] self.assertEqual(entry_rel, session.entry_points.all()) #self.assertEqual(session.entry_points.all(), # session.cache.entry_points) # Successful logout. No status returned.. m.register_uri('PUT', '/6.1/logout', status_code=204) self.assertIsNone(session.logout()) # Session logged out. This would indicate no valid login session self.assertRaises(SMCConnectionError, lambda: session.entry_points.get('boo'))
def test_login_refresh(self): import os from smc.tests.constants import url, api_key os.environ['SMC_ADDRESS'] = url os.environ['SMC_API_KEY'] = api_key os.environ['SMC_TIMEOUT'] = '200' session.login(beta=True) self.assertEqual(url, 'http://172.18.1.26:8082') self.assertEqual(session._extra_args.get('beta'), True) session.refresh() self.assertEqual(url, 'http://172.18.1.26:8082') self.assertEqual(session._extra_args.get('beta'), True) session.logout() session._api_key = None # Raises because we do not have a session already with self.assertRaises(SMCConnectionError): session.refresh() # Somehow credential is bad during retry. This will just raise with self.assertRaises(SMCConnectionError): session._api_key = 'foo' session.refresh()
def test_requests_error_during_logout_with_ssl(self, m): # Initial connect m.register_uri('GET', '/api', json=self.version_dict()) # Get entry points m.register_uri('GET', '/6.1/api', json=self.entry_point_dict()) m.register_uri('POST', '/6.1/login', status_code=200) session.login(url='http://1.1.1.1:8082', api_key='12345', api_version=6.1) m.register_uri('PUT', '/6.1/logout', json=self.raise_requests_ssl_exception) # Entry point cache exists self.assertTrue(len(session.entry_points) > 0) # Logout will catch an SSL Error self.assertIsNone(session.logout()) # Entry point cache is still removed with self.assertRaises(SMCConnectionError): session.entry_points
def tearDown(self): try: engine_not_initialized.delete() session.logout() except SystemExit: pass
mydestinations = 'any' policy.fw_ipv4_access_rules.create(name='mynewrule', sources=mysources, destinations=mydestinations, services=myservices, action='permit') """ View a metadata version of each configured rule """ for rule in policy.fw_ipv4_access_rules.all(): print rule.name """ View details of the rule/s (this can be resource intensive depending on how many rules are configured """ for rule in policy.fw_ipv4_access_rules.all(): print rule.describe() """ Delete a rule by name (comment this out to verify rule creation) """ # for rule in policy.fw_ipv4_access_rules.all(): # if rule.name == 'myrule': # rule.delete() session.logout()
def run_query_and_upload(): aws_integration = cfg.get('aws-integration', False) azure_integration = cfg.get('azure-integration', False) # Create default insights if they don't already exist if aws_integration: threading.Thread(target=create_default_insights).start() setup_sec_hub() enable_batch_import_findings() default_filter = __setup_smc_query_filter(cfg['default-filter']) smc_url = cfg['host-ip'] + ':' + cfg['host-port'] api_version = __get_latest_api_version(smc_url) session.login(url=smc_url, api_key=cfg['client-api-key'], api_version=api_version) try: query = LogQuery(fetch_size=int(cfg['fetch-size'])) translated_filter = query.add_translated_filter() # Create default filter specified in the config file translated_filter.update_filter(default_filter) # Query the SMC for events matching the filter and flatten the list of result-lists into a single list record_list = list(itertools.chain(*query.fetch_raw())) extra_filters_enabled = cfg['extra-filters-enabled'] # Check to see if extra filters are enabled and if any are present before iterating over them and requesting # matching events from the SMC and appending to the original results list if bool(extra_filters_enabled): extra_filters = cfg['extra-filters'] if bool(extra_filters): for log_filter in extra_filters: translated_filter.update_filter(__setup_smc_query_filter(log_filter)) record_list.extend(list(itertools.chain(*query.fetch_raw()))) if record_list: # Find the max date in the record list and store this to add to the filter for subsequent queries # to avoid uploading duplicates/wasting bandwidth. This value is written to the cfg.json file max_finding_date = format_date_smc_filter(max(item['Creation Time'] for item in record_list)) loop = asyncio.get_event_loop() # Map to appropriate format and upload if integration is active if aws_integration: aws_task = loop.create_task( amazon_security_hub_batch_upload(list(map(create_asff_object, record_list)), max_finding_date)) loop.run_until_complete(aws_task) if azure_integration: send_sentinel_data(list(map(format_smc_logs_to_cef, record_list)), max_finding_date) # This catches any issues related to requesting events with a malformed filter except FetchAborted as exception: print(exception) write_to_log(exception) session.logout()
def main(): logger = logging.getLogger() formatter = logging.Formatter( '%(asctime)s (%(threadName)-8s) [%(levelname)s] - %(name)s %(message)s' ) handler = logging.StreamHandler() handler.setFormatter(formatter) logger.addHandler(handler) from deploy import __version__ import argparse parser = argparse.ArgumentParser(description='Stonesoft NGFW AWS Launcher') group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-y', '--yaml', help='Specify yaml configuration file name') group.add_argument('configure', nargs='?', help='Initial configuration wizard') actions = parser.add_mutually_exclusive_group() actions.add_argument('--delete_vpc', action='store_true', help='Delete a VPC (menu)') actions.add_argument('--create_vpc', action='store_true', help='Create a VPC with NGFW') actions.add_argument('-r', '--remove', action='store_true', help='Remove NGFW from VPC (menu)') actions.add_argument('-a', '--add', action='store_true', help='Add NGFW to existing VPC (menu)') actions.add_argument('-l', '--list', action='store_true', help='List NGFW installed in VPC (menu)') actions.add_argument('-la', '--listall', action='store_true', help='List all NGFW instances in AZs') parser.add_argument('-v', '--verbose', action='store_true', help='Enable verbose logging') parser.add_argument( '--version', action='version', version='%(prog)s {version}'.format(version=__version__)) args = parser.parse_args() if not any(vars(args).values()): parser.print_help() parser.exit() logger.setLevel(logging.INFO) logging.getLogger('smc').setLevel(logging.ERROR) logging.getLogger('boto3').setLevel(logging.CRITICAL) logging.getLogger('botocore').setLevel(logging.CRITICAL) if args.verbose: logging.getLogger('smc').setLevel(logging.INFO) logging.getLogger('requests').setLevel(logging.INFO) logging.getLogger('boto3').setLevel(logging.INFO) logging.getLogger('botocore').setLevel(logging.INFO) print() print('Stonesoft AWS Launcher') print("======================") print() if args.configure: path = prompt_user() print('Configuration complete. You can launch the script using ' 'the -y {} for subsequent operations.'.format(path)) return if args.yaml: path = args.yaml with open(path, 'r') as stream: try: data = yaml.safe_load(stream) awscfg = AWSConfig(**data.get('AWS')) ngfw = data.get('NGFW') smc = data.get('SMC') except yaml.YAMLError as exc: print(exc) if args.listall: aws_session = get_boto3_session() template = '{0:22}|{1:20}|{2:12}|{3:12}|{4:12}' vpc_template = '{0:15}|' print( vpc_template.format('VPC ID'), template.format('Instance ID', 'Availability Zone', 'Type', 'State', 'Launch Time')) for region in aws_session.get_available_regions('ec2'): ec2 = get_ec2_resource(awscfg.aws_access_key_id, awscfg.aws_secret_access_key, region) for vpc in ec2.vpcs.filter(): instances = installed_as_list_view(vpc) if instances: for instance in instances: print(vpc_template.format(vpc.id), template.format(*instance)) return get_ec2_client(awscfg, prompt_for_region=True) get_smc_session(smc) if args.remove: tagged = list_tagged_instances(select_vpc(as_instance=True)) if tagged: instances = select_instance(tagged, as_instance=True) remove_ngfw_from_vpc(instances) else: print('Nothing to remove.') return if args.list: instances = installed_as_list_view(select_vpc(as_instance=True)) if instances: template = '{0:22}|{1:20}|{2:12}|{3:12}|{4:12}' print( template.format('Instance ID', 'Availability Zone', 'Type', 'State', 'Launch Time')) for instance in instances: print(template.format(*instance)) return # Need the NGFW config validated for remaining options validate(**ngfw) #Raises if validation fails if args.add: validate_aws(awscfg) vpc = select_vpc(as_instance=True) subnets = select_unused_subnet(vpc, as_instance=True) if subnets: style = select_deploy_style() if style == 'Inline Gateway': style = create_inline_ngfw else: #NAT Gateway style = create_as_nat_gateway subnet_map = map_az_to_subnet(subnets) itr = next_available_subnet(list_all_subnets(vpc), vpc.cidr_block) q = Queue() pool, subnet_keys, results = ([] for i in range(3)) try: for zone, subnets in subnet_map.items(): t = threading.Thread( target=style, args=[subnets, next(itr), awscfg, ngfw, q]) pool.append(t) subnet_keys.append(zone) except StopIteration: for zone in subnet_keys: del subnet_map[zone] results.append((subnet_map, [ 'No available network addresses in VPC to create ' 'NGFW in the following subnets. Skipping.' ])) finally: for thread in pool: thread.start() start_time = time.time() for thread in pool: thread.join() response = q.get() results.append(response) generate_report(results) logger.info("Process completed in %s seconds" % (time.time() - start_time)) else: print('No unused subnets available.') return if args.delete_vpc: selection = select_delete_vpc() vpc = VpcConfiguration(selection).load() try: rollback(vpc.vpc) except VpcConfigurationError as e: logger.error(e) if args.create_vpc: validate_aws(awscfg, vpc_create=True) start_time = time.time() results = create_vpc_and_ngfw(awscfg, ngfw) generate_report(results) logger.info("Process completed in %s seconds" % (time.time() - start_time)) session.logout()
def engine_creation(engine_name, private_ip, public_ip, protected_network, router_ip, private_network): session.login(url=get_url(), api_key=get_api_key(), api_version=get_api_version(), verify=pem_dir) profile = VPNProfile.get_or_create(name=PROFILE_NAME) profile.update(capabilities={ 'ike_v1': True, 'aes128_for_ike': True, 'aggressive_mode': False, 'sha1_for_ike': True, 'dh_group_2_for_ike': True, 'pre_shared_key_for_ike': True, 'rsa_signature_for_ike': False, 'main_mode': True, 'esp_for_ipsec': True, 'aes128_for_ipsec': True, 'sha1_for_ipsec': True, 'sa_per_net': True, 'pfs_dh_group_2_for_ipsec': True, 'rsa_signature_for_ike': True, 'vpn_client_sa_per_net': True }, sa_life_time=28800, tunnel_life_time_seconds=3600, hybrid_authentication_for_mobile_vpn=True, trust_all_cas=True) # we should wait for the engine to be present engine = None while not engine: try: engine = Engine(engine_name) except smc.api.exceptions.ElementNotFound as e: print(e) print(engine) print("retrying in 3 sec") time.sleep(3) interface = engine.interface.get(0) # set_stream_logger(log_level=logging.DEBUG) for sub in interface.sub_interfaces(): sub.data['dynamic'] = False sub.data['address'] = private_ip if 'dynamic_index' in sub.data: del sub.data['dynamic_index'] sub.data['network_value'] = private_network sub.update() interface.update() ROUTER_NAME = "aws_default_router-{}".format(router_ip) if Router.objects.filter(ROUTER_NAME): router = Router(ROUTER_NAME) else: router = Router.create(ROUTER_NAME, router_ip) # update routing interface0 = engine.routing.get(0) for network in interface0: if network.name == 'Network (IPv4)': print("{} should be deleted".format(network)) network.delete() if network.name == "network-{}".format(private_network): print("{} should be updated".format(network)) interface0.add_static_route(gateway=router, destination=[Network('Any network')]) # we need to add custom policy routing so advertised BGP routes are not used when # we source nat the traffic engine.data['policy_route'].append( dict(source=private_ip + '/32', destination=protected_network, gateway_ip=router_ip)) engine.update() # print(interface0.as_tree()) ca = engine.contact_addresses.get(0, interface_ip=private_ip) ca.add_contact_address(public_ip, location='Default') session.logout()
"target": ENGINENAME }, "fetch": {}, "format": { "type": "texts" } } ws.send(json.dumps(query)) result = ws.recv() print("Received '%s'" % result) result = ws.recv() print("Received '%s'" % result) ws.close() print("") print("Retrieve IPv6 Neighbors Data using smc_monitoring") query = NeighborQuery(ENGINENAME) query.add_in_filter(FieldValue(LogField.NEIGHBORPROTOCOL), [StringValue("IPv6")]) for record in query.fetch_batch(): print(record) print("Retrieve all Neighbor elements using smc_monitoring") query = NeighborQuery(ENGINENAME) for element in query.fetch_as_element(): print(element.node_id + " " + element.neighbor_state + " " + element.neighbor_interface + " " + element.neighbor_protocol + " " + element.neighbor_l3_data + "->" + element.neighbor_l2_data) session.logout()
def create(namespace): if namespace.template_path: with open(namespace.template_path, 'r') as template_file_fd: template = json.load(template_file_fd) pub_ssh_key_path = os.path.expanduser( '~/.ssh/id_rsa.pub') # the path to rsa public key file with open(pub_ssh_key_path, 'r') as pub_ssh_file_fd: pub_ssh_key = pub_ssh_file_fd.read() session.login() if namespace.force_remove: try: Layer3Firewall(namespace.resource_group).delete() except ElementNotFound: pass engineCfg = provision_stonesoft(name=namespace.resource_group, vnet=None, location=namespace.engine_location) parameters = { 'engineCfg': engineCfg, 'engineUsername': namespace.engine_username, 'sshKey': pub_ssh_key } parameters = {k: {'value': v} for k, v in parameters.items()} resource_client = client() resource_group_params = { 'location': namespace.location_id, 'tags': { 'stonesoft': namespace.tag_value } } try: resource_client.resource_groups.create_or_update( namespace.resource_group, resource_group_params) deployment_properties = { 'mode': DeploymentMode.incremental, 'parameters': parameters, 'template': None, 'template_link': None } if namespace.template_path: deployment_properties.update(template=template) else: deployment_properties.update( template_link=TemplateLink(namespace.template_link)) deployment_async_operation = resource_client.deployments.create_or_update( resource_group_name=namespace.resource_group, deployment_name=namespace.deployment_name, properties=deployment_properties) # AzureOperationPoller initial_result = deployment_async_operation.result(timeout=30) logger.info('Starting Azure deployment; correlation id: %s', initial_result.properties.correlation_id) logger.info('Azure provisioning state: %s', initial_result.properties.provisioning_state) while not deployment_async_operation.done(): deployment_async_operation.wait(timeout=30) status = resource_client.deployments.get( namespace.resource_group, deployment_name=namespace.deployment_name) logger.info('Azure provisioning state: %s', status.properties.provisioning_state) result = deployment_async_operation.result() elapsed_time = result.properties.timestamp - initial_result.properties.timestamp logger.info('Elapsed Time: %s (seconds)', elapsed_time.total_seconds()) if namespace.engine_policy: provision_stonesoft_policy(namespace.engine_policy) for k, v in result.properties.outputs.items(): logger.info('{} -> {}'.format(k, v.get('value'))) except CloudError: Layer3Firewall(namespace.resource_group).delete() raise finally: session.logout()
def tearDown(self): try: session.logout() except (SystemExit, requests.exceptions.ConnectionError): pass
def logout(self): # Logout from session session.logout()
def tearDown(self): try: session.logout() except SystemExit: pass
def tearDown(self): session.logout()