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')
Exemple #2
0
 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')
Exemple #4
0
 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.")
Exemple #5
0
    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')
Exemple #7
0
    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()
Exemple #8
0
    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.")
Exemple #9
0
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')
"""
Exemple #10
0
    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'))