def onStart(self): env_vars = get_environment_file_dict() self.suricata_rule_config = config.ConfigManager( env_vars['SURICATA_CONFIG'], backup_configuration_directory=const.CONFIG_BACKUP_PATH) self.addForm('MAIN', SuricataRuleSettingsForm, name='Suricata Rule Configuration')
def get_attached_interfaces(self) -> List[str]: conf_mng = suricata_config.ConfigManager( configuration_directory=self.config_directory, stdout=False, verbose=False) if not conf_mng.af_packet_interfaces: return [] return [ iface.interface for iface in conf_mng.af_packet_interfaces if iface.interface in utilities.get_network_interface_names() ]
def onStart(self): npyscreen.setTheme(npyscreen.Themes.ColorfulTheme) env_vars = get_environment_file_dict() self.suricata_config = config.ConfigManager( env_vars['SURICATA_CONFIG'], backup_configuration_directory=os.path.join( const.CONFIG_BACKUP_PATH)) self.addForm('MAIN', SuricataInstanceSettingsForm, name='Suricata Instance Configuration') self.addForm('EDITINTERFACEFM', EditInterfaceForm, name='Edit Suricata Network Interface')
def setup_suricata(self): """ Setup Suricata IDS with AF_PACKET support """ env_file = os.path.join(const.CONFIG_PATH, 'environment') self._copy_suricata_files_and_directories() self._configure_and_compile_suricata() try: with open(env_file) as env_f: if 'SURICATA_HOME' not in env_f.read(): self.logger.info('Updating Suricata default home path [{}]'.format(self.install_directory)) subprocess.call('echo SURICATA_HOME="{}" >> {}'.format(self.install_directory, env_file), shell=True) if 'SURICATA_CONFIG' not in env_f.read(): self.logger.info('Updating Suricata default config path [{}]'.format(self.configuration_directory)) subprocess.call('echo SURICATA_CONFIG="{}" >> {}'.format( self.configuration_directory, env_file), shell=True) except IOError: self.logger.error("Failed to open {} for reading.".format(env_file)) raise suricata_exceptions.InstallSuricataError( "Failed to open {} for reading.".format(env_file)) except Exception as e: self.logger.error("General error while creating environment variables in {}.".format(env_file)) self.logger.debug("General error while creating environment variables in {}; {}".format(env_file, e)) raise suricata_exceptions.InstallSuricataError( "General error while creating environment variables in {}; {}".format(env_file, e)) try: config = suricata_configs.ConfigManager(self.configuration_directory) except suricata_exceptions.ReadsSuricataConfigError: self.logger.error("Failed to read Suricata configuration.") raise suricata_exceptions.InstallSuricataError("Failed to read Suricata configuration.") config.af_packet_interfaces = [] for interface in self.capture_network_interfaces: config.add_afpacket_interface(interface, threads='auto', cluster_id=99) try: config.write_config() except suricata_exceptions.WriteSuricataConfigError: self.logger.error("Failed to write Suricata configuration.") suricata_exceptions.InstallSuricataError("Could not write Suricata configurations.") try: sysctl = systemctl.SystemCtl() except general_exceptions.CallProcessError: raise suricata_exceptions.InstallSuricataError("Could not find systemctl.") self.logger.info("Installing Suricata systemd Service.") if not sysctl.install_and_enable(os.path.join(const.DEFAULT_CONFIGS, 'systemd', 'suricata.service')): raise suricata_exceptions.InstallSuricataError("Failed to install Suricata systemd service.")
def get_available_cpus(self) -> list: """Get the CPU core numbers that are not currently being utilized Returns: A list of available CPUs """ zeek_profiler = zeek_profile.ProcessProfiler() suricata_profiler = suricata_profile.ProcessProfiler() available_cpus = [c for c in range(0, utilities.get_cpu_core_count())] reserved_cpus = [] zeek_cpus = [] suricata_cpus = [] if zeek_profiler.is_installed(): zeek_node_config_mng = zeek_config.NodeConfigManager( install_directory=self.zeek_install_directory, stdout=self.stdout, verbose=self.verbose) for worker in zeek_node_config_mng.workers: zeek_cpus.extend(worker.pinned_cpus) if suricata_profiler.is_installed(): suricata_config_mng = suricata_config.ConfigManager( configuration_directory=self.suricata_configuration_directory, stdout=self.stdout, verbose=self.verbose) if suricata_config_mng.threading.worker_cpu_set: suricata_cpus.extend( suricata_config_mng.threading.worker_cpu_set) if suricata_config_mng.threading.receive_cpu_set: suricata_cpus.extend( suricata_config_mng.threading.receive_cpu_set) if suricata_config_mng.threading.management_cpu_set: suricata_cpus.extend( suricata_config_mng.threading.management_cpu_set) reserved_cpus.extend(suricata_cpus) reserved_cpus.extend(zeek_cpus) return list(set([c for c in available_cpus if c not in reserved_cpus]))
def onStart(self): env_vars = get_environment_file_dict() self.suricata_rule_config = config.ConfigManager(env_vars['SURICATA_CONFIG']) self.addForm('MAIN', SuricataRuleSettingsForm, name='Suricata Rule Configuration')
def optimize(self, available_cpus: Optional[List[int]] = None) -> None: """Apply the best CPU-affinity related configurations to Zeek and Suricata Returns: None """ zeek_profiler = zeek_profile.ProcessProfiler() suricata_profiler = suricata_profile.ProcessProfiler() if not available_cpus: available_cpus = [ c for c in range(0, utilities.get_cpu_core_count()) ] self.logger.info(f'{len(available_cpus)} CPU cores detected.') if zeek_profiler.is_attached_to_network( ) and suricata_profiler.is_attached_to_network(): self.logger.info( 'Both Zeek and Suricata are installed. Allocating 60% of resources to Zeek, ' '30% to Suricata, and 10% to Kernel.') kern_alloc, zeek_alloc, suricata_alloc = .1, .6, .3 elif zeek_profiler.is_attached_to_network(): self.logger.info( 'Only Zeek is installed. Allocating 90% of resources to it and 10% to Kernel.' ) kern_alloc, zeek_alloc, suricata_alloc = .1, .9, 0 elif suricata_profiler.is_attached_to_network(): self.logger.info( 'Only Suricata is installed. Allocating 90% of resources to it and 10% to Kernel.' ) kern_alloc, zeek_alloc, suricata_alloc = .1, 0, .9 else: self.logger.error( 'Neither Zeek nor Suricata is installed. You must install at least one of these in order ' 'to run this command.') return None if len(available_cpus) > 4: round_func = math.ceil else: round_func = math.floor kern_cpu_count = math.ceil(kern_alloc * len(available_cpus)) zeek_cpu_count = round_func(zeek_alloc * len(available_cpus)) suricata_cpu_count = round_func(suricata_alloc * len(available_cpus)) zeek_cpus = [ c for c in available_cpus[kern_cpu_count:kern_cpu_count + zeek_cpu_count] ] suricata_cpus = [ c for c in available_cpus[kern_cpu_count + zeek_cpu_count:kern_cpu_count + zeek_cpu_count + suricata_cpu_count] ] if zeek_profiler.is_attached_to_network(): zeek_node_config_mng = zeek_config.NodeConfigManager( install_directory=self.zeek_install_directory, stdout=self.stdout, verbose=self.verbose) zeek_node_config_mng.workers = zeek_node_config_mng.get_optimal_zeek_worker_config( zeek_profiler.get_attached_interfaces(), available_cpus=tuple(zeek_cpus)) zeek_node_config_mng.commit() if suricata_profiler.is_attached_to_network(): suricata_config_mng = suricata_config.ConfigManager( configuration_directory=self.suricata_configuration_directory, stdout=self.stdout, verbose=self.verbose) suricata_config_mng.threading = suricata_config_mng.get_optimal_suricata_threading_config( available_cpus=tuple(suricata_cpus)) suricata_config_mng.runmode = 'workers' for suricata_iface in suricata_config_mng.af_packet_interfaces: suricata_iface.threads = round_func( len(suricata_config_mng.threading.worker_cpu_set) / len(suricata_profiler.get_attached_interfaces())) suricata_iface.cluster_type = 'cluster_qm' suricata_config_mng.commit()
def setup_suricata_rules(self): """ Installs Oinkmaster, sets up rules, and disables unneeded rule sets. """ self.logger.info("Installing Suricata Rules (via Oinkmaster).") oink_installer = rules_install.InstallManager( download_oinkmaster_archive=True, stdout=self.stdout, verbose=self.verbose, install_directory=os.path.join(self.install_directory, 'oinkmaster')) try: oink_installer.setup_oinkmaster() except oinkmaster_exceptions.InstallOinkmasterError as e: self.logger.error("Unable to install Oinkmaster dependency.") self.logger.debug( "Unable to install Oinkmaster dependency; {}".format(e)) raise suricata_exceptions.InstallSuricataError( "Unable to install Oinkmaster dependency.") try: self.logger.info("Updating Suricata Rules (via Oinkmaster)") rules_install.update_suricata_rules() except oinkmaster_exceptions.UpdateSuricataRulesError as e: self.logger.error("Unable to update Suricata rule-sets.") self.logger.debug( "Unable to update Suricata rule-sets; {}".format(e)) raise suricata_exceptions.InstallSuricataError( "Unable to update Suricata rule-sets.") try: config = suricata_configs.ConfigManager( self.configuration_directory) except suricata_exceptions.ReadsSuricataConfigError: self.logger.error("Failed to read Suricata configuration.") raise suricata_exceptions.InstallSuricataError( "Failed to read Suricata configuration.") config.default_log_directory = self.log_directory config.suricata_log_output_file = os.path.join(self.log_directory, 'suricata.log') config.default_rules_directory = os.path.join( self.configuration_directory, 'rules') config.reference_config_file = os.path.join( self.configuration_directory, 'reference.config') config.classification_file = os.path.join(self.configuration_directory, 'rules', 'classification.config') # Disable Unneeded Suricata rules try: self.logger.debug("Disabling Suricata Rule: 'http-events.rules'") config.disable_rule('http-events.rules') self.logger.debug("Disabling Suricata Rule: 'smtp-events.rules'") config.disable_rule('smtp-events.rules') self.logger.debug("Disabling Suricata Rule: 'dns-events.rules'") config.disable_rule('dns-events.rules') self.logger.debug("Disabling Suricata Rule: 'tls-events.rules'") config.disable_rule('tls-events.rules') self.logger.debug("Disabling Suricata Rule: 'drop.rules'") config.disable_rule('drop.rules') self.logger.debug("Disabling Suricata Rule: 'emerging-p2p.rules'") config.disable_rule('emerging-p2p.rules') self.logger.debug("Disabling Suricata Rule: 'emerging-pop3.rules'") config.disable_rule('emerging-pop3.rules') self.logger.debug( "Disabling Suricata Rule: 'emerging-telnet.rules'") config.disable_rule('emerging-telnet.rules') self.logger.debug("Disabling Suricata Rule: 'http-events.rules'") config.disable_rule('emerging-tftp.rules') self.logger.debug("Disabling Suricata Rule: 'emerging-voip.rules'") config.disable_rule('emerging-voip.rules') except suricata_exceptions.SuricataRuleNotFoundError: self.logger.error('Could not disable one or more Suricata rules.') raise suricata_exceptions.InstallSuricataError( "Could not disable one or more Suricata rules.") try: config.write_config() except suricata_exceptions.WriteSuricataConfigError: self.logger.error('Could not write Suricata configurations.') suricata_exceptions.InstallSuricataError( "Could not write Suricata configurations.")
from dynamite_nsm.services.suricata import config from dynamite_nsm.utilities import get_environment_file_dict from dynamite_nsm.cmd.service_interfaces import SimpleConfigManagerInterface env_vars = get_environment_file_dict() try: interface = \ SimpleConfigManagerInterface(config.ConfigManager(env_vars['SURICATA_CONFIG']), interface_name='Suricata Configuration', interface_description='Configure various Suricata config options.', defaults=dict(configuration_directory=env_vars['SURICATA_CONFIG'], stdout=True) ) except KeyError: interface = None except FileNotFoundError: interface = None """ if not interface: print(f'Skipping suricata.config.main as it was never retrieved successfully') """
def setup(self, inspect_interfaces: List[str]): """Install Suricata Args: inspect_interfaces: A list of network interfaces to capture on (E.G ["mon0", "mon1"]) Returns: None """ if not self.skip_interface_validation: if not self.validate_inspect_interfaces(inspect_interfaces): raise install.NetworkInterfaceNotFound(inspect_interfaces) sysctl = systemctl.SystemCtl() self.install_suricata_dependencies() self.create_update_suricata_environment_variables() self.logger.debug(f'Creating directory: {self.configuration_directory}') utilities.makedirs(self.configuration_directory) self.logger.debug(f'Creating directory: {self.install_directory}') utilities.makedirs(self.install_directory) self.logger.debug(f'Creating directory: {self.log_directory}') utilities.makedirs(self.log_directory) self.copy_suricata_files_and_directories() self.logger.info('Setting up Suricata from source. This can a few minutes.') if self.stdout: utilities.print_coffee_art() self.configure_compile_suricata() self.copy_file_or_directory_to_destination( f'{const.DEFAULT_CONFIGS}/suricata/suricata.yaml', self.configuration_directory ) suricata_config = config.ConfigManager(self.configuration_directory, stdout=self.stdout, verbose=self.verbose) suricata_config.default_log_directory = self.log_directory suricata_config.suricata_log_output_file = os.path.join(self.log_directory, 'suricata.log') suricata_config.default_rules_directory = os.path.join(self.configuration_directory, 'rules') suricata_config.reference_config_file = os.path.join(self.configuration_directory, 'reference.config') suricata_config.classification_file = os.path.join(self.configuration_directory, 'rules', 'classification.config') suricata_config.af_packet_interfaces = misc.AfPacketInterfaces() for interface in inspect_interfaces: suricata_config.af_packet_interfaces.add( misc.AfPacketInterface( interface_name=interface, threads='auto', cluster_id=random.randint(1, 50000), cluster_type='cluster_qm' ) ) suricata_config.threading = suricata_config.get_optimal_suricata_threading_config( tuple([i for i in range(0, utilities.get_cpu_core_count() - 1)])) suricata_config.commit() self.logger.info('Applying Suricata configuration.') self.logger.debug(suricata_config.af_packet_interfaces) suricata_config.commit() # Fix Permissions self.logger.info('Setting up file permissions.') utilities.set_ownership_of_file(self.configuration_directory, user='******', group='dynamite') utilities.set_ownership_of_file(self.install_directory, user='******', group='dynamite') utilities.set_ownership_of_file(self.log_directory, user='******', group='dynamite') post_install_bootstrap_updater(self.install_directory, stdout=self.stdout, verbose=self.verbose) self.logger.info(f'Installing service -> {const.DEFAULT_CONFIGS}/systemd/suricata.service') sysctl.install_and_enable(os.path.join(const.DEFAULT_CONFIGS, 'systemd', 'suricata.service'))