install
Installation Manager for Zeek and its dependencies.
To import...
from dynamite_nsm.services.zeek import install as zeek_install
InstallManager
Manage Zeek installation process
__init__(self, configuration_directory, install_directory, download_zeek_archive=True, skip_interface_validation=False, stdout=False, verbose=False)
special
Install Zeek
Parameters:
Name | Type | Description | Default |
---|---|---|---|
configuration_directory |
str |
Path to the configuration directory (E.G /etc/dynamite/zeek/) |
required |
install_directory |
str |
Path to the install directory (E.G /opt/dynamite/zeek/) |
required |
download_zeek_archive |
Optional[bool] |
If True, download the Zeek archive from a mirror |
True |
skip_interface_validation |
Optional[bool] |
If included we don't check if the interface is available on the system |
False |
stdout |
Optional[bool] |
Print output to console |
False |
verbose |
Optional[bool] |
Include detailed debug messages |
False |
Source code in dynamite_nsm/services/zeek/install.py
def __init__(self, configuration_directory: str, install_directory: str,
download_zeek_archive: Optional[bool] = True, skip_interface_validation: Optional[bool] = False,
stdout: Optional[bool] = False,
verbose: Optional[bool] = False):
"""Install Zeek
Args:
configuration_directory: Path to the configuration directory (E.G /etc/dynamite/zeek/)
install_directory: Path to the install directory (E.G /opt/dynamite/zeek/)
download_zeek_archive: If True, download the Zeek archive from a mirror
skip_interface_validation: If included we don't check if the interface is available on the system
stdout: Print output to console
verbose: Include detailed debug messages
"""
self.configuration_directory = configuration_directory
self.install_directory = install_directory
self.skip_interface_validation = skip_interface_validation
self.stdout = stdout
self.verbose = verbose
super(InstallManager, self).__init__(name='zeek.install', verbose=verbose, stdout=stdout)
if not shutil.which('python3-config'):
raise InstallError(
'Python3 development bindings must be installed for Zeek installation to fully succeed. '
'Common Packages: "python3-dev" (Debian based) "python3-devel" (RHEL based)')
if download_zeek_archive:
self.logger.info("Attempting to download Zeek archive.")
_, archive_name, self.local_mirror_root = self.download_from_mirror(const.ZEEK_MIRRORS)
self.logger.info(f'Attempting to extract Zeek archive ({archive_name}).')
self.extract_archive(os.path.join(const.INSTALL_CACHE, archive_name))
self.logger.info("Extraction completed.")
else:
_, _, self.local_mirror_root = self.get_mirror_info(const.ZEEK_MIRRORS)
configure_compile_zeek(self, parallel_threads=None)
Configure and build Zeek from source
Parameters:
Name | Type | Description | Default |
---|---|---|---|
parallel_threads |
Optional[int] |
Number of parallel threads to use during the compiling process |
None |
Returns:
Type | Description |
---|---|
None |
None |
Source code in dynamite_nsm/services/zeek/install.py
def configure_compile_zeek(self, parallel_threads: Optional[int] = None) -> None:
"""Configure and build Zeek from source
Args:
parallel_threads: Number of parallel threads to use during the compiling process
Returns:
None
"""
zeek_source_install_cache = os.path.join(const.INSTALL_CACHE, self.local_mirror_root)
configure_args = [f'--prefix={self.install_directory}', f'--scriptdir={self.configuration_directory}',
'--enable-jemalloc', '--with-python=/usr/bin/python3']
self.configure_source_package(zeek_source_install_cache, configure_args=configure_args)
time.sleep(1)
self.compile_source_package(zeek_source_install_cache,
parallel_threads=parallel_threads,
expected_lines_printed=COMPILE_PROCESS_EXPECTED_LINE_COUNT)
create_update_zeek_environment_variables(self)
Creates all the required Zeek environmental variables
Returns:
Type | Description |
---|---|
None |
None |
Source code in dynamite_nsm/services/zeek/install.py
def create_update_zeek_environment_variables(self) -> None:
"""Creates all the required Zeek environmental variables
Args:
Returns:
None
"""
self.create_update_env_variable('ZEEK_HOME', self.install_directory)
self.create_update_env_variable('ZEEK_SCRIPTS', self.configuration_directory)
install_zeek_dependencies(self)
Install Zeek dependencies (And PowerTools repo if on redhat based distro)
Returns:
Type | Description |
---|---|
None |
None |
Source code in dynamite_nsm/services/zeek/install.py
def install_zeek_dependencies(self) -> None:
"""Install Zeek dependencies (And PowerTools repo if on redhat based distro)
Args:
Returns:
None
"""
def install_powertools_rhel(pacman_type):
"""Install Zeek dependencies (And PowerTools repo if on redhat based distro)
Args:
Returns:
None
"""
if pacman_type != 'yum':
self.logger.info('Skipping RHEL PowerTools install, as it is not needed on this distribution.')
return
self.install_dependencies(yum_packages=['dnf-plugins-core', 'epel-release'])
enable_powertools_p = subprocess.Popen(['yum', 'config-manager', '--set-enabled', 'powertools'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
enable_powertools_p.communicate()
if enable_powertools_p.returncode == 0:
self.logger.info("Installed PowerTools.")
apt_get_packages = \
['bison', 'cmake', 'cmake3', 'flex', 'g++', 'gcc', 'libjemalloc-dev', 'libpcap-dev', 'libssl-dev',
'linux-headers-$(uname -r)', 'linux-headers-generic', 'make', 'swig', 'tar', 'sqlite3', 'zlib1g-dev']
yum_packages = \
['bison', 'cmake', 'cmake3', 'flex', 'gcc', 'gcc-c++', 'jemalloc-devel', 'kernel-devel', 'libpcap-devel',
'make', 'openssl-devel', 'swig', 'tar', 'sqlite-devel', 'zlib-devel']
self.install_dependencies(apt_get_packages=apt_get_packages, yum_packages=yum_packages,
pre_install_function=install_powertools_rhel)
setup(self, inspect_interfaces)
Setup Zeek
Parameters:
Name | Type | Description | Default |
---|---|---|---|
inspect_interfaces |
List[str] |
A list of network interfaces to capture on (E.G ["mon0", "mon1"]) |
required |
Returns:
Type | Description |
---|---|
|
None |
Source code in dynamite_nsm/services/zeek/install.py
def setup(self, inspect_interfaces: List[str]):
"""Setup Zeek
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_zeek_dependencies()
self.create_update_zeek_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.info('Setting up Zeek from source. This can take up to 15 minutes.')
if self.stdout:
utilities.print_coffee_art()
self.configure_compile_zeek()
self.logger.info('Setting up Zeek package manager.')
zkg_installer = zkg_install.InstallManager()
zkg_installer.setup()
try:
package.InstallPackageManager(const.ZEEK_PACKAGES, stdout=self.stdout, verbose=self.verbose).setup()
except zkg.InstallZeekPackageError as e:
self.logger.error(f'An error occurred while installing one or more Zeek packages: {e}')
self.copy_file_or_directory_to_destination(f'{const.DEFAULT_CONFIGS}/zeek/broctl-nodes.cfg',
f'{self.install_directory}/etc/node.cfg')
self.copy_file_or_directory_to_destination(f'{const.DEFAULT_CONFIGS}/zeek/local.zeek',
f'{self.configuration_directory}/site/local.zeek')
# Optimize Configurations
node_config = config.NodeConfigManager(self.install_directory, stdout=self.stdout, verbose=self.verbose)
node_config.workers = node.Workers()
for worker in node_config.get_optimal_zeek_worker_config(inspect_interfaces):
node_config.workers.add_worker(
worker=worker
)
self.logger.info('Applying node configuration.')
node_config.commit()
self.logger.info('Setting up BPF input configuration')
with open(f'{self.configuration_directory}/bpf_map_file.input', 'w') as bpf_config_f:
bpf_config_f.write('')
# Fix Permissions
self.logger.info('Setting up file permissions.')
utilities.set_ownership_of_file(self.configuration_directory, user='dynamite', group='dynamite')
utilities.set_permissions_of_file(f'{self.configuration_directory}/site/local.zeek', 660)
utilities.set_permissions_of_file(f'{self.configuration_directory}/site/bpf_map_file.input', 660)
utilities.set_ownership_of_file(self.install_directory, user='dynamite', group='dynamite')
utilities.set_permissions_of_file(f'{self.install_directory}/etc/node.cfg', 660)
utilities.set_permissions_of_file(f'{self.install_directory}/etc/networks.cfg', 660)
utilities.set_permissions_of_file(f'{self.install_directory}/etc/networks.cfg', 660)
self.logger.info('Setting up Zeek capture rules for dynamite user.')
set_caps.SetCapturePermissions(self.install_directory).invoke(shell=True)
self.logger.info(f'Installing service -> {const.DEFAULT_CONFIGS}/systemd/zeek.service')
sysctl.install_and_enable(os.path.join(const.DEFAULT_CONFIGS, 'systemd', 'zeek.service'))
UninstallManager
Manage Zeek uninstallation process
__init__(self, purge_config=True, stdout=False, verbose=False)
special
Uninstall Zeek
Parameters:
Name | Type | Description | Default |
---|---|---|---|
purge_config |
Optional[bool] |
If enabled, remove all the configuration files associated with this installation |
True |
stdout |
Optional[bool] |
Print output to console |
False |
verbose |
Optional[bool] |
Include detailed debug messages |
False |
Source code in dynamite_nsm/services/zeek/install.py
def __init__(self, purge_config: Optional[bool] = True, stdout: Optional[bool] = False,
verbose: Optional[bool] = False):
"""Uninstall Zeek
Args:
purge_config: If enabled, remove all the configuration files associated with this installation
stdout: Print output to console
verbose: Include detailed debug messages
"""
from dynamite_nsm.services.zeek.process import ProcessManager
env_vars = utilities.get_environment_file_dict()
zeek_directories = [env_vars.get('ZEEK_HOME')]
if purge_config:
zeek_directories.append(env_vars.get('ZEEK_SCRIPTS'))
super().__init__('zeek.uninstall', directories=zeek_directories, sysctl_service_name='zeek.service',
environ_vars=['ZEEK_HOME', 'ZEEK_SCRIPTS'],
process=ProcessManager(stdout=stdout, verbose=verbose), stdout=stdout, verbose=verbose)