diff --git a/emulation-system/envs/050/level_15/Makefile b/emulation-system/envs/050/level_15/Makefile
new file mode 100644
index 000000000..4584488d6
--- /dev/null
+++ b/emulation-system/envs/050/level_15/Makefile
@@ -0,0 +1,13 @@
+
+# Installs the configuration in the metastore
+install:
+ python config.py --install
+
+# Uninstalls the configuration from the metastore
+uninstall:
+ python config.py --uninstall
+
+# Cleans all configuration files
+clean_config:
+ rm -rf ./config.json
+ rm -rf ./containers
diff --git a/emulation-system/envs/050/level_15/README.MD b/emulation-system/envs/050/level_15/README.MD
new file mode 100644
index 000000000..bb46ad6f1
--- /dev/null
+++ b/emulation-system/envs/050/level_15/README.MD
@@ -0,0 +1,47 @@
+# Capture the Flag - Level 15
+
+An emulation environment with a set of nodes that run common networked services such as SSH, Kafka,
+etc. Some of the services are vulnerable to simple dictionary attacks as they use weak passwords.
+The task of an attacker agent is to identify the vulnerabilities and exploit them and discover hidden flags
+on the nodes. Conversely, the task of the defender is to harden the defense of the nodes and to detect the
+attacker.
+
+- Number of nodes: 4
+- IDS: Yes (Snort)
+- Traffic generation: Yes
+- Number of flags: 1
+- Vulnerabilities: SSH, FTP, Telnet servers that can be compromised using dictionary attacks
+
+## Architecture
+
+
+
+
+
+## Useful commands
+
+```bash
+make install # Install the emulation in the metastore
+make uninstall # Uninstall the emulation from the metastore
+make clean_config # Clean config files
+docker container ls --all # list all running containers
+docker image ls --all # list all images
+docker system prune # remove unused images and containers
+docker container prune # remove stopped containers
+sudo useradd -rm -d /home/csle_admin -s /bin/bash -g root -G sudo -p "$(openssl passwd -1 'csle@admin-pw_191')" csle_admin
+docker run --name=iperf3 -d --restart=unless-stopped -p 5201:5201/tcp -p 5201:5201/udp mlabbe/iperf3 # Start the iperf server on the host
+iperf3 -R -c # network performance, where is the IP where the iperf server is running e.g. the host 172.31.212.92
+```
+
+## Author & Maintainer
+
+Kim Hammar
+Forough Shahab
+
+## Copyright and license
+
+[LICENSE](../../../../../LICENSE.md)
+
+Creative Commons
+
+(C) 2020-2024, Kim Hammar
\ No newline at end of file
diff --git a/emulation-system/envs/050/level_15/config.py b/emulation-system/envs/050/level_15/config.py
new file mode 100644
index 000000000..1fa01ac8b
--- /dev/null
+++ b/emulation-system/envs/050/level_15/config.py
@@ -0,0 +1,1367 @@
+from typing import Dict, List, Union
+import argparse
+import os
+import multiprocessing
+import csle_common.constants.constants as constants
+import csle_collector.constants.constants as collector_constants
+from csle_collector.client_manager.dao.constant_arrival_config import ConstantArrivalConfig
+from csle_collector.client_manager.dao.workflows_config import WorkflowsConfig
+from csle_collector.client_manager.dao.workflow_service import WorkflowService
+from csle_collector.client_manager.dao.workflow_markov_chain import WorkflowMarkovChain
+from csle_collector.client_manager.dao.client import Client
+from csle_common.dao.emulation_config.topology_config import TopologyConfig
+from csle_common.dao.emulation_config.node_firewall_config import NodeFirewallConfig
+from csle_common.dao.emulation_config.default_network_firewall_config import DefaultNetworkFirewallConfig
+from csle_common.dao.emulation_config.containers_config import ContainersConfig
+from csle_common.dao.emulation_config.node_container_config import NodeContainerConfig
+from csle_common.dao.emulation_config.container_network import ContainerNetwork
+from csle_common.dao.emulation_config.flags_config import FlagsConfig
+from csle_common.dao.emulation_config.node_flags_config import NodeFlagsConfig
+from csle_common.dao.emulation_config.resources_config import ResourcesConfig
+from csle_common.dao.emulation_config.node_resources_config import NodeResourcesConfig
+from csle_common.dao.emulation_config.node_network_config import NodeNetworkConfig
+from csle_common.dao.emulation_config.packet_loss_type import PacketLossType
+from csle_common.dao.emulation_config.packet_delay_distribution_type import PacketDelayDistributionType
+from csle_common.dao.emulation_config.traffic_config import TrafficConfig
+from csle_common.dao.emulation_config.node_traffic_config import NodeTrafficConfig
+from csle_common.dao.emulation_config.users_config import UsersConfig
+from csle_common.dao.emulation_config.node_users_config import NodeUsersConfig
+from csle_common.dao.emulation_config.vulnerabilities_config import VulnerabilitiesConfig
+from csle_common.dao.emulation_config.emulation_env_config import EmulationEnvConfig
+from csle_common.controllers.emulation_env_controller import EmulationEnvController
+from csle_common.dao.emulation_config.client_population_config import ClientPopulationConfig
+from csle_common.dao.emulation_config.kafka_config import KafkaConfig
+from csle_common.dao.emulation_config.kafka_topic import KafkaTopic
+from csle_common.util.experiment_util import ExperimentUtil
+from csle_common.dao.emulation_config.flag import Flag
+from csle_common.dao.emulation_config.node_vulnerability_config import NodeVulnerabilityConfig
+from csle_common.dao.emulation_config.credential import Credential
+from csle_common.dao.emulation_config.vulnerability_type import VulnType
+from csle_common.dao.emulation_config.transport_protocol import TransportProtocol
+from csle_common.dao.emulation_config.node_services_config import NodeServicesConfig
+from csle_common.dao.emulation_config.services_config import ServicesConfig
+from csle_common.dao.emulation_config.network_service import NetworkService
+from csle_common.dao.emulation_config.ovs_config import OVSConfig
+from csle_common.dao.emulation_config.sdn_controller_config import SDNControllerConfig
+from csle_common.dao.emulation_config.user import User
+from csle_common.dao.emulation_action.attacker.emulation_attacker_action import EmulationAttackerAction
+from csle_common.dao.emulation_config.host_manager_config import HostManagerConfig
+from csle_common.dao.emulation_config.snort_ids_manager_config import SnortIDSManagerConfig
+from csle_common.dao.emulation_config.ossec_ids_manager_config import OSSECIDSManagerConfig
+from csle_common.dao.emulation_config.docker_stats_manager_config import DockerStatsManagerConfig
+from csle_common.dao.emulation_config.elk_config import ElkConfig
+from csle_common.dao.emulation_config.beats_config import BeatsConfig
+from csle_common.dao.emulation_config.node_beats_config import NodeBeatsConfig
+
+
+def default_config(name: str, network_id: int = 15, level: int = 15, version: str = "0.5.0",
+ time_step_len_seconds: int = 15) -> EmulationEnvConfig:
+ """
+ Returns the default configuration of the emulation environment
+
+ :param name: the name of the emulation
+ :param network_id: the network id of the emulation
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the emulation environment configuration
+ """
+ containers_cfg = default_containers_config(network_id=network_id, level=level, version=version)
+ flags_cfg = default_flags_config(network_id=network_id)
+ resources_cfg = default_resource_constraints_config(network_id=network_id, level=level)
+ topology_cfg = default_topology_config(network_id=network_id)
+ traffic_cfg = default_traffic_config(network_id=network_id, time_step_len_seconds=time_step_len_seconds)
+ users_cfg = default_users_config(network_id=network_id)
+ vuln_cfg = default_vulns_config(network_id=network_id)
+ kafka_cfg = default_kafka_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ services_cfg = default_services_config(network_id=network_id)
+ descr = "An emulation environment with a set of nodes that run common networked services " \
+ "such as SSH, FTP, Telnet, IRC, Kafka," \
+ " etc. Some of the services are vulnerable to simple dictionary attacks as " \
+ "they use weak passwords." \
+ "The task of an attacker agent is to identify the vulnerabilities and exploit them and " \
+ "discover hidden flags" \
+ "on the nodes. Conversely, the task of the defender is to harden the defense of the nodes " \
+ "and to detect the" \
+ "attacker."
+ static_attackers_cfg = default_static_attacker_sequences(topology_cfg.subnetwork_masks)
+ ovs_cfg = default_ovs_config(network_id=network_id, level=level, version=version)
+ sdn_controller_cfg = default_sdn_controller_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ host_manager_cfg = default_host_manager_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ snort_ids_manager_cfg = default_snort_ids_manager_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ ossec_ids_manager_cfg = default_ossec_ids_manager_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ docker_stats_manager_cfg = default_docker_stats_manager_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ elk_cfg = default_elk_config(network_id=network_id, level=level, version=version,
+ time_step_len_seconds=time_step_len_seconds)
+ beats_cfg = default_beats_config(network_id=network_id)
+ emulation_env_cfg = EmulationEnvConfig(
+ name=name, containers_config=containers_cfg, users_config=users_cfg, flags_config=flags_cfg,
+ vuln_config=vuln_cfg, topology_config=topology_cfg, traffic_config=traffic_cfg, resources_config=resources_cfg,
+ kafka_config=kafka_cfg, services_config=services_cfg,
+ descr=descr, static_attacker_sequences=static_attackers_cfg, ovs_config=ovs_cfg,
+ sdn_controller_config=sdn_controller_cfg, host_manager_config=host_manager_cfg,
+ snort_ids_manager_config=snort_ids_manager_cfg, ossec_ids_manager_config=ossec_ids_manager_cfg,
+ docker_stats_manager_config=docker_stats_manager_cfg, elk_config=elk_cfg,
+ level=level, execution_id=-1, version=version, beats_config=beats_cfg
+ )
+ return emulation_env_cfg
+
+
+def default_containers_config(network_id: int, level: int, version: str) -> ContainersConfig:
+ """
+ Generates default containers config
+
+ :param version: the version of the containers to use
+ :param level: the level parameter of the emulation
+ :param network_id: the network id
+ :return: the ContainersConfig of the emulation
+ """
+ containers = [
+ NodeContainerConfig(
+ name=f"{constants.CONTAINER_IMAGES.CLIENT_1}",
+ os=constants.CONTAINER_OS.CLIENT_1_OS,
+ ips_and_networks=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.254",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH0,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.254",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH2,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ ))
+ ],
+ version=version, level=str(level), restart_policy=constants.DOCKER.ON_FAILURE_3, suffix="_1"),
+ NodeContainerConfig(name=f"{constants.CONTAINER_IMAGES.HACKER_KALI_1}",
+ os=constants.CONTAINER_OS.HACKER_KALI_1_OS,
+ ips_and_networks=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH0,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.191",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH2,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ ))
+ ],
+ version=version, level=str(level),
+ restart_policy=constants.DOCKER.ON_FAILURE_3,
+ suffix="_1"),
+ NodeContainerConfig(name=f"{constants.CONTAINER_IMAGES.ROUTER_2}",
+ os=constants.CONTAINER_OS.ROUTER_2_OS,
+ ips_and_networks=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH0,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ (
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.10",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH2,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.10",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH3,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ ))
+ ],
+ version=version, level=str(level),
+ restart_policy=constants.DOCKER.ON_FAILURE_3,
+ suffix="_1"),
+ NodeContainerConfig(name=f"{constants.CONTAINER_IMAGES.SSH_1}",
+ os=constants.CONTAINER_OS.SSH_1_OS,
+ ips_and_networks=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH0,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.78",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ interface=constants.NETWORKING.ETH2,
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ ))
+ ],
+ version=version, level=str(level),
+ restart_policy=constants.DOCKER.ON_FAILURE_3,
+ suffix="_1")
+ ]
+ containers_cfg = ContainersConfig(
+ containers=containers,
+ agent_ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ router_ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ ids_enabled=True,
+ vulnerable_nodes=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78"
+ ],
+ agent_reachable_nodes=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78"
+ ],
+ networks=[
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ ),
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ ),
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ]
+ )
+ return containers_cfg
+
+
+def default_flags_config(network_id: int) -> FlagsConfig:
+ """
+ Generates default flags config
+
+ :param network_id: the network id
+ :return: The flags confguration
+ """
+ flags = [
+ NodeFlagsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ flags=[Flag(
+ name=f"{constants.COMMON.FLAG_FILENAME_PREFIX}2",
+ path=f"/{constants.COMMANDS.TMP_DIR}/{constants.COMMON.FLAG_FILENAME_PREFIX}2"
+ f"{constants.FILE_PATTERNS.TXT_FILE_SUFFIX}",
+ dir=f"/{constants.COMMANDS.TMP_DIR}/",
+ id=2, requires_root=True, score=1
+ )])
+ ]
+ flags_config = FlagsConfig(node_flag_configs=flags)
+ return flags_config
+
+
+def default_resource_constraints_config(network_id: int, level: int) -> ResourcesConfig:
+ """
+ Generates default resource constraints config
+
+ :param level: the level parameter of the emulation
+ :param network_id: the network id
+ :return: generates the ResourcesConfig
+ """
+ node_resources_configurations = [
+ NodeResourcesConfig(
+ container_name=f"{constants.CSLE.NAME}-"
+ f"{constants.CONTAINER_IMAGES.HACKER_KALI_1}_1-{constants.CSLE.LEVEL}{level}",
+ num_cpus=1, available_memory_gb=4,
+ ips_and_network_configs=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ NodeNetworkConfig(
+ interface=constants.NETWORKING.ETH0,
+ limit_packets_queue=30000, packet_delay_ms=2,
+ packet_delay_jitter_ms=0.5, packet_delay_correlation_percentage=25,
+ packet_delay_distribution=PacketDelayDistributionType.PARETO,
+ packet_loss_type=PacketLossType.GEMODEL,
+ loss_gemodel_p=0.02, loss_gemodel_r=0.97,
+ loss_gemodel_k=0.98, loss_gemodel_h=0.0001, packet_corrupt_percentage=0.02,
+ packet_corrupt_correlation_percentage=25, packet_duplicate_percentage=0.00001,
+ packet_duplicate_correlation_percentage=25, packet_reorder_percentage=2,
+ packet_reorder_correlation_percentage=25, packet_reorder_gap=5,
+ rate_limit_mbit=100, packet_overhead_bytes=0,
+ cell_overhead_bytes=0
+ ))]),
+ NodeResourcesConfig(
+ container_name=f"{constants.CSLE.NAME}-"
+ f"{constants.CONTAINER_IMAGES.CLIENT_1}_1-{constants.CSLE.LEVEL}{level}",
+ num_cpus=min(16, multiprocessing.cpu_count()), available_memory_gb=4,
+ ips_and_network_configs=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.254",
+ NodeNetworkConfig(
+ interface=constants.NETWORKING.ETH0,
+ limit_packets_queue=30000, packet_delay_ms=2,
+ packet_delay_jitter_ms=0.5, packet_delay_correlation_percentage=25,
+ packet_delay_distribution=PacketDelayDistributionType.PARETO,
+ packet_loss_type=PacketLossType.GEMODEL,
+ loss_gemodel_p=0.02, loss_gemodel_r=0.97,
+ loss_gemodel_k=0.98, loss_gemodel_h=0.0001, packet_corrupt_percentage=0.02,
+ packet_corrupt_correlation_percentage=25, packet_duplicate_percentage=0.00001,
+ packet_duplicate_correlation_percentage=25, packet_reorder_percentage=2,
+ packet_reorder_correlation_percentage=25, packet_reorder_gap=5,
+ rate_limit_mbit=10000, packet_overhead_bytes=0,
+ cell_overhead_bytes=0
+ ))]),
+ NodeResourcesConfig(
+ container_name=f"{constants.CSLE.NAME}-"
+ f"{constants.CONTAINER_IMAGES.ROUTER_2}_1-{constants.CSLE.LEVEL}{level}",
+ num_cpus=1, available_memory_gb=4,
+ ips_and_network_configs=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ NodeNetworkConfig(
+ interface=constants.NETWORKING.ETH0,
+ limit_packets_queue=30000, packet_delay_ms=0.1,
+ packet_delay_jitter_ms=0.025, packet_delay_correlation_percentage=25,
+ packet_delay_distribution=PacketDelayDistributionType.PARETO,
+ packet_loss_type=PacketLossType.GEMODEL,
+ loss_gemodel_p=0.0001, loss_gemodel_r=0.999,
+ loss_gemodel_k=0.9999, loss_gemodel_h=0.0001, packet_corrupt_percentage=0.00001,
+ packet_corrupt_correlation_percentage=25, packet_duplicate_percentage=0.00001,
+ packet_duplicate_correlation_percentage=25, packet_reorder_percentage=0.0025,
+ packet_reorder_correlation_percentage=25, packet_reorder_gap=5,
+ rate_limit_mbit=1000, packet_overhead_bytes=0,
+ cell_overhead_bytes=0
+ )),
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f""f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.10",
+ NodeNetworkConfig(
+ interface=constants.NETWORKING.ETH2,
+ limit_packets_queue=30000, packet_delay_ms=2,
+ packet_delay_jitter_ms=0.5, packet_delay_correlation_percentage=25,
+ packet_delay_distribution=PacketDelayDistributionType.PARETO,
+ packet_loss_type=PacketLossType.GEMODEL,
+ loss_gemodel_p=0.02, loss_gemodel_r=0.97,
+ loss_gemodel_k=0.98, loss_gemodel_h=0.0001, packet_corrupt_percentage=0.02,
+ packet_corrupt_correlation_percentage=25, packet_duplicate_percentage=0.00001,
+ packet_duplicate_correlation_percentage=25, packet_reorder_percentage=2,
+ packet_reorder_correlation_percentage=25, packet_reorder_gap=5,
+ rate_limit_mbit=100, packet_overhead_bytes=0,
+ cell_overhead_bytes=0
+ ))]),
+ NodeResourcesConfig(
+ container_name=f"{constants.CSLE.NAME}-"
+ f"{constants.CONTAINER_IMAGES.SSH_1}_1-{constants.CSLE.LEVEL}{level}",
+ num_cpus=1, available_memory_gb=4,
+ ips_and_network_configs=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ NodeNetworkConfig(
+ interface=constants.NETWORKING.ETH0,
+ limit_packets_queue=30000, packet_delay_ms=0.1,
+ packet_delay_jitter_ms=0.025, packet_delay_correlation_percentage=25,
+ packet_delay_distribution=PacketDelayDistributionType.PARETO,
+ packet_loss_type=PacketLossType.GEMODEL,
+ loss_gemodel_p=0.0001, loss_gemodel_r=0.999,
+ loss_gemodel_k=0.9999, loss_gemodel_h=0.0001, packet_corrupt_percentage=0.00001,
+ packet_corrupt_correlation_percentage=25, packet_duplicate_percentage=0.00001,
+ packet_duplicate_correlation_percentage=25, packet_reorder_percentage=0.0025,
+ packet_reorder_correlation_percentage=25, packet_reorder_gap=5,
+ rate_limit_mbit=1000, packet_overhead_bytes=0,
+ cell_overhead_bytes=0
+ ))])
+ ]
+ resources_config = ResourcesConfig(node_resources_configurations=node_resources_configurations)
+ return resources_config
+
+
+def default_topology_config(network_id: int) -> TopologyConfig:
+ """
+ Generates default topology config
+
+ :param network_id: the network id
+ :return: the Topology configuration
+ """
+ node_1 = NodeFirewallConfig(
+ hostname=f"{constants.CONTAINER_IMAGES.ROUTER_2}_1",
+ ips_gw_default_policy_networks=[
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.ACCEPT,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.10",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.ACCEPT,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.10",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ )
+ ],
+ output_accept=set([]),
+ input_accept=set([]),
+ forward_accept=set([]),
+ output_drop=set(), input_drop=set(), forward_drop=set(), routes=set())
+ node_2 = NodeFirewallConfig(
+ hostname=f"{constants.CONTAINER_IMAGES.SSH_1}_1",
+ ips_gw_default_policy_networks=[
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=None,
+ default_gw=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.78",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ )
+ ],
+ output_accept=set([]),
+ input_accept=set([]),
+ forward_accept=set(), output_drop=set(), input_drop=set(), routes=set(), forward_drop=set()
+ )
+
+ node_6 = NodeFirewallConfig(
+ hostname=f"{constants.CONTAINER_IMAGES.HACKER_KALI_1}_1",
+ ips_gw_default_policy_networks=[
+ DefaultNetworkFirewallConfig(
+ ip=None,
+ default_gw=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.10",
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.191",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ )
+ ],
+ output_accept=set([]),
+ input_accept=set([]),
+ forward_accept=set(), output_drop=set(), input_drop=set(), forward_drop=set(),
+ routes=set())
+ node_7 = NodeFirewallConfig(
+ hostname=f"{constants.CONTAINER_IMAGES.CLIENT_1}_1",
+ ips_gw_default_policy_networks=[
+ DefaultNetworkFirewallConfig(
+ ip=None,
+ default_gw=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}"
+ f".{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.10",
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.254",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_1",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ ),
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.254",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.DROP,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ )
+ ],
+ output_accept=set([]),
+ input_accept=set([]),
+ forward_accept=set(), output_drop=set(), input_drop=set(), forward_drop=set(),
+ routes=set())
+ node_configs = [node_1, node_2, node_6, node_7]
+ topology = TopologyConfig(node_configs=node_configs,
+ subnetwork_masks=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.1{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}"
+ ])
+ return topology
+
+
+def default_traffic_config(network_id: int, time_step_len_seconds: int) -> TrafficConfig:
+ """
+ Generates default traffic config
+
+ :param network_id: the network id
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the traffic configuration
+ """
+ traffic_generators = [
+ NodeTrafficConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ commands=(constants.TRAFFIC_COMMANDS.DEFAULT_COMMANDS[constants.CONTAINER_IMAGES.ROUTER_2]
+ + constants.TRAFFIC_COMMANDS.DEFAULT_COMMANDS[
+ constants.TRAFFIC_COMMANDS.GENERIC_COMMANDS]),
+ traffic_manager_port=collector_constants.MANAGER_PORTS.TRAFFIC_MANAGER_DEFAULT_PORT,
+ traffic_manager_log_file=collector_constants.LOG_FILES.TRAFFIC_MANAGER_LOG_FILE,
+ traffic_manager_log_dir=collector_constants.LOG_FILES.TRAFFIC_MANAGER_LOG_DIR,
+ traffic_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS),
+ NodeTrafficConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ commands=(constants.TRAFFIC_COMMANDS.DEFAULT_COMMANDS[constants.CONTAINER_IMAGES.SSH_1]
+ + constants.TRAFFIC_COMMANDS.DEFAULT_COMMANDS[
+ constants.TRAFFIC_COMMANDS.GENERIC_COMMANDS]),
+ traffic_manager_port=collector_constants.MANAGER_PORTS.TRAFFIC_MANAGER_DEFAULT_PORT,
+ traffic_manager_log_file=collector_constants.LOG_FILES.TRAFFIC_MANAGER_LOG_FILE,
+ traffic_manager_log_dir=collector_constants.LOG_FILES.TRAFFIC_MANAGER_LOG_DIR,
+ traffic_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ ]
+ all_ips_and_commands = []
+ for i in range(len(traffic_generators)):
+ all_ips_and_commands.append((traffic_generators[i].ip, traffic_generators[i].commands))
+ workflows_config = WorkflowsConfig(
+ workflow_services=[
+ WorkflowService(id=0, ips_and_commands=all_ips_and_commands)
+ ],
+ workflow_markov_chains=[
+ WorkflowMarkovChain(
+ transition_matrix=[
+ [0.8, 0.2],
+ [0, 1]
+ ],
+ initial_state=0,
+ id=0
+ )
+ ]
+ )
+ client_population_config = ClientPopulationConfig(
+ networks=[ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_2",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.2{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )],
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.254",
+ client_manager_port=collector_constants.MANAGER_PORTS.CLIENT_MANAGER_DEFAULT_PORT,
+ client_time_step_len_seconds=time_step_len_seconds,
+ client_manager_log_dir=collector_constants.LOG_FILES.CLIENT_MANAGER_LOG_DIR,
+ client_manager_log_file=collector_constants.LOG_FILES.CLIENT_MANAGER_LOG_FILE,
+ client_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS,
+ clients=[
+ Client(id=0, workflow_distribution=[1],
+ arrival_config=ConstantArrivalConfig(lamb=20), mu=4, exponential_service_time=True)
+ ],
+ workflows_config=workflows_config)
+ traffic_conf = TrafficConfig(node_traffic_configs=traffic_generators,
+ client_population_config=client_population_config)
+ return traffic_conf
+
+
+def default_beats_config(network_id: int) -> BeatsConfig:
+ """
+ Generates default beats config
+
+ :param network_id: the network id
+ :return: the beats configuration
+ """
+ node_beats_configs = [
+ NodeBeatsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ log_files_paths=collector_constants.LOG_FILES.DEFAULT_LOG_FILE_PATHS,
+ filebeat_modules=[collector_constants.FILEBEAT.SYSTEM_MODULE,
+ collector_constants.FILEBEAT.SNORT_MODULE],
+ kafka_input=False, start_filebeat_automatically=False,
+ start_packetbeat_automatically=False,
+ metricbeat_modules=[collector_constants.METRICBEAT.SYSTEM_MODULE,
+ collector_constants.METRICBEAT.LINUX_MODULE],
+ start_metricbeat_automatically=False,
+ start_heartbeat_automatically=False,
+ heartbeat_hosts_to_monitor=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}"
+ ]),
+ NodeBeatsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ log_files_paths=collector_constants.LOG_FILES.DEFAULT_LOG_FILE_PATHS,
+ filebeat_modules=[collector_constants.FILEBEAT.SYSTEM_MODULE],
+ kafka_input=False, start_filebeat_automatically=False,
+ start_packetbeat_automatically=False,
+ metricbeat_modules=[collector_constants.METRICBEAT.SYSTEM_MODULE,
+ collector_constants.METRICBEAT.LINUX_MODULE],
+ start_metricbeat_automatically=False,
+ start_heartbeat_automatically=False,
+ heartbeat_hosts_to_monitor=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}"
+ ]),
+ NodeBeatsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ log_files_paths=collector_constants.LOG_FILES.DEFAULT_LOG_FILE_PATHS,
+ filebeat_modules=[collector_constants.FILEBEAT.SYSTEM_MODULE,
+ collector_constants.FILEBEAT.KAFKA_MODULE],
+ kafka_input=True, start_filebeat_automatically=False,
+ start_packetbeat_automatically=False,
+ metricbeat_modules=[collector_constants.METRICBEAT.SYSTEM_MODULE,
+ collector_constants.METRICBEAT.LINUX_MODULE,
+ collector_constants.FILEBEAT.KAFKA_MODULE],
+ start_metricbeat_automatically=False,
+ start_heartbeat_automatically=False,
+ heartbeat_hosts_to_monitor=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.254",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.191",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.78"
+ ]),
+ NodeBeatsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ log_files_paths=collector_constants.LOG_FILES.DEFAULT_LOG_FILE_PATHS,
+ filebeat_modules=[collector_constants.FILEBEAT.SYSTEM_MODULE,
+ collector_constants.FILEBEAT.ELASTICSEARCH_MODULE,
+ collector_constants.FILEBEAT.KIBANA_MODULE,
+ collector_constants.FILEBEAT.LOGSTASH_MODULE], kafka_input=False,
+ start_filebeat_automatically=False, start_packetbeat_automatically=False,
+ metricbeat_modules=[collector_constants.METRICBEAT.SYSTEM_MODULE,
+ collector_constants.METRICBEAT.LINUX_MODULE,
+ collector_constants.FILEBEAT.ELASTICSEARCH_MODULE,
+ collector_constants.FILEBEAT.KIBANA_MODULE,
+ collector_constants.FILEBEAT.LOGSTASH_MODULE],
+ start_metricbeat_automatically=False,
+ start_heartbeat_automatically=False,
+ heartbeat_hosts_to_monitor=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.254",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.191",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}.78"
+ ]),
+ NodeBeatsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.254",
+ log_files_paths=collector_constants.LOG_FILES.DEFAULT_LOG_FILE_PATHS,
+ filebeat_modules=[collector_constants.FILEBEAT.SYSTEM_MODULE],
+ kafka_input=False, start_filebeat_automatically=False,
+ start_packetbeat_automatically=False,
+ metricbeat_modules=[collector_constants.METRICBEAT.SYSTEM_MODULE,
+ collector_constants.METRICBEAT.LINUX_MODULE],
+ start_metricbeat_automatically=False,
+ start_heartbeat_automatically=False,
+ heartbeat_hosts_to_monitor=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}"
+ ]),
+ NodeBeatsConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ log_files_paths=collector_constants.LOG_FILES.DEFAULT_LOG_FILE_PATHS,
+ filebeat_modules=[collector_constants.FILEBEAT.SYSTEM_MODULE],
+ kafka_input=False, start_filebeat_automatically=False,
+ start_packetbeat_automatically=False,
+ metricbeat_modules=[collector_constants.METRICBEAT.SYSTEM_MODULE,
+ collector_constants.METRICBEAT.LINUX_MODULE],
+ start_metricbeat_automatically=False,
+ start_heartbeat_automatically=False,
+ heartbeat_hosts_to_monitor=[
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}"
+ ])
+ ]
+ beats_conf = BeatsConfig(node_beats_configs=node_beats_configs, num_elastic_shards=1, reload_enabled=False)
+ return beats_conf
+
+
+def default_kafka_config(network_id: int, level: int, version: str, time_step_len_seconds: int) -> KafkaConfig:
+ """
+ Generates the default kafka configuration
+
+ :param network_id: the id of the emulation network
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the kafka configuration
+ """
+ container = NodeContainerConfig(
+ name=f"{constants.CONTAINER_IMAGES.KAFKA_1}",
+ os=constants.CONTAINER_OS.KAFKA_1_OS,
+ ips_and_networks=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ ],
+ version=version, level=str(level),
+ restart_policy=constants.DOCKER.ON_FAILURE_3, suffix=collector_constants.KAFKA_CONFIG.SUFFIX)
+
+ resources = NodeResourcesConfig(
+ container_name=f"{constants.CSLE.NAME}-"
+ f"{constants.CONTAINER_IMAGES.KAFKA_1}_1-{constants.CSLE.LEVEL}{level}",
+ num_cpus=1, available_memory_gb=4,
+ ips_and_network_configs=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ None)])
+
+ firewall_config = NodeFirewallConfig(
+ hostname=f"{constants.CONTAINER_IMAGES.KAFKA_1}_1",
+ ips_gw_default_policy_networks=[
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.ACCEPT,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.KAFKA_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ )
+ ],
+ output_accept=set([]),
+ input_accept=set([]),
+ forward_accept=set([]),
+ output_drop=set(), input_drop=set(), forward_drop=set(), routes=set())
+
+ topics = [
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.CLIENT_POPULATION_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.CLIENT_POPULATION_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.SNORT_IDS_LOG_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.SNORT_IDS_LOG_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.OSSEC_IDS_LOG_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.OSSEC_IDS_LOG_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.HOST_METRICS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.HOST_METRICS_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.DOCKER_STATS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.DOCKER_STATS_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.ATTACKER_ACTIONS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.ATTACKER_ACTIONS_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.DEFENDER_ACTIONS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.DEFENDER_ACTIONS_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.DOCKER_HOST_STATS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.DOCKER_STATS_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.OPENFLOW_FLOW_STATS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.OPENFLOW_FLOW_STATS_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.OPENFLOW_PORT_STATS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.OPENFLOW_PORT_STATS_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.AVERAGE_OPENFLOW_FLOW_STATS_PER_SWITCH_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.AVERAGE_OPENFLOW_FLOW_STATS_PER_SWITCH_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.AVERAGE_OPENFLOW_PORT_STATS_PER_SWITCH_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.AVERAGE_OPENFLOW_PORT_STATS_PER_SWITCH_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.OPENFLOW_AGG_FLOW_STATS_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.OPENFLOW_AGG_FLOW_STATS_TOPIC_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.SNORT_IDS_RULE_LOG_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.SNORT_IDS_RULE_LOG_ATTRIBUTES
+ ),
+ KafkaTopic(
+ name=collector_constants.KAFKA_CONFIG.SNORT_IDS_IP_LOG_TOPIC_NAME,
+ num_replicas=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_REPLICAS,
+ num_partitions=collector_constants.KAFKA_CONFIG.DEFAULT_NUM_PARTITIONS,
+ retention_time_hours=collector_constants.KAFKA_CONFIG.DEFAULT_RETENTION_TIME_HOURS,
+ attributes=collector_constants.KAFKA_CONFIG.SNORT_IDS_IP_LOG_ATTRIBUTES
+ )
+ ]
+
+ config = KafkaConfig(container=container, resources=resources, topics=topics, firewall_config=firewall_config,
+ version=version,
+ kafka_port=collector_constants.KAFKA.PORT,
+ kafka_port_external=collector_constants.KAFKA.EXTERNAL_PORT,
+ kafka_manager_port=collector_constants.MANAGER_PORTS.KAFKA_MANAGER_DEFAULT_PORT,
+ time_step_len_seconds=time_step_len_seconds,
+ kafka_manager_log_file=collector_constants.LOG_FILES.KAFKA_MANAGER_LOG_FILE,
+ kafka_manager_log_dir=collector_constants.LOG_FILES.KAFKA_MANAGER_LOG_DIR,
+ kafka_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ return config
+
+
+def default_users_config(network_id: int) -> UsersConfig:
+ """
+ Generates default users config
+
+ :param network_id: the network id
+ :return: generates the UsersConfig
+ """
+ users = [
+ NodeUsersConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ users=[User(username="agent", pw="agent", root=True)]),
+ NodeUsersConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10", users=[
+ User(username="admin", pw="admin1235912", root=True),
+ User(username="jessica", pw="water", root=False)
+ ]),
+ NodeUsersConfig(ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78", users=[
+ User(username="admin", pw="test32121", root=True),
+ User(username="user1", pw="123123", root=True)
+ ])
+ ]
+ users_conf = UsersConfig(users_configs=users)
+ return users_conf
+
+
+def default_vulns_config(network_id: int) -> VulnerabilitiesConfig:
+ """
+ Generates default vulnerabilities config
+
+ :param network_id: the network id
+ :return: the vulnerability config
+ """
+ vulns = [
+ NodeVulnerabilityConfig(
+ name=constants.EXPLOIT_VULNERABILITES.SSH_DICT_SAME_USER_PASS,
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ vuln_type=VulnType.WEAK_PW,
+ credentials=[Credential(username="puppet", pw="puppet", root=True,
+ service=constants.SSH.SERVICE_NAME,
+ protocol=TransportProtocol.TCP,
+ port=constants.SSH.DEFAULT_PORT)],
+ cvss=constants.EXPLOIT_VULNERABILITES.WEAK_PASSWORD_CVSS,
+ cve=None,
+ root=True, port=constants.SSH.DEFAULT_PORT, protocol=TransportProtocol.TCP,
+ service=constants.SSH.SERVICE_NAME)
+ ]
+ vulns_config = VulnerabilitiesConfig(node_vulnerability_configs=vulns)
+ return vulns_config
+
+
+def default_services_config(network_id: int) -> ServicesConfig:
+ """
+ Generates default services config
+
+ :param network_id: the network id
+ :return: The services configuration
+ """
+ services_configs = [
+ NodeServicesConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.254",
+ services=[
+ NetworkService(protocol=TransportProtocol.TCP, port=constants.SSH.DEFAULT_PORT,
+ name=constants.SSH.SERVICE_NAME, credentials=[])
+ ]
+ ),
+ NodeServicesConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.EXTERNAL_NETWORK.NETWORK_ID_THIRD_OCTET}.191",
+ services=[
+ NetworkService(protocol=TransportProtocol.TCP, port=constants.SSH.DEFAULT_PORT,
+ name=constants.SSH.SERVICE_NAME, credentials=[])
+ ]
+ ),
+ NodeServicesConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.10",
+ services=[
+ NetworkService(protocol=TransportProtocol.TCP, port=constants.SSH.DEFAULT_PORT,
+ name=constants.SSH.SERVICE_NAME, credentials=[])
+ ]
+ ),
+ NodeServicesConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}.2.78",
+ services=[
+ NetworkService(protocol=TransportProtocol.TCP, port=constants.SSH.DEFAULT_PORT,
+ name=constants.SSH.SERVICE_NAME, credentials=[]),
+ NetworkService(protocol=TransportProtocol.TCP, port=constants.DNS.DEFAULT_PORT,
+ name=constants.DNS.SERVICE_NAME, credentials=[]),
+ NetworkService(protocol=TransportProtocol.TCP, port=constants.HTTP.DEFAULT_PORT,
+ name=constants.HTTP.SERVICE_NAME, credentials=[])
+ ]
+ )
+ ]
+ service_cfg = ServicesConfig(
+ services_configs=services_configs
+ )
+ return service_cfg
+
+
+def default_static_attacker_sequences(subnet_masks: List[str]) -> Dict[str, List[EmulationAttackerAction]]:
+ """
+ Generates default attacker sequences config
+
+ :param subnetmasks: list of subnet masks for the emulation
+ :return: the default static attacker sequences configuration
+ """
+ return {}
+
+
+def default_ovs_config(network_id: int, level: int, version: str) -> OVSConfig:
+ """
+ Generates default OVS config
+
+ :param network_id: the network id of the emulation
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :return: the default OVS config
+ """
+ ovs_config = OVSConfig(switch_configs=[])
+ return ovs_config
+
+
+def default_sdn_controller_config(network_id: int, level: int, version: str, time_step_len_seconds: int) \
+ -> Union[None, SDNControllerConfig]:
+ """
+ Generates the default SDN controller config
+
+ :param network_id: the network id of the emulation
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the default SDN Controller config
+ """
+ return None
+
+
+def default_host_manager_config(network_id: int, level: int, version: str, time_step_len_seconds: int) \
+ -> HostManagerConfig:
+ """
+ Generates the default host manager configuration
+
+ :param network_id: the id of the emulation network
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the host manager configuration
+ """
+ config = HostManagerConfig(version=version, time_step_len_seconds=time_step_len_seconds,
+ host_manager_port=collector_constants.MANAGER_PORTS.HOST_MANAGER_DEFAULT_PORT,
+ host_manager_log_file=collector_constants.LOG_FILES.HOST_MANAGER_LOG_FILE,
+ host_manager_log_dir=collector_constants.LOG_FILES.HOST_MANAGER_LOG_DIR,
+ host_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ return config
+
+
+def default_snort_ids_manager_config(network_id: int, level: int, version: str, time_step_len_seconds: int) \
+ -> SnortIDSManagerConfig:
+ """
+ Generates the default Snort IDS manager configuration
+
+ :param network_id: the id of the emulation network
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the Snort IDS manager configuration
+ """
+ config = SnortIDSManagerConfig(
+ version=version, time_step_len_seconds=time_step_len_seconds,
+ snort_ids_manager_port=collector_constants.MANAGER_PORTS.SNORT_IDS_MANAGER_DEFAULT_PORT,
+ snort_ids_manager_log_dir=collector_constants.LOG_FILES.SNORT_IDS_MANAGER_LOG_DIR,
+ snort_ids_manager_log_file=collector_constants.LOG_FILES.SNORT_IDS_MANAGER_LOG_FILE,
+ snort_ids_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ return config
+
+
+def default_ossec_ids_manager_config(network_id: int, level: int, version: str, time_step_len_seconds: int) \
+ -> OSSECIDSManagerConfig:
+ """
+ Generates the default OSSEC IDS manager configuration
+
+ :param network_id: the id of the emulation network
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the OSSEC IDS manager configuration
+ """
+ config = OSSECIDSManagerConfig(
+ version=version, time_step_len_seconds=time_step_len_seconds,
+ ossec_ids_manager_port=collector_constants.MANAGER_PORTS.OSSEC_IDS_MANAGER_DEFAULT_PORT,
+ ossec_ids_manager_log_file=collector_constants.LOG_FILES.OSSEC_IDS_MANAGER_LOG_FILE,
+ ossec_ids_manager_log_dir=collector_constants.LOG_FILES.OSSEC_IDS_MANAGER_LOG_DIR,
+ ossec_ids_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ return config
+
+
+def default_docker_stats_manager_config(network_id: int, level: int, version: str, time_step_len_seconds: int) \
+ -> DockerStatsManagerConfig:
+ """
+ Generates the default docker stats manager configuration
+
+ :param network_id: the id of the emulation network
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the docker stats manager configuration
+ """
+ config = DockerStatsManagerConfig(
+ version=version, time_step_len_seconds=time_step_len_seconds,
+ docker_stats_manager_port=collector_constants.MANAGER_PORTS.DOCKER_STATS_MANAGER_DEFAULT_PORT,
+ docker_stats_manager_log_file=collector_constants.LOG_FILES.DOCKER_STATS_MANAGER_LOG_FILE,
+ docker_stats_manager_log_dir=collector_constants.LOG_FILES.DOCKER_STATS_MANAGER_LOG_DIR,
+ docker_stats_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ return config
+
+
+def default_elk_config(network_id: int, level: int, version: str, time_step_len_seconds: int) -> ElkConfig:
+ """
+ Generates the default ELK configuration
+
+ :param network_id: the id of the emulation network
+ :param level: the level of the emulation
+ :param version: the version of the emulation
+ :param time_step_len_seconds: default length of a time-step in the emulation
+ :return: the ELK configuration
+ """
+ container = NodeContainerConfig(
+ name=f"{constants.CONTAINER_IMAGES.ELK_1}",
+ os=constants.CONTAINER_OS.ELK_1_OS,
+ ips_and_networks=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )),
+ ],
+ version=version, level=str(level),
+ restart_policy=constants.DOCKER.ON_FAILURE_3, suffix=collector_constants.ELK_CONFIG.SUFFIX)
+
+ resources = NodeResourcesConfig(
+ container_name=f"{constants.CSLE.NAME}-"
+ f"{constants.CONTAINER_IMAGES.ELK_1}_1-{constants.CSLE.LEVEL}{level}",
+ num_cpus=2, available_memory_gb=16,
+ ips_and_network_configs=[
+ (f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ None)])
+
+ firewall_config = NodeFirewallConfig(
+ hostname=f"{constants.CONTAINER_IMAGES.ELK_1}_1",
+ ips_gw_default_policy_networks=[
+ DefaultNetworkFirewallConfig(
+ ip=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}."
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_FOURTH_OCTET}",
+ default_gw=None,
+ default_input=constants.FIREWALL.ACCEPT,
+ default_output=constants.FIREWALL.ACCEPT,
+ default_forward=constants.FIREWALL.ACCEPT,
+ network=ContainerNetwork(
+ name=f"{constants.CSLE.CSLE_NETWORK_PREFIX}{network_id}_"
+ f"{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}",
+ subnet_mask=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}"
+ f"{network_id}.{collector_constants.ELK_CONFIG.NETWORK_ID_THIRD_OCTET}"
+ f"{constants.CSLE.CSLE_EDGE_SUBNETMASK_SUFFIX}",
+ subnet_prefix=f"{constants.CSLE.CSLE_SUBNETMASK_PREFIX}{network_id}",
+ bitmask=constants.CSLE.CSLE_EDGE_BITMASK
+ )
+ )
+ ],
+ output_accept=set([]),
+ input_accept=set([]),
+ forward_accept=set([]),
+ output_drop=set(), input_drop=set(), forward_drop=set(), routes=set())
+
+ config = ElkConfig(version=version, time_step_len_seconds=time_step_len_seconds,
+ elastic_port=collector_constants.ELK.ELASTIC_PORT,
+ kibana_port=collector_constants.ELK.KIBANA_PORT,
+ logstash_port=collector_constants.ELK.LOGSTASH_PORT,
+ elk_manager_port=collector_constants.MANAGER_PORTS.ELK_MANAGER_DEFAULT_PORT,
+ container=container,
+ resources=resources, firewall_config=firewall_config,
+ elk_manager_log_file=collector_constants.LOG_FILES.ELK_MANAGER_LOG_FILE,
+ elk_manager_log_dir=collector_constants.LOG_FILES.ELK_MANAGER_LOG_DIR,
+ elk_manager_max_workers=collector_constants.GRPC_WORKERS.DEFAULT_MAX_NUM_WORKERS)
+ return config
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser()
+ parser.add_argument("-i", "--install", help="Boolean parameter, if true, install config",
+ action="store_true")
+ parser.add_argument("-u", "--uninstall", help="Boolean parameter, if true, uninstall config",
+ action="store_true")
+ args = parser.parse_args()
+ config = default_config(name="csle-level15-050", network_id=15, level=15, version="0.5.0", time_step_len_seconds=30)
+ ExperimentUtil.write_emulation_config_file(config, ExperimentUtil.default_emulation_config_path())
+
+ if args.install:
+ EmulationEnvController.install_emulation(config=config)
+ img_path = ExperimentUtil.default_emulation_picture_path()
+ if os.path.exists(img_path):
+ encoded_image_str = ExperimentUtil.read_env_picture(img_path)
+ EmulationEnvController.save_emulation_image(img=encoded_image_str, emulation_name=config.name)
+ if args.uninstall:
+ EmulationEnvController.uninstall_emulation(config=config)
\ No newline at end of file
diff --git a/emulation-system/envs/050/level_15/env.png b/emulation-system/envs/050/level_15/env.png
new file mode 100644
index 000000000..6e90abd42
Binary files /dev/null and b/emulation-system/envs/050/level_15/env.png differ
diff --git a/emulation-system/envs/050/level_15/test_config.py b/emulation-system/envs/050/level_15/test_config.py
new file mode 100644
index 000000000..aff7dd754
--- /dev/null
+++ b/emulation-system/envs/050/level_15/test_config.py
@@ -0,0 +1,34 @@
+from config import default_config
+
+
+class TestEmulationConfigSuite:
+ """
+ Test suite for the emulation configuration for 'level-4'
+ """
+
+ def test_create_config(self) -> None:
+ """
+ Tests creation of the emulation configuration
+
+ :return: None
+ """
+ config = default_config(name="csle-level15-050", network_id=15, level=15, version="0.5.0",
+ time_step_len_seconds=15)
+ assert config.vuln_config is not None
+ assert config.containers_config is not None
+ assert config.flags_config is not None
+ assert config.resources_config is not None
+ assert config.topology_config is not None
+ assert config.traffic_config is not None
+ assert config.users_config is not None
+ assert config.vuln_config is not None
+ assert config.kafka_config is not None
+ assert config.services_config is not None
+ assert config.static_attacker_sequences is not None
+ assert config.ovs_config is not None
+ assert config.host_manager_config is not None
+ assert config.snort_ids_manager_config is not None
+ assert config.ossec_ids_manager_config is not None
+ assert config.docker_stats_manager_config is not None
+ assert config.elk_config is not None
+ assert config.beats_config is not None
diff --git a/emulation-system/envs/Makefile b/emulation-system/envs/Makefile
index 56be4b15f..f1ba89280 100644
--- a/emulation-system/envs/Makefile
+++ b/emulation-system/envs/Makefile
@@ -41,6 +41,9 @@ install_level_13:
install_level_14:
cd 050/level_14/ && $(MAKE) install
+install_level_15:
+ cd 050/level_15/ && $(MAKE) install
+
# Installs all emulations
install:
cd 050/level_1/ && $(MAKE) install
@@ -57,6 +60,7 @@ install:
cd 050/level_12/ && $(MAKE) install
cd 050/level_13/ && $(MAKE) install
cd 050/level_14/ && $(MAKE) install
+ cd 050/level_15/ && $(MAKE) install
# Targets for uninstalling each individual env
uninstall_level_1:
@@ -101,6 +105,9 @@ uninstall_level_13:
uninstall_level_14:
cd 050/level_14/ && $(MAKE) uninstall
+uninstall_level_15:
+ cd 050/level_15/ && $(MAKE) uninstall
+
# Uninstalls all emulations
uninstall:
cd 050/level_1/ && $(MAKE) uninstall
@@ -117,6 +124,7 @@ uninstall:
cd 050/level_12/ && $(MAKE) uninstall
cd 050/level_13/ && $(MAKE) uninstall
cd 050/level_14/ && $(MAKE) uninstall
+ cd 050/level_15/ && $(MAKE) uninstall
# Targets for cleaning the config each individual env
clean_config_level_1:
@@ -161,6 +169,9 @@ clean_config_level_13:
clean_config_level_14:
cd 050/level_14/ && $(MAKE) clean_config
+clean_config_level_15:
+ cd 050/level_15/ && $(MAKE) clean_config
+
# Cleans the materialized configuration of each emulation
clean_config:
cd 050/level_1/ && $(MAKE) clean_config
@@ -177,3 +188,4 @@ clean_config:
cd 050/level_12/ && $(MAKE) clean_config
cd 050/level_13/ && $(MAKE) clean_config
cd 050/level_14/ && $(MAKE) clean_config
+ cd 050/level_15/ && $(MAKE) clean_config