207 lines
9.1 KiB
Plaintext
207 lines
9.1 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 1,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"%load_ext autoreload\n",
|
|
"%autoreload 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 2,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"import yaml\n",
|
|
"from primaite.simulator.sim_container import Simulation\n",
|
|
"from primaite.simulator.network.hardware.nodes.computer import Computer\n",
|
|
"from primaite.simulator.network.hardware.nodes.server import Server\n",
|
|
"from primaite.simulator.network.hardware.nodes.switch import Switch\n",
|
|
"from primaite.simulator.network.hardware.nodes.router import Router\n",
|
|
"\n",
|
|
"from primaite.simulator.system.applications.database_client import DatabaseClient\n",
|
|
"from primaite.simulator.system.services.database_service import DatabaseService\n",
|
|
"from primaite.simulator.system.services.dns_client import DNSClient\n",
|
|
"from primaite.simulator.system.services.dns_server import DNSServer\n",
|
|
"from primaite.simulator.system.services.red_services.data_manipulation_bot import DataManipulationBot\n",
|
|
"\n",
|
|
"\n",
|
|
"from primaite.simulator.network.hardware.nodes.router import ACLAction\n",
|
|
"from primaite.simulator.network.transmission.network_layer import IPProtocol\n",
|
|
"from primaite.simulator.network.transmission.transport_layer import Port\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": 5,
|
|
"metadata": {},
|
|
"outputs": [
|
|
{
|
|
"name": "stderr",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"2023-09-26 10:51:10,388: Added node 48e6cb0b-f351-47f6-b837-df9443f9db26 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,390::WARNING::primaite.simulator.network.container::181::Can't add node 48e6cb0b-f351-47f6-b837-df9443f9db26. It is already in the network.\n",
|
|
"2023-09-26 10:51:10,394: Added node 6a969d4d-e0af-402e-b576-2a787505f7c7 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,397: Added node c58e6f17-dbf1-4c6a-9dbf-d60883c6d948 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,401: Added node 7f2a418d-2d0b-4f02-beb3-5703fc5035c8 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,408: Added node 967417fa-2300-4ee1-8ba0-7a4d055d5d30 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,413: Added node 80c1c99b-4c7a-41fb-86f0-b93c35c3b497 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,418: Added node 9a11dd40-9243-4510-9b43-9f247f669ad2 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,424: Added node 81fff4a6-35c8-4933-bb6c-fd8fd49315fe to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n",
|
|
"2023-09-26 10:51:10,429: Added node 7cc11532-3f65-4c65-a4df-af2c6318a976 to Network 7250d818-ec1b-4940-bb87-8e05fea87fe9\n"
|
|
]
|
|
},
|
|
{
|
|
"name": "stdout",
|
|
"output_type": "stream",
|
|
"text": [
|
|
"service type not found DatabaseBackup\n",
|
|
"service type not found WebBrowser\n"
|
|
]
|
|
}
|
|
],
|
|
"source": [
|
|
"# import yaml\n",
|
|
"\n",
|
|
"\n",
|
|
"class PrimaiteSession:\n",
|
|
"\n",
|
|
" def __init__(self):\n",
|
|
" self.simulation: Simulation\n",
|
|
" self.agents = []\n",
|
|
"\n",
|
|
" @classmethod\n",
|
|
" def from_config(cls, cfg_path):\n",
|
|
" ref_to_uuid = {}\n",
|
|
"\n",
|
|
" game = cls()\n",
|
|
" with open(cfg_path, 'r') as file:\n",
|
|
" conf = yaml.safe_load(file)\n",
|
|
" \n",
|
|
" #1. create nodes \n",
|
|
" sim = Simulation()\n",
|
|
" net = sim.network\n",
|
|
" nodes_cfg = conf['simulation']['network']['nodes']\n",
|
|
" links_cfg = conf['simulation']['network']['links']\n",
|
|
" for node_cfg in nodes_cfg:\n",
|
|
" node_ref = node_cfg['ref']\n",
|
|
" n_type = node_cfg['type']\n",
|
|
" if n_type == 'computer':\n",
|
|
" new_node = Computer(hostname = node_cfg['hostname'], \n",
|
|
" ip_address = node_cfg['ip_address'], \n",
|
|
" subnet_mask = node_cfg['subnet_mask'], \n",
|
|
" default_gateway = node_cfg['default_gateway'],\n",
|
|
" dns_server = node_cfg['dns_server'])\n",
|
|
" elif n_type == 'server':\n",
|
|
" new_node = Server(hostname = node_cfg['hostname'], \n",
|
|
" ip_address = node_cfg['ip_address'], \n",
|
|
" subnet_mask = node_cfg['subnet_mask'], \n",
|
|
" default_gateway = node_cfg['default_gateway'],\n",
|
|
" dns_server = node_cfg.get('dns_server'))\n",
|
|
" elif n_type == 'switch':\n",
|
|
" new_node = Switch(hostname = node_cfg['hostname'],\n",
|
|
" num_ports = node_cfg.get('num_ports'))\n",
|
|
" elif n_type == 'router':\n",
|
|
" new_node = Router(hostname=node_cfg['hostname'],\n",
|
|
" num_ports = node_cfg.get('num_ports'))\n",
|
|
" if 'ports' in node_cfg:\n",
|
|
" for port_num, port_cfg in node_cfg['ports'].items():\n",
|
|
" new_node.configure_port(port=port_num, \n",
|
|
" ip_address=port_cfg['ip_address'],\n",
|
|
" subnet_mask=port_cfg['subnet_mask'])\n",
|
|
" if 'acl' in node_cfg:\n",
|
|
" for r_num, r_cfg in node_cfg['acl'].items():\n",
|
|
" # excuse the uncommon walrus operator ` := `. It's just here as a shorthand, so that we can do\n",
|
|
" # both of these things once: check if a key is defined, access and convert it to a \n",
|
|
" # Port/IPProtocol. TODO Refactor\n",
|
|
" new_node.acl.add_rule(\n",
|
|
" action = ACLAction[r_cfg['action']],\n",
|
|
" src_port = None if not (p:=r_cfg.get('src_port')) else Port[p],\n",
|
|
" dst_port = None if not (p:=r_cfg.get('dst_port')) else Port[p],\n",
|
|
" protocol = None if not (p:=r_cfg.get('protocol')) else IPProtocol[p],\n",
|
|
" src_ip_address = r_cfg.get('ip_address'),\n",
|
|
" dst_ip_address = r_cfg.get('ip_address'),\n",
|
|
" position = r_num\n",
|
|
" )\n",
|
|
" if 'services' in node_cfg:\n",
|
|
" for service_cfg in node_cfg['services']:\n",
|
|
" service_ref = service_cfg['ref']\n",
|
|
" service_type = service_cfg['type']\n",
|
|
" service_types_mapping = {\n",
|
|
" 'DNSClient': DNSClient, # key is equal to the 'name' attr of the service class itself.\n",
|
|
" 'DNSServer' : DNSServer,\n",
|
|
" 'DatabaseClient': DatabaseClient,\n",
|
|
" 'DatabaseService': DatabaseService,\n",
|
|
" # 'database_backup': ,\n",
|
|
" 'DataManipulationBot': DataManipulationBot,\n",
|
|
" # 'web_browser'\n",
|
|
" }\n",
|
|
" if service_type in service_types_mapping:\n",
|
|
" new_node.software_manager.install(service_types_mapping[service_type])\n",
|
|
" service_obj = new_node.software_manager.software[service_type]\n",
|
|
" ref_to_uuid[service_ref] = service_obj.uuid\n",
|
|
" else:\n",
|
|
" print(f\"service type not found {service_type}\")\n",
|
|
"\n",
|
|
"\n",
|
|
" net.add_node(new_node)\n",
|
|
" ref_to_uuid[node_ref] = new_node.uuid\n",
|
|
"\n",
|
|
"\n",
|
|
" #2. start/setup simulation objects\n",
|
|
" #3. create agents\n",
|
|
" #4. set up agents' actions and observation spaces.\n",
|
|
" game.simulation = sim\n",
|
|
" return game\n",
|
|
"\n",
|
|
"s = PrimaiteSession.from_config('example_config.yaml')\n",
|
|
"# print(s.simulation.describe_state())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"print(s.simulation.describe_state())"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": []
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "venv",
|
|
"language": "python",
|
|
"name": "python3"
|
|
},
|
|
"language_info": {
|
|
"codemirror_mode": {
|
|
"name": "ipython",
|
|
"version": 3
|
|
},
|
|
"file_extension": ".py",
|
|
"mimetype": "text/x-python",
|
|
"name": "python",
|
|
"nbconvert_exporter": "python",
|
|
"pygments_lexer": "ipython3",
|
|
"version": "3.10.12"
|
|
},
|
|
"orig_nbformat": 4
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 2
|
|
}
|