Merged PR 620: 4.0.0 changes into dev
Related work items: #2869, #2887, #2912, #3029, #3060, #3062, #3075
This commit is contained in:
@@ -14,31 +14,36 @@ parameters:
|
||||
- name: matrix
|
||||
type: object
|
||||
default:
|
||||
# - job_name: 'UbuntuPython38'
|
||||
# py: '3.8'
|
||||
# img: 'ubuntu-latest'
|
||||
# every_time: false
|
||||
# publish_coverage: false
|
||||
- job_name: 'UbuntuPython311'
|
||||
py: '3.11'
|
||||
- job_name: 'UbuntuPython39'
|
||||
py: '3.9'
|
||||
img: 'ubuntu-latest'
|
||||
every_time: false
|
||||
publish_coverage: false
|
||||
- job_name: 'UbuntuPython310'
|
||||
py: '3.10'
|
||||
img: 'ubuntu-latest'
|
||||
every_time: true
|
||||
publish_coverage: true
|
||||
# - job_name: 'WindowsPython38'
|
||||
# py: '3.8'
|
||||
# img: 'windows-latest'
|
||||
# every_time: false
|
||||
# publish_coverage: false
|
||||
- job_name: 'UbuntuPython311'
|
||||
py: '3.11'
|
||||
img: 'ubuntu-latest'
|
||||
every_time: false
|
||||
publish_coverage: false
|
||||
- job_name: 'WindowsPython39'
|
||||
py: '3.9'
|
||||
img: 'windows-latest'
|
||||
every_time: false
|
||||
publish_coverage: false
|
||||
- job_name: 'WindowsPython311'
|
||||
py: '3.11'
|
||||
img: 'windows-latest'
|
||||
every_time: false
|
||||
publish_coverage: false
|
||||
# - job_name: 'MacOSPython38'
|
||||
# py: '3.8'
|
||||
# img: 'macOS-latest'
|
||||
# every_time: false
|
||||
# publish_coverage: false
|
||||
- job_name: 'MacOSPython39'
|
||||
py: '3.9'
|
||||
img: 'macOS-latest'
|
||||
every_time: false
|
||||
publish_coverage: false
|
||||
- job_name: 'MacOSPython311'
|
||||
py: '3.11'
|
||||
img: 'macOS-latest'
|
||||
@@ -63,7 +68,7 @@ stages:
|
||||
displayName: 'Use Python ${{ item.py }}'
|
||||
|
||||
- script: |
|
||||
python -m pip install pre-commit
|
||||
python -m pip install pre-commit>=6.1
|
||||
pre-commit install
|
||||
pre-commit run --all-files
|
||||
displayName: 'Run pre-commits'
|
||||
@@ -71,7 +76,6 @@ stages:
|
||||
- script: |
|
||||
python -m pip install --upgrade pip==23.0.1
|
||||
pip install wheel==0.38.4 --upgrade
|
||||
pip install setuptools==66 --upgrade
|
||||
pip install build==0.10.0
|
||||
pip install pytest-azurepipelines
|
||||
displayName: 'Install build dependencies'
|
||||
@@ -109,10 +113,8 @@ stages:
|
||||
- script: |
|
||||
pytest --nbmake -n=auto src/primaite/notebooks --junit-xml=./notebook-tests/notebooks.xml
|
||||
notebooks_exit_code=$?
|
||||
pytest --nbmake -n=auto src/primaite/simulator/_package_data --junit-xml=./notebook-tests/package-notebooks.xml
|
||||
package_notebooks_exit_code=$?
|
||||
# Fail step if either of these do not have exit code 0
|
||||
if [ $notebooks_exit_code -ne 0 ] || [ $package_notebooks_exit_code -ne 0 ]; then
|
||||
# Fail step if exit code not equal to 0
|
||||
if [ $notebooks_exit_code -ne 0 ]; then
|
||||
exit 1
|
||||
fi
|
||||
displayName: 'Run notebooks on Linux and macOS'
|
||||
@@ -122,11 +124,8 @@ stages:
|
||||
- script: |
|
||||
pytest --nbmake -n=auto src/primaite/notebooks --junit-xml=./notebook-tests/notebooks.xml
|
||||
set notebooks_exit_code=%ERRORLEVEL%
|
||||
pytest --nbmake -n=auto src/primaite/simulator/_package_data --junit-xml=./notebook-tests/package-notebooks.xml
|
||||
set package_notebooks_exit_code=%ERRORLEVEL%
|
||||
rem Fail step if either of these do not have exit code 0
|
||||
rem Fail step if exit code not equal to 0
|
||||
if %notebooks_exit_code% NEQ 0 exit /b 1
|
||||
if %package_notebooks_exit_code% NEQ 0 exit /b 1
|
||||
displayName: 'Run notebooks on Windows'
|
||||
condition: eq(variables['Agent.OS'], 'Windows_NT')
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: ensure-copyright-clause
|
||||
name: ensure copyright clause
|
||||
entry: python copyright_clause_pre_commit_hook.py
|
||||
language: python
|
||||
# - repo: local
|
||||
# hooks:
|
||||
# - id: ensure-copyright-clause
|
||||
# name: ensure copyright clause
|
||||
# entry: python copyright_clause_pre_commit_hook.py
|
||||
# language: python
|
||||
- repo: http://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
@@ -31,7 +31,7 @@ repos:
|
||||
- id: isort
|
||||
args: [ "--profile", "black" ]
|
||||
- repo: http://github.com/PyCQA/flake8
|
||||
rev: 6.0.0
|
||||
rev: 6.1.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
|
||||
41
CHANGELOG.md
41
CHANGELOG.md
@@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [4.0.0] = TBC
|
||||
|
||||
### Added
|
||||
- Log observation space data by episode and step.
|
||||
- Added `show_history` method to Agents, allowing you to view actions taken by an agent per step. By default, `do-nothing` actions are omitted.
|
||||
- New ``node-send-local-command`` action implemented which grants agents the ability to execute commands locally. (Previously limited to remote only)
|
||||
- Added ability to set the observation threshold for NMNE, file access and application executions
|
||||
|
||||
### Changed
|
||||
- Agents now follow a common configuration format, simplifying the configuration of agents and their extensibilty.
|
||||
- Actions within PrimAITE are now extensible, allowing for plugin support.
|
||||
- Added a config schema to `ObservationManager`, `ActionManager`, and `RewardFunction`.
|
||||
- Streamlined the way agents are created from config
|
||||
- Agent config no longer requires a dummy action space if the action space is empty, the same applies for observation space and reward function
|
||||
- Actions now support a config schema, to allow yaml data validation and default parameter values
|
||||
- Action parameters are no longer defined through IDs, instead meaningful data is provided directly in the action map
|
||||
- Test and example YAMLs have been updated to match the new agent and action schemas, such as:
|
||||
- Removed empty action spaces, observation spaces, or reward spaces for agent which didn't use them
|
||||
- Relabeled action parameters to match the new action config schemas, and updated the values to no longer rely on indices
|
||||
- Removed action space options which were previously used for assigning meaning to action space IDs
|
||||
- Updated tests that don't use YAMLs to still use the new action and agent schemas
|
||||
- Nodes now use a config schema and are extensible, allowing for plugin support.
|
||||
- Node tests have been updated to use the new node config schemas when not using YAML files.
|
||||
- ACLs are no longer applied to layer-2 traffic.
|
||||
- Random number seed values are recorded in simulation/seed.log if the seed is set in the config file
|
||||
or `generate_seed_value` is set to `true`.
|
||||
- ARP .show() method will now include the port number associated with each entry.
|
||||
- Added `services_requires_scan` and `applications_requires_scan` to agent observation space config to allow the agents to be able to see actual health states of services and applications without requiring scans (Default `True`, set to `False` to allow agents to see actual health state without scanning).
|
||||
- Updated the `Terminal` class to provide response information when sending remote command execution.
|
||||
|
||||
### Fixed
|
||||
- DNS client no longer fails to check its cache if a DNS server address is missing.
|
||||
- DNS client now correctly inherits the node's DNS address configuration setting.
|
||||
|
||||
|
||||
## [3.3.0] - 2024-09-04
|
||||
|
||||
## [3.4.0]
|
||||
|
||||
@@ -36,11 +72,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Added reward calculation details to AgentHistoryItem.
|
||||
- Added a new Privilege-Escalation-and Data-Loss-Example.ipynb notebook with a realistic cyber scenario focusing on
|
||||
internal privilege escalation and data loss through the manipulation of SSH access and Access Control Lists (ACLs).
|
||||
- Added a new extensible `NetworkNodeAdder` class for convenient addition of sets of nodes based on a simplified config.
|
||||
|
||||
### Changed
|
||||
- File and folder observations can now be configured to always show the true health status, or require scanning like before.
|
||||
- It's now possible to disable stickiness on reward components, meaning their value returns to 0 during timesteps where agent don't issue the corresponding action. Affects `GreenAdminDatabaseUnreachablePenalty`, `WebpageUnavailablePenalty`, `WebServer404Penalty`
|
||||
- Node observations can now be configured to show the number of active local and remote logins.
|
||||
- Ports and IP Protocols no longer use enums. They are defined in dictionary lookups and are handled by custom validation to enable extensibility with plugins.
|
||||
- Changed AirSpaceFrequency to a data transfer object with a registry to allow extensibility
|
||||
- Changed the Office LAN creation convenience function to follow the new `NetworkNodeAdder` pattern. Office LANs can now also be defined in YAML config.
|
||||
|
||||
### Fixed
|
||||
- Folder observations showing the true health state without scanning (the old behaviour can be reenabled via config)
|
||||
@@ -48,6 +88,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
and `uninstall` methods in the `Node` class.
|
||||
- Updated the `receive_payload_from_session_manager` method in `SoftwareManager` so that it now sends a copy of the
|
||||
payload to any software listening on the destination port of the `Frame`.
|
||||
- Made the `show` method of `Network` show all node types, including ones registered at runtime
|
||||
|
||||
### Removed
|
||||
- Removed the `install` and `uninstall` methods in the `Node` class.
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
include src/primaite/setup/_package_data/primaite_config.yaml
|
||||
include src/primaite/config/_package_data/*.yaml
|
||||
include src/primaite/simulator/_package_data/*.ipynb
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
from typing import Any, Dict, Optional, Tuple
|
||||
|
||||
from gymnasium.core import ObsType
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
import json
|
||||
import shutil
|
||||
from datetime import datetime
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
import json
|
||||
import sys
|
||||
from datetime import datetime
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
import platform
|
||||
from typing import Dict
|
||||
|
||||
|
||||
2
docs/_templates/custom-class-template.rst
vendored
2
docs/_templates/custom-class-template.rst
vendored
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
..
|
||||
Credit to https://github.com/JamesALeedham/Sphinx-Autosummary-Recursion for the custom templates.
|
||||
|
||||
2
docs/_templates/custom-module-template.rst
vendored
2
docs/_templates/custom-module-template.rst
vendored
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
..
|
||||
Credit to https://github.com/JamesALeedham/Sphinx-Autosummary-Recursion for the custom templates.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
..
|
||||
DO NOT DELETE THIS FILE! It contains the all-important `.. autosummary::` directive with `:recursive:` option, without
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# For the full list of built-in configuration values, see the documentation:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Welcome to PrimAITE's documentation
|
||||
====================================
|
||||
@@ -30,6 +30,7 @@ What is PrimAITE?
|
||||
source/varying_config_files
|
||||
source/environment
|
||||
source/action_masking
|
||||
source/node_sets
|
||||
|
||||
.. toctree::
|
||||
:caption: Notebooks:
|
||||
@@ -69,7 +70,7 @@ PrimAITE incorporates the following features:
|
||||
|
||||
- Architected with a separate Simulation layer and Game layer. This separation of concerns defines a clear path towards transfer learning with environments of differing fidelity;
|
||||
- Ability to reconfigure an RL reward function based on (a) the ability to counter the modelled adversarial cyber-attack, and (b) the ability to ensure success for green agents;
|
||||
- Access Control List (ACL) functions for network devices (routers and firewalls), following standard ACL rule format (e.g., DENY / ALLOW, source / destination IP addresses, protocol and port);
|
||||
- Access Control List (ACL) functions for network devices (routers and firewalls), following standard ACL rule format (e.g., DENY / PERMIT, source / destination IP addresses, protocol and port);
|
||||
- Application of traffic to the links of the system laydown adheres to the ACL rulesets and routing tables contained within each network device;
|
||||
- Provides RL environments adherent to the Farama Foundation Gymnasium (Previously OpenAI Gym) API, allowing integration with any compliant RL Agent frameworks;
|
||||
- Provides RL environments adherent to Ray RLlib environment specifications for single-agent and multi-agent scenarios;
|
||||
|
||||
@@ -184,7 +184,7 @@ Head over to the :ref:`getting-started` page to install and setup PrimAITE!
|
||||
- 192.168.1.5
|
||||
- ANY
|
||||
- ANY
|
||||
All ACL rules are considered when applying an IER. Logic follows the order of rules, so a DENY or ALLOW for the same parameters will override an earlier entry.
|
||||
All ACL rules are considered when applying an IER. Logic follows the order of rules, so a DENY or PERMIT for the same parameters will override an earlier entry.
|
||||
Observation Spaces
|
||||
******************
|
||||
The observation space provides the blue agent with information about the current status of nodes and links.
|
||||
@@ -331,7 +331,7 @@ Head over to the :ref:`getting-started` page to install and setup PrimAITE!
|
||||
* Dictionary item {... ,1: [x1, x2, x3, x4, x5, x6] ...}
|
||||
The placeholders inside the list under the key '1' mean the following:
|
||||
* [0, 2] - Action (0 = do nothing, 1 = create rule, 2 = delete rule)
|
||||
* [0, 1] - Permission (0 = DENY, 1 = ALLOW)
|
||||
* [0, 1] - Permission (0 = DENY, 1 = PERMIT)
|
||||
* [0, num nodes] - Source IP (0 = any, then 1 -> x resolving to IP addresses)
|
||||
* [0, num nodes] - Dest IP (0 = any, then 1 -> x resolving to IP addresses)
|
||||
* [0, num services] - Protocol (0 = any, then 1 -> x resolving to protocol)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Action Masking
|
||||
**************
|
||||
@@ -23,123 +23,117 @@ The following logic is applied:
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| Action | Action Mask Logic |
|
||||
+==========================================+=====================================================================+
|
||||
| **DONOTHING** | Always Possible. |
|
||||
| **do-nothing** | Always Possible. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_SCAN** | Node is on. Service is running. |
|
||||
| **node-service-scan** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_STOP** | Node is on. Service is running. |
|
||||
| **node-service-stop** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_START** | Node is on. Service is stopped. |
|
||||
| **node-service-start** | Node is on. Service is stopped. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_PAUSE** | Node is on. Service is running. |
|
||||
| **node-service-pause** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_RESUME** | Node is on. Service is paused. |
|
||||
| **node-service-resume** | Node is on. Service is paused. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_RESTART** | Node is on. Service is running. |
|
||||
| **node-service-restart** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_DISABLE** | Node is on. |
|
||||
| **node-service-disable** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_ENABLE** | Node is on. Service is disabled. |
|
||||
| **node-service-enable** | Node is on. Service is disabled. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SERVICE_FIX** | Node is on. Service is running. |
|
||||
| **node-service-fix** | Node is on. Service is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_APPLICATION_EXECUTE** | Node is on. |
|
||||
| **node-application-execute** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_APPLICATION_SCAN** | Node is on. Application is running. |
|
||||
| **node-application-scan** | Node is on. Application is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_APPLICATION_CLOSE** | Node is on. Application is running. |
|
||||
| **node-application-close** | Node is on. Application is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_APPLICATION_FIX** | Node is on. Application is running. |
|
||||
| **node-application-fix** | Node is on. Application is running. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_APPLICATION_INSTALL** | Node is on. |
|
||||
| **node-application-install** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_APPLICATION_REMOVE** | Node is on. |
|
||||
| **node-application-remove** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_SCAN** | Node is on. File exists. File not deleted. |
|
||||
| **node-file-scan** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_CREATE** | Node is on. |
|
||||
| **node-file-create** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_CHECKHASH** | Node is on. File exists. File not deleted. |
|
||||
| **node-file-checkhash** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_DELETE** | Node is on. File exists. |
|
||||
| **node-file-delete** | Node is on. File exists. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_REPAIR** | Node is on. File exists. File not deleted. |
|
||||
| **node-file-repair** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_RESTORE** | Node is on. File exists. File is deleted. |
|
||||
| **node-file-restore** | Node is on. File exists. File is deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_CORRUPT** | Node is on. File exists. File not deleted. |
|
||||
| **node-file-corrupt** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FILE_ACCESS** | Node is on. File exists. File not deleted. |
|
||||
| **node-file-access** | Node is on. File exists. File not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FOLDER_CREATE** | Node is on. |
|
||||
| **node-folder-create** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FOLDER_SCAN** | Node is on. Folder exists. Folder not deleted. |
|
||||
| **node-folder-scan** | Node is on. Folder exists. Folder not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FOLDER_CHECKHASH** | Node is on. Folder exists. Folder not deleted. |
|
||||
| **node-folder-checkhash** | Node is on. Folder exists. Folder not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FOLDER_REPAIR** | Node is on. Folder exists. Folder not deleted. |
|
||||
| **node-folder-repair** | Node is on. Folder exists. Folder not deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_FOLDER_RESTORE** | Node is on. Folder exists. Folder is deleted. |
|
||||
| **node-folder-restore** | Node is on. Folder exists. Folder is deleted. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_OS_SCAN** | Node is on. |
|
||||
| **node-os-scan** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **HOST_NIC_ENABLE** | NIC is disabled. Node is on. |
|
||||
| **host-nic-enable** | NIC is disabled. Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **HOST_NIC_DISABLE** | NIC is enabled. Node is on. |
|
||||
| **host-nic-disable** | NIC is enabled. Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SHUTDOWN** | Node is on. |
|
||||
| **node-shutdown** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_STARTUP** | Node is off. |
|
||||
| **node-startup** | Node is off. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_RESET** | Node is on. |
|
||||
| **node-reset** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_NMAP_PING_SCAN** | Node is on. |
|
||||
| **node-nmap-ping-scan** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_NMAP_PORT_SCAN** | Node is on. |
|
||||
| **node-nmap-port-scan** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_NMAP_NETWORK_SERVICE_RECON** | Node is on. |
|
||||
| **node-network-service-recon** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NETWORK_PORT_ENABLE** | Node is on. Router is on. |
|
||||
| **network-port-enable** | Node is on. Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NETWORK_PORT_DISABLE** | Router is on. |
|
||||
| **network-port-disable** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **ROUTER_ACL_ADDRULE** | Router is on. |
|
||||
| **router-acl-add-rule** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **ROUTER_ACL_REMOVERULE** | Router is on. |
|
||||
| **router-acl-remove-rule** | Router is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **FIREWALL_ACL_ADDRULE** | Firewall is on. |
|
||||
| **firewall-acl-add-rule** | Firewall is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **FIREWALL_ACL_REMOVERULE** | Firewall is on. |
|
||||
| **firewall-acl-remove-rule** | Firewall is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_NMAP_PING_SCAN** | Node is on. |
|
||||
| **configure-database-client** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_NMAP_PORT_SCAN** | Node is on. |
|
||||
| **configure-ransomware-script** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_NMAP_NETWORK_SERVICE_RECON** | Node is on. |
|
||||
| **c2-server-ransomware-configure** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **CONFIGURE_DATABASE_CLIENT** | Node is on. |
|
||||
| **configure-dos-bot** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **CONFIGURE_RANSOMWARE_SCRIPT** | Node is on. |
|
||||
| **configure-c2-beacon** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **CONFIGURE_DOSBOT** | Node is on. |
|
||||
| **c2-server-ransomware-launch** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **CONFIGURE_C2_BEACON** | Node is on. |
|
||||
| **c2-server-terminal-command** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **C2_SERVER_RANSOMWARE_LAUNCH** | Node is on. |
|
||||
| **c2-server-data-exfiltrate** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **C2_SERVER_RANSOMWARE_CONFIGURE** | Node is on. |
|
||||
| **node-account-change-password** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **C2_SERVER_TERMINAL_COMMAND** | Node is on. |
|
||||
| **node-session-remote-login** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **C2_SERVER_DATA_EXFILTRATE** | Node is on. |
|
||||
| **node-session-remote-logoff** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_ACCOUNTS_CHANGE_PASSWORD** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **SSH_TO_REMOTE** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **SESSIONS_REMOTE_LOGOFF** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
| **NODE_SEND_REMOTE_COMMAND** | Node is on. |
|
||||
| **node-send-remote-command** | Node is on. |
|
||||
+------------------------------------------+---------------------------------------------------------------------+
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
PrimAITE |VERSION| Configuration
|
||||
********************************
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
``agents``
|
||||
@@ -19,26 +19,7 @@ Agents can be scripted (deterministic and stochastic), or controlled by a reinfo
|
||||
...
|
||||
- ref: green_agent_example
|
||||
team: GREEN
|
||||
type: ProbabilisticAgent
|
||||
observation_space:
|
||||
type: UC2GreenObservation
|
||||
action_space:
|
||||
action_list:
|
||||
- type: DONOTHING
|
||||
- type: NODE_APPLICATION_EXECUTE
|
||||
options:
|
||||
nodes:
|
||||
- node_name: client_2
|
||||
applications:
|
||||
- application_name: WebBrowser
|
||||
max_folders_per_node: 1
|
||||
max_files_per_folder: 1
|
||||
max_services_per_node: 1
|
||||
max_applications_per_node: 1
|
||||
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: DUMMY
|
||||
type: probabilistic-agent
|
||||
|
||||
agent_settings:
|
||||
start_settings:
|
||||
@@ -57,13 +38,13 @@ Specifies if the agent is malicious (``RED``), benign (``GREEN``), or defensive
|
||||
|
||||
``type``
|
||||
--------
|
||||
Specifies which class should be used for the agent. ``ProxyAgent`` is used for agents that receive instructions from an RL algorithm. Scripted agents like ``RedDatabaseCorruptingAgent`` and ``ProbabilisticAgent`` generate their own behaviour.
|
||||
Specifies which class should be used for the agent. ``proxy-agent`` is used for agents that receive instructions from an RL algorithm. Scripted agents like ``red-database-corrupting-agent`` and ``probabilistic-agent`` generate their own behaviour.
|
||||
|
||||
Available agent types:
|
||||
|
||||
- ``ProbabilisticAgent``
|
||||
- ``ProxyAgent``
|
||||
- ``RedDatabaseCorruptingAgent``
|
||||
- ``probabilistic-agent``
|
||||
- ``proxy-agent``
|
||||
- ``red-database-corrupting-agent``
|
||||
|
||||
``observation_space``
|
||||
---------------------
|
||||
@@ -79,10 +60,10 @@ selects which python class from the :py:mod:`primaite.game.agent.observation` mo
|
||||
|
||||
Allows configuration of the chosen observation type. These are optional.
|
||||
|
||||
* ``num_services_per_node``, ``num_folders_per_node``, ``num_files_per_folder``, ``num_nics_per_node`` all define the shape of the observation space. The size and shape of the obs space must remain constant, but the number of files, folders, ACL rules, and other components can change within an episode. Therefore padding is performed and these options set the size of the obs space.
|
||||
* ``num_services_per_node``, ``num_folders_per_node``, ``num_files_per_folder``, ``num_nics_per_node`` all define the shape of the observation space. The size and shape of the obs space must remain constant, but the number of files, folders, acl rules, and other components can change within an episode. Therefore padding is performed and these options set the size of the obs space.
|
||||
* ``nodes``: list of nodes that will be present in this agent's observation space. The ``node_ref`` relates to the human-readable unique reference defined later in the ``simulation`` part of the config. Each node can also be configured with services, and files that should be monitored.
|
||||
* ``links``: list of links that will be present in this agent's observation space. The ``link_ref`` relates to the human-readable unique reference defined later in the ``simulation`` part of the config.
|
||||
* ``acl``: configure how the agent reads the access control list on the router in the simulation. ``router_node_ref`` is for selecting which router's ACL table should be used. ``ip_list`` sets the encoding of ip addresses as integers within the observation space.
|
||||
* ``acl``: configure how the agent reads the access control list on the router in the simulation. ``router_node_ref`` is for selecting which router's acl table should be used. ``ip_list`` sets the encoding of ip addresses as integers within the observation space.
|
||||
|
||||
For more information see :py:mod:`primaite.game.agent.observations`
|
||||
|
||||
@@ -91,10 +72,6 @@ For more information see :py:mod:`primaite.game.agent.observations`
|
||||
|
||||
The action space is configured to be made up of individual action types. Once configured, the agent can select an action type and some optional action parameters at every step. For example: The ``NODE_SERVICE_SCAN`` action takes the parameters ``node_id`` and ``service_id``.
|
||||
|
||||
``action_list``
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
A list of action modules. The options are listed in the :py:mod:`primaite.game.agent.actions.ActionManager.act_class_identifiers` module.
|
||||
|
||||
``action_map``
|
||||
^^^^^^^^^^^^^^
|
||||
@@ -120,7 +97,7 @@ Similar to action space, this is defined as a list of components from the :py:mo
|
||||
|
||||
``reward_components``
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
TODO: update description
|
||||
A list of reward types from :py:mod:`primaite.game.agent.rewards.RewardFunction.rew_class_identifiers`
|
||||
|
||||
e.g.
|
||||
@@ -128,8 +105,8 @@ e.g.
|
||||
.. code-block:: yaml
|
||||
|
||||
reward_components:
|
||||
- type: DUMMY
|
||||
- type: DATABASE_FILE_INTEGRITY
|
||||
- type: dummy
|
||||
- type: database-file-integrity
|
||||
|
||||
|
||||
``agent_settings``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
``game``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
``io_settings``
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
``simulation``
|
||||
==============
|
||||
In this section the network layout is defined. This part of the config follows a hierarchical structure. Almost every component defines a ``ref`` field which acts as a human-readable unique identifier, used by other parts of the config, such as agents.
|
||||
|
||||
# TODO: ref field is no longer real
|
||||
At the top level of the network are ``nodes``, ``links`` and ``airspace``.
|
||||
|
||||
e.g.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _Node Attributes:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _common_host_node_attributes:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _common_network_node_attributes:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _common_node_attributes:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
``type``
|
||||
--------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _computer_configuration:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _firewall_configuration:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _network_examples:
|
||||
|
||||
@@ -617,10 +617,10 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 192.168.1.1
|
||||
dns_server: 8.8.8.2
|
||||
applications:
|
||||
- type: DatabaseClient
|
||||
- type: database-client
|
||||
options:
|
||||
db_server_ip: 10.10.1.11
|
||||
- type: WebBrowser
|
||||
- type: web-browser
|
||||
options:
|
||||
target_url: http://sometech.ai
|
||||
|
||||
@@ -631,10 +631,10 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 192.168.1.1
|
||||
dns_server: 8.8.8.2
|
||||
applications:
|
||||
- type: DatabaseClient
|
||||
- type: database-client
|
||||
options:
|
||||
db_server_ip: 10.10.1.11
|
||||
- type: WebBrowser
|
||||
- type: web-browser
|
||||
options:
|
||||
target_url: http://sometech.ai
|
||||
|
||||
@@ -700,7 +700,7 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 8.8.8.1
|
||||
services:
|
||||
- ref: dns_server
|
||||
type: DNSServer
|
||||
type: dns-server
|
||||
options:
|
||||
domain_mapping:
|
||||
sometech.ai: 94.10.180.6
|
||||
@@ -794,9 +794,9 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
dns_server: 8.8.8.2
|
||||
services:
|
||||
- ref: web_server
|
||||
type: WebServer
|
||||
type: web-server
|
||||
applications:
|
||||
- type: DatabaseClient
|
||||
- type: database-client
|
||||
options:
|
||||
db_server_ip: 10.10.1.11
|
||||
|
||||
@@ -903,10 +903,10 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 10.10.1.1
|
||||
dns_server: 8.8.8.2
|
||||
services:
|
||||
- type: DatabaseService
|
||||
- type: database-service
|
||||
options:
|
||||
backup_server_ip: 10.10.1.12 # The some_tech_storage_srv server
|
||||
- type: FTPClient
|
||||
- type: ftp-client
|
||||
|
||||
- hostname: some_tech_storage_srv
|
||||
type: server
|
||||
@@ -915,7 +915,7 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 10.10.1.1
|
||||
dns_server: 8.8.8.2
|
||||
services:
|
||||
- type: FTPServer
|
||||
- type: ftp-server
|
||||
|
||||
- hostname: some_tech_hr_1
|
||||
type: computer
|
||||
@@ -924,10 +924,10 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 10.10.3.1
|
||||
dns_server: 8.8.8.2
|
||||
applications:
|
||||
- type: DatabaseClient
|
||||
- type: database-client
|
||||
options:
|
||||
db_server_ip: 10.10.1.11
|
||||
- type: WebBrowser
|
||||
- type: web-browser
|
||||
options:
|
||||
target_url: http://sometech.ai
|
||||
|
||||
@@ -938,10 +938,10 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 10.10.2.1
|
||||
dns_server: 8.8.8.2
|
||||
applications:
|
||||
- type: DatabaseClient
|
||||
- type: database-client
|
||||
options:
|
||||
db_server_ip: 10.10.1.11
|
||||
- type: WebBrowser
|
||||
- type: web-browser
|
||||
options:
|
||||
target_url: http://sometech.ai
|
||||
|
||||
@@ -952,10 +952,10 @@ Each node is configured to ensure it meets the specific security and operational
|
||||
default_gateway: 10.10.2.1
|
||||
dns_server: 8.8.8.2
|
||||
applications:
|
||||
- type: DatabaseClient
|
||||
- type: database-client
|
||||
options:
|
||||
db_server_ip: 10.10.1.11
|
||||
- type: WebBrowser
|
||||
- type: web-browser
|
||||
options:
|
||||
target_url: http://sometech.ai
|
||||
|
||||
@@ -1177,8 +1177,8 @@ ACLs permitting or denying traffic as per our configured ACL rules.
|
||||
some_tech_storage_srv = network.get_node_by_hostname("some_tech_storage_srv")
|
||||
some_tech_storage_srv.file_system.create_file(file_name="test.png")
|
||||
|
||||
pc_1_ftp_client: FTPClient = network.get_node_by_hostname("pc_1").software_manager.software["FTPClient"]
|
||||
pc_2_ftp_client: FTPClient = network.get_node_by_hostname("pc_2").software_manager.software["FTPClient"]
|
||||
pc_1_ftp_client: FTPClient = network.get_node_by_hostname("pc_1").software_manager.software["ftp-client"]
|
||||
pc_2_ftp_client: FTPClient = network.get_node_by_hostname("pc_2").software_manager.software["ftp-client"]
|
||||
|
||||
assert not pc_1_ftp_client.request_file(
|
||||
dest_ip_address=some_tech_storage_srv.network_interface[1].ip_address,
|
||||
@@ -1224,7 +1224,7 @@ ACLs permitting or denying traffic as per our configured ACL rules.
|
||||
|
||||
web_server: Server = network.get_node_by_hostname("some_tech_web_srv")
|
||||
|
||||
web_ftp_client: FTPClient = web_server.software_manager.software["FTPClient"]
|
||||
web_ftp_client: FTPClient = web_server.software_manager.software["ftp-client"]
|
||||
|
||||
assert not web_ftp_client.request_file(
|
||||
dest_ip_address=some_tech_storage_srv.network_interface[1].ip_address,
|
||||
@@ -1269,7 +1269,7 @@ ACLs permitting or denying traffic as per our configured ACL rules.
|
||||
some_tech_storage_srv.file_system.create_file(file_name="test.png")
|
||||
|
||||
some_tech_snr_dev_pc: Computer = network.get_node_by_hostname("some_tech_snr_dev_pc")
|
||||
snr_dev_ftp_client: FTPClient = some_tech_snr_dev_pc.software_manager.software["FTPClient"]
|
||||
snr_dev_ftp_client: FTPClient = some_tech_snr_dev_pc.software_manager.software["ftp-client"]
|
||||
|
||||
assert snr_dev_ftp_client.request_file(
|
||||
dest_ip_address=some_tech_storage_srv.network_interface[1].ip_address,
|
||||
@@ -1294,7 +1294,7 @@ ACLs permitting or denying traffic as per our configured ACL rules.
|
||||
some_tech_storage_srv.file_system.create_file(file_name="test.png")
|
||||
|
||||
some_tech_jnr_dev_pc: Computer = network.get_node_by_hostname("some_tech_jnr_dev_pc")
|
||||
jnr_dev_ftp_client: FTPClient = some_tech_jnr_dev_pc.software_manager.software["FTPClient"]
|
||||
jnr_dev_ftp_client: FTPClient = some_tech_jnr_dev_pc.software_manager.software["ftp-client"]
|
||||
|
||||
assert not jnr_dev_ftp_client.request_file(
|
||||
dest_ip_address=some_tech_storage_srv.network_interface[1].ip_address,
|
||||
@@ -1337,7 +1337,7 @@ ACLs permitting or denying traffic as per our configured ACL rules.
|
||||
some_tech_storage_srv.file_system.create_file(file_name="test.png")
|
||||
|
||||
some_tech_hr_pc: Computer = network.get_node_by_hostname("some_tech_hr_1")
|
||||
hr_ftp_client: FTPClient = some_tech_hr_pc.software_manager.software["FTPClient"]
|
||||
hr_ftp_client: FTPClient = some_tech_hr_pc.software_manager.software["ftp-client"]
|
||||
|
||||
assert not hr_ftp_client.request_file(
|
||||
dest_ip_address=some_tech_storage_srv.network_interface[1].ip_address,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _router_configuration:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _server_configuration:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _switch_configuration:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
``applications``
|
||||
----------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
``services``
|
||||
------------
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Customising Agents
|
||||
******************
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. role:: raw-html(raw)
|
||||
:format: html
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _Developer Tools:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
RL Environments
|
||||
***************
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _example jupyter notebooks:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
PrimAITE Game layer
|
||||
*******************
|
||||
@@ -57,13 +57,13 @@ An agent's reward can be based on rewards of other agents. This is particularly
|
||||
reward_components:
|
||||
|
||||
# When the webpage loads, the reward goes up by 0.25 when it fails to load, it goes down to -0.25
|
||||
- type: WEBPAGE_UNAVAILABLE_PENALTY
|
||||
- type: webpage-unavailable-penalty
|
||||
weight: 0.25
|
||||
options:
|
||||
node_hostname: client_2
|
||||
|
||||
# When the database is reachable, the reward goes up by 0.05, when it is unreachable it goes down to -0.05
|
||||
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
|
||||
- type: green-admin-database-unreachable-penalty
|
||||
weight: 0.05
|
||||
options:
|
||||
node_hostname: client_2
|
||||
@@ -74,7 +74,7 @@ An agent's reward can be based on rewards of other agents. This is particularly
|
||||
reward_components:
|
||||
|
||||
# When the database file is in a good state, blue's reward is 0.4, when it's in a corrupted state the reward is -0.4
|
||||
- type: DATABASE_FILE_INTEGRITY
|
||||
- type: database-file-integrity
|
||||
weight: 0.40
|
||||
options:
|
||||
node_hostname: database_server
|
||||
@@ -82,7 +82,7 @@ An agent's reward can be based on rewards of other agents. This is particularly
|
||||
file_name: database.db
|
||||
|
||||
# The green's reward is added onto the blue's reward.
|
||||
- type: SHARED_REWARD
|
||||
- type: shared-reward
|
||||
weight: 1.0
|
||||
options:
|
||||
agent_name: client_2_green_user
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _getting-started:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Glossary
|
||||
=============
|
||||
|
||||
67
docs/source/how_to_guides/extensible_actions.rst
Normal file
67
docs/source/how_to_guides/extensible_actions.rst
Normal file
@@ -0,0 +1,67 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
Extensible Actions
|
||||
******************
|
||||
|
||||
|
||||
Changes to Actions class Structure.
|
||||
===================================
|
||||
|
||||
Actions within PrimAITE have been updated to inherit from a base class, AbstractAction, standardising their format and allowing for easier creation of custom actions. Actions now use a ``ConfigSchema`` to define the possible configuration variables, and use pydantic to enforce correct parameters are passed through.
|
||||
|
||||
|
||||
Developing Custom Actions.
|
||||
==========================
|
||||
|
||||
Custom actions within PrimAITE must be a sub-class of `AbstractAction`, and contain 3 key items:
|
||||
|
||||
#. ConfigSchema class
|
||||
|
||||
#. Unique discriminator
|
||||
|
||||
#. `form_request` method.
|
||||
|
||||
|
||||
ConfigSchema
|
||||
############
|
||||
|
||||
The ConfigSchema sub-class of the action must contain all `configurable` variables within the action, that would be specified within the environments configuration YAML file.
|
||||
|
||||
|
||||
Unique discriminator
|
||||
#################
|
||||
|
||||
When declaring a custom class, it must have a unique discriminator string, that allows PrimAITE to generate the correct action when needed.
|
||||
|
||||
.. code:: Python
|
||||
|
||||
class CreateDirectoryAction(AbstractAction, discriminator="node-folder-create")
|
||||
|
||||
config: CreateDirectoryAction.ConfigSchema
|
||||
|
||||
class ConfigSchema(AbstractAction.ConfigSchema):
|
||||
|
||||
verb: ClassVar[str] = "create"
|
||||
node_name: str
|
||||
directory_name: str
|
||||
|
||||
def form_request(cls, config: ConfigSchema) -> RequestFormat:
|
||||
return ["network",
|
||||
"node",
|
||||
config.node_name,
|
||||
"file_system",
|
||||
config.verb,
|
||||
"folder",
|
||||
config.directory_name,
|
||||
]
|
||||
|
||||
The above action would fail pydantic validation as the discriminator "node-folder-create" is already used by the `NodeFolderCreateAction`, and would create a duplicate listing within `AbstractAction._registry`.
|
||||
|
||||
|
||||
form_request method
|
||||
###################
|
||||
|
||||
PrimAITE actions need to have a `form_request` method, which can be passed to the `RequestManager` for processing. This allows the custom action to be actioned within the simulation environment.
|
||||
74
docs/source/how_to_guides/extensible_agents.rst
Normal file
74
docs/source/how_to_guides/extensible_agents.rst
Normal file
@@ -0,0 +1,74 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _about:
|
||||
|
||||
Extensible Agents
|
||||
*****************
|
||||
|
||||
Agents defined within PrimAITE have been updated to allow for easier creation of new bespoke agents for use in custom environments.
|
||||
|
||||
|
||||
Developing Agents for PrimAITE
|
||||
==============================
|
||||
|
||||
All agent types within PrimAITE must be subclassed from ``AbstractAgent`` in order to be used from configuration YAML files. This then allows you to implement any custom agent logic for the new agent in your training scenario. Examples of implementing custom agent logic can be seen in pre-existing agents, such as the ``DataManipulationBot`` and ``RandomAgent``.
|
||||
|
||||
The core features that should be implemented in any new agent are detailed below:
|
||||
|
||||
#. **ConfigSchema**:
|
||||
|
||||
Configurable items within a new agent within PrimAITE should contain a ``ConfigSchema`` which holds all configurable variables of the agent. This should not include parameters related to its *state*, these would be listed seperately.
|
||||
Agent generation will fail pydantic checks if incorrect or invalid parameters are passed to the ConfigSchema of the chosen Agent.
|
||||
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class ExampleAgent(AbstractAgent, discriminator = "ExampleAgent"):
|
||||
"""An example agent for demonstration purposes."""
|
||||
|
||||
config: "ExampleAgent.ConfigSchema" = Field(default_factory= lambda: ExampleAgent.ConfigSchema())
|
||||
"""Agent configuration"""
|
||||
num_executions: int = 0
|
||||
"""Number of action executions by agent"""
|
||||
|
||||
class ConfigSchema(AbstractAgent.ConfigSchema):
|
||||
"""ExampleAgent configuration schema"""
|
||||
|
||||
type: str = "ExampleAgent
|
||||
"""Name of agent"""
|
||||
starting_host: int
|
||||
"""Host node that this agent should start from in the given environment."""
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- ref: example_green_agent
|
||||
team: GREEN
|
||||
type: example-agent
|
||||
|
||||
action_space:
|
||||
action_map:
|
||||
0:
|
||||
action: do-nothing
|
||||
options: {}
|
||||
agent_settings:
|
||||
start_step: 25
|
||||
frequency: 20
|
||||
variance: 5
|
||||
starting_host: "Server_1"
|
||||
|
||||
|
||||
#. **discriminators**:
|
||||
|
||||
All agent classes should have an ``discriminator`` attribute, a unique kebab-case string, for when they are added to the base ``AbstractAgent`` registry. This is then specified in your configuration YAML, and used by PrimAITE to generate the correct Agent.
|
||||
|
||||
Changes to YAML file
|
||||
====================
|
||||
|
||||
PrimAITE v4.0.0 introduces some breaking changes to how environment configuration yaml files are created. YAML files created for Primaite versions 3.3.0 should be compatible through a translation function, though it is encouraged that these are updated to reflect the updated format of 4.0.0+.
|
||||
|
||||
Agents now follow a more standardised settings definition, so should be more consistent across YAML files and the available agent types with PrimAITE.
|
||||
|
||||
All configurable items for agents sit under the ``agent_settings`` heading within your YAML files. There is no need for the inclusion of a ``start_settings``. Please see the above YAML example for full changes to agents.
|
||||
55
docs/source/how_to_guides/extensible_nodes.rst
Normal file
55
docs/source/how_to_guides/extensible_nodes.rst
Normal file
@@ -0,0 +1,55 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _about:
|
||||
|
||||
|
||||
Extensible Nodes
|
||||
****************
|
||||
|
||||
Node classes within PrimAITE have been updated to allow for easier generation of custom nodes within simulations.
|
||||
|
||||
|
||||
Changes to Node Class structure.
|
||||
================================
|
||||
|
||||
Node classes all inherit from the base Node Class, though new classes should inherit from either HostNode or NetworkNode, subject to the intended application of the Node.
|
||||
|
||||
The use of an `__init__` method is not necessary, as configurable variables for the class should be specified within the `config` of the class, and passed at run time via your YAML configuration using the `from_config` method.
|
||||
|
||||
An example of how additional Node classes is below, taken from `router.py` within PrimAITE.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
class Router(NetworkNode, identifier="router"):
|
||||
""" Represents a network router within the simulation, managing routing and forwarding of IP packets across network interfaces."""
|
||||
|
||||
SYSTEM_SOFTWARE: ClassVar[Dict] = {
|
||||
"user-session-manager": UserSessionManager,
|
||||
"user-manager": UserManager,
|
||||
"terminal": Terminal,
|
||||
}
|
||||
|
||||
network_interfaces: Dict[str, RouterInterface] = {}
|
||||
"The Router Interfaces on the node."
|
||||
network_interface: Dict[int, RouterInterface] = {}
|
||||
"The Router Interfaces on the node by port id."
|
||||
|
||||
sys_log: SysLog
|
||||
|
||||
config: "Router.ConfigSchema" = Field(default_factory=lambda: Router.ConfigSchema())
|
||||
|
||||
class ConfigSchema(NetworkNode.ConfigSchema):
|
||||
"""Configuration Schema for Router Objects."""
|
||||
|
||||
num_ports: int = 5
|
||||
|
||||
hostname: str = "Router"
|
||||
|
||||
|
||||
|
||||
Changes to YAML file.
|
||||
=====================
|
||||
|
||||
While effort has been made to ensure that nodes defined within configuration YAML files for use with PrimAITE 3.X remain compatible with PrimAITE v4+, it is encouraged to review for minor changes needed.
|
||||
57
docs/source/how_to_guides/extensible_rewards.rst
Normal file
57
docs/source/how_to_guides/extensible_rewards.rst
Normal file
@@ -0,0 +1,57 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _about:
|
||||
|
||||
Extensible Rewards
|
||||
******************
|
||||
Extensible Rewards differ from the previous reward mechanism used in PrimAITE v3.x as new reward
|
||||
types can be added without requiring a change to the RewardFunction class in rewards.py (PrimAITE
|
||||
core repository).
|
||||
|
||||
Changes to reward class structure.
|
||||
==================================
|
||||
|
||||
Reward classes are inherited from AbstractReward (a sub-class of Pydantic's BaseModel).
|
||||
Within the reward class there is a ConfigSchema class responsible for ensuring the config file data
|
||||
is in the correct format. This also means there is little (if no) requirement for and `__init__`
|
||||
method. The `.from_config` method is no longer required as it's inherited from `AbstractReward`.
|
||||
Each class requires an discriminator string which is used by the ConfigSchema class to verify that it
|
||||
hasn't previously been added to the registry.
|
||||
|
||||
Inheriting from `BaseModel` removes the need for an `__init__` method but means that object
|
||||
attributes need to be passed by keyword.
|
||||
|
||||
To add a new reward class follow the example below. Note that the type attribute in the
|
||||
`ConfigSchema` class should match the type used in the config file to define the reward.
|
||||
|
||||
.. code-block:: Python
|
||||
|
||||
class DatabaseFileIntegrity(AbstractReward, discriminator="database-file-integrity"):
|
||||
"""Reward function component which rewards the agent for maintaining the integrity of a database file."""
|
||||
|
||||
config: "DatabaseFileIntegrity.ConfigSchema"
|
||||
location_in_state: List[str] = [""]
|
||||
reward: float = 0.0
|
||||
|
||||
class ConfigSchema(AbstractReward.ConfigSchema):
|
||||
"""ConfigSchema for DatabaseFileIntegrity."""
|
||||
|
||||
type: str = "database-file-integrity"
|
||||
node_hostname: str
|
||||
folder_name: str
|
||||
file_name: str
|
||||
|
||||
def calculate(self, state: Dict, last_action_response: "AgentHistoryItem") -> float:
|
||||
"""Calculate the reward for the current state.
|
||||
pass
|
||||
|
||||
|
||||
|
||||
Changes to YAML file.
|
||||
=====================
|
||||
.. code:: YAML
|
||||
|
||||
There's no longer a need to provide a `dns_server` as an option in the simulation section
|
||||
of the config file.
|
||||
115
docs/source/node_sets.rst
Normal file
115
docs/source/node_sets.rst
Normal file
@@ -0,0 +1,115 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _network_node_adder:
|
||||
|
||||
Network Node Adder Module
|
||||
#########################
|
||||
|
||||
This module provides a framework for adding nodes to a network in a standardised way. It defines a base class ``NetworkNodeAdder``, which can be extended to create specific node adders, and utility functions to calculate network infrastructure requirements.
|
||||
|
||||
The module allows you to use the pre-defined node adders, ``OfficeLANAdder``, or create custom ones by extending the base class.
|
||||
|
||||
How It Works
|
||||
============
|
||||
|
||||
The main class in the module is ``NetworkNodeAdder``, which defines the interface for adding nodes to a network. Child classes are expected to:
|
||||
|
||||
1. Define a ``ConfigSchema`` nested class to define configuration options.
|
||||
2. Implement the ``add_nodes_to_net(config, network)`` method, which adds the nodes to the network according to the configuration object.
|
||||
|
||||
The ``NetworkNodeAdder`` base class handles node adders defined in the primAITE config YAML file as well. It does this by keeping a registry of node adder classes, and uses the ``type`` field of the config to select the appropriate class to which to pass the configuration.
|
||||
|
||||
Example Usage
|
||||
=============
|
||||
|
||||
Via Python API
|
||||
--------------
|
||||
|
||||
Adding nodes to a network can be done using the python API by constructing the relevant ``ConfigSchema`` object like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
net = Network()
|
||||
|
||||
office_lan_config = OfficeLANAdder.ConfigSchema(
|
||||
lan_name="CORP-LAN",
|
||||
subnet_base=2,
|
||||
pcs_ip_block_start=10,
|
||||
num_pcs=8,
|
||||
include_router=False,
|
||||
bandwidth=150,
|
||||
)
|
||||
OfficeLANAdder.add_nodes_to_net(config=office_lan_config, network=net)
|
||||
|
||||
In this example, a network with 8 computers connected by a switch will be added to the network object.
|
||||
|
||||
|
||||
Via YAML Config
|
||||
---------------
|
||||
|
||||
.. code-block:: yaml
|
||||
simulation:
|
||||
network:
|
||||
nodes:
|
||||
# ... nodes go here
|
||||
node_sets:
|
||||
- type: office-lan
|
||||
lan_name: CORP_LAN
|
||||
subnet_base: 2
|
||||
pcs_ip_block_start: 10
|
||||
num_pcs: 8
|
||||
include_router: False
|
||||
bandwidth: 150
|
||||
# ... additional node sets can be added below
|
||||
|
||||
``NetworkNodeAdder`` reads the ``type`` property of the config, then constructs and passes the configuration to ``OfficeLANAdder.add_nodes_to_net()``.
|
||||
|
||||
In this example, a network with 8 computers connected by a switch will be added to the network object. Equivalent to the above.
|
||||
|
||||
|
||||
Creating Custom Node Adders
|
||||
===========================
|
||||
To create a custom node adder, subclass NetworkNodeAdder and define:
|
||||
|
||||
* A ConfigSchema class that defines the configuration schema for the node adder.
|
||||
* The add_nodes_to_net method that implements how nodes should be added to the network.
|
||||
|
||||
Example: DataCenterAdder
|
||||
------------------------
|
||||
Here is an example of creating a custom node adder, DataCenterAdder:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class DataCenterAdder(NetworkNodeAdder, discriminator="data-center"):
|
||||
class ConfigSchema(NetworkNodeAdder.ConfigSchema):
|
||||
type: Literal["data-center"] = "data-center"
|
||||
num_servers: int
|
||||
data_center_name: str
|
||||
|
||||
@classmethod
|
||||
def add_nodes_to_net(cls, config: ConfigSchema, network: Network) -> None:
|
||||
for i in range(config.num_servers):
|
||||
server = Computer(
|
||||
hostname=f"server_{i}_{config.data_center_name}",
|
||||
ip_address=f"192.168.100.{i + 8}",
|
||||
subnet_mask="255.255.255.0",
|
||||
default_gateway="192.168.100.1",
|
||||
start_up_duration=0
|
||||
)
|
||||
server.power_on()
|
||||
network.add_node(server)
|
||||
|
||||
**Using the Custom Node Adder:**
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
config = {
|
||||
"type": "data-center",
|
||||
"num_servers": 5,
|
||||
"data_center_name": "dc1"
|
||||
}
|
||||
|
||||
network = Network()
|
||||
DataCenterAdder.from_config(config, network)
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _Executed Notebooks:
|
||||
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| Name | Version | License | Description | URL |
|
||||
+===================+=========+====================================+=======================================================================================================+====================================================================+
|
||||
| gymnasium | 0.28.1 | MIT License | A standard API for reinforcement learning and a diverse set of reference environments (formerly Gym). | https://farama.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| ipywidgets | 8.1.5 | BSD License | Jupyter interactive widgets | http://jupyter.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| jupyterlab | 3.6.1 | BSD License | JupyterLab computational environment | https://jupyter.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| kaleido | 0.2.1 | MIT | Static image export for web-based visualization libraries with zero dependencies | https://github.com/plotly/Kaleido |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| matplotlib | 3.7.1 | Python Software Foundation License | Python plotting package | https://matplotlib.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| networkx | 3.1 | BSD License | Python package for creating and manipulating graphs and networks | https://networkx.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| numpy | 1.23.5 | BSD License | NumPy is the fundamental package for array computing with Python. | https://www.numpy.org |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| platformdirs | 3.5.1 | MIT License | A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir". | https://github.com/platformdirs/platformdirs |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| plotly | 5.15.0 | MIT License | An open-source, interactive data visualization library for Python | https://plotly.com/python/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| polars | 0.20.30 | MIT License | Blazingly fast DataFrame library | https://www.pola.rs/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| prettytable | 3.8.0 | BSD License (BSD (3 clause)) | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format | https://github.com/jazzband/prettytable |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| pydantic | 2.7.0 | MIT License | Data validation using Python type hints | https://github.com/pydantic/pydantic |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| PyYAML | 6.0 | MIT License | YAML parser and emitter for Python | https://pyyaml.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| ray | 2.32.0 | Apache 2.0 | Ray provides a simple, universal API for building distributed applications. | https://github.com/ray-project/ray |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| stable-baselines3 | 2.1.0 | MIT | Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms. | https://github.com/DLR-RM/stable-baselines3 |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| tensorflow | 2.12.0 | Apache Software License | TensorFlow is an open source machine learning framework for everyone. | https://www.tensorflow.org/ |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| typer | 0.9.0 | MIT License | Typer, build great CLIs. Easy to code. Based on Python type hints. | https://github.com/tiangolo/typer |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| Deepdiff | 8.0.1 | MIT License | Deep difference of dictionaries, iterables, strings, and any other object objects. | https://github.com/seperman/deepdiff |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
| sb3_contrib | 2.1.0 | MIT License | Contrib package for Stable-Baselines3 - Experimental reinforcement learning (RL) code (Action Masking)| https://github.com/Stable-Baselines-Team/stable-baselines3-contrib |
|
||||
+-------------------+---------+------------------------------------+-------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------+
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| Name | Supported Version | Built Version | License | Description | URL |
|
||||
+===================+=====================+===============+======================================+========================================================================================================+=====================================================================+
|
||||
| gymnasium | 0.28.1 | 0.28.1 | MIT License | A standard API for reinforcement learning and a diverse set of reference environments (formerly Gym). | https://farama.org |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| ipywidgets | ~=8.0 | 8.1.5 | BSD License | Jupyter interactive widgets | http://jupyter.org |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| jupyterlab | 3.6.1 | 3.6.1 | BSD License | JupyterLab computational environment | https://jupyter.org |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| kaleido | ==0.2.1 | 0.2.1 | MIT | Static image export for web-based visualization libraries with zero dependencies | https://github.com/plotly/Kaleido |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| matplotlib | >=3.7.1 | 3.7.1 | Python Software Foundation License | Python plotting package | https://matplotlib.org |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| networkx | 3.1 | 3.1 | BSD License | Python package for creating and manipulating graphs and networks | https://networkx.org/ |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| numpy | ~1.23 | 1.23.5 | BSD License | NumPy is the fundamental package for array computing with Python. | https://www.numpy.org |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| platformdirs | 3.5.1 | 3.5.1 | MIT License | A small Python package for determining appropriate platform-specific dirs, e.g. a "user data dir". | https://github.com/platformdirs/platformdirs |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| plotly | 5.15 | 5.15.0 | MIT License | An open-source, interactive data visualization library for Python | https://plotly.com/python/ |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| polars | 0.20.30 | 0.20.30 | MIT License | Blazingly fast DataFrame library | https://www.pola.rs/ |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| prettytable | 3.8.0 | 3.8.0 | BSD License (BSD (3 clause)) | A simple Python library for easily displaying tabular data in a visually appealing ASCII table format | https://github.com/jazzband/prettytable |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| pydantic | 2.7.0 | 2.7.0 | MIT License | Data validation using Python type hints | https://github.com/pydantic/pydantic |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| PyYAML | >=6.0 | 6.0 | MIT License | YAML parser and emitter for Python | https://pyyaml.org/ |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| ray | >=2.20, <2.33 | 2.32.0 | Apache 2.0 | Ray provides a simple, universal API for building distributed applications. | https://github.com/ray-project/ray |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| stable-baselines3 | 2.1.0 | 2.1.0 | MIT | Pytorch version of Stable Baselines, implementations of reinforcement learning algorithms. | https://github.com/DLR-RM/stable-baselines3 |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| tensorflow | ~=2.12 | 2.12.0 | Apache Software License | TensorFlow is an open source machine learning framework for everyone. | https://www.tensorflow.org/ |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| typer | >=0.9 | 0.9.0 | MIT License | Typer, build great CLIs. Easy to code. Based on Python type hints. | https://github.com/tiangolo/typer |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| Deepdiff | 8.0.1 | 8.0.1 | MIT License | Deep difference of dictionaries, iterables, strings, and any other object objects. | https://github.com/seperman/deepdiff |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
| sb3_contrib | 2.1.0 | 2.1.0 | MIT License | Contrib package for Stable-Baselines3 - Experimental reinforcement learning (RL) code (Action Masking) | https://github.com/Stable-Baselines-Team/stable-baselines3-contrib |
|
||||
+-------------------+---------------------+---------------+--------------------------------------+--------------------------------------------------------------------------------------------------------+---------------------------------------------------------------------+
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _request_system:
|
||||
|
||||
@@ -53,10 +53,10 @@ Request responses
|
||||
When the simulator receives a request, it returns a response with a success status. The possible statuses are:
|
||||
|
||||
* **success**: The request was received and successfully executed.
|
||||
* For example, the agent tries to add an ACL rule and specifies correct parameters, and the ACL rule is added successfully.
|
||||
* For example, the agent tries to add an acl rule and specifies correct parameters, and the acl rule is added successfully.
|
||||
|
||||
* **failure**: The request was received, but it could not be executed, or it failed while executing.
|
||||
* For example, the agent tries to execute the ``WebBrowser`` application, but the webpage wasn't retrieved because the DNS server is not setup on the node.
|
||||
* For example, the agent tries to execute the ``web-browser`` application, but the webpage wasn't retrieved because the DNS server is not setup on the node.
|
||||
|
||||
* **unreachable**: The request was sent to a simulation component that does not exist.
|
||||
* For example, the agent tries to scan a file that has not been created yet.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Rewards
|
||||
#######
|
||||
@@ -23,7 +23,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: DUMMY
|
||||
- type: dummy
|
||||
weight: 1.0
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: DATABASE_FILE_INTEGRITY
|
||||
- type: database-file-integrity
|
||||
weight: 1.0
|
||||
options:
|
||||
node_hostname: server_1
|
||||
@@ -53,7 +53,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: WEB_SERVER_404_PENALTY
|
||||
- type: web-server-404-penalty
|
||||
node_hostname: web_server
|
||||
weight: 1.0
|
||||
options:
|
||||
@@ -70,7 +70,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: WEBPAGE_UNAVAILABLE_PENALTY
|
||||
- type: webpage-unavailable-penalty
|
||||
node_hostname: computer_1
|
||||
weight: 1.0
|
||||
options:
|
||||
@@ -86,7 +86,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: GREEN_ADMIN_DATABASE_UNREACHABLE_PENALTY
|
||||
- type: green-admin-database-unreachable-penalty
|
||||
weight: 1.0
|
||||
options:
|
||||
node_hostname: admin_pc_1
|
||||
@@ -104,7 +104,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: SHARED_REWARD
|
||||
- type: shared-reward
|
||||
weight: 1.0
|
||||
options:
|
||||
agent_name: scripted_agent
|
||||
@@ -119,7 +119,7 @@ The following API pages describe the use of each reward component and the possib
|
||||
# ...
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: ACTION_PENALTY
|
||||
- type: action-penalty
|
||||
weight: 1.0
|
||||
options:
|
||||
action_penalty: -0.3
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
Simulation
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _airspace:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
#############
|
||||
Base Hardware
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _network:
|
||||
|
||||
@@ -103,6 +103,13 @@ we'll use the following Network that has a client, server, two switches, and a r
|
||||
|
||||
router_1.acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.ICMP,
|
||||
src_port=PORT_LOOKUP["ARP"],
|
||||
dst_port=PORT_LOOKUP["ARP"],
|
||||
position=22
|
||||
)
|
||||
|
||||
router_1.acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=PROTOCOL_LOOKUP["ICMP"],
|
||||
position=23
|
||||
)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
#################################
|
||||
Network Interface Hierarchy Model
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
########
|
||||
Firewall
|
||||
@@ -156,8 +156,8 @@ To prevent all external traffic from accessing the internal network, with except
|
||||
# Exception rule to allow HTTP traffic from external to internal network
|
||||
firewall.internal_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.HTTP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["HTTP"],
|
||||
dst_ip_address="192.168.1.0",
|
||||
dst_wildcard_mask="0.0.0.255",
|
||||
position=2
|
||||
@@ -172,16 +172,16 @@ To enable external traffic to access specific services hosted within the DMZ:
|
||||
# Allow HTTP and HTTPS traffic to the DMZ
|
||||
firewall.dmz_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.HTTP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["HTTP"],
|
||||
dst_ip_address="172.16.0.0",
|
||||
dst_wildcard_mask="0.0.0.255",
|
||||
position=3
|
||||
)
|
||||
firewall.dmz_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.HTTPS,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["HTTPS"],
|
||||
dst_ip_address="172.16.0.0",
|
||||
dst_wildcard_mask="0.0.0.255",
|
||||
position=4
|
||||
@@ -196,9 +196,9 @@ To permit SSH access from a designated external IP to a specific server within t
|
||||
# Allow SSH from a specific external IP to an internal server
|
||||
firewall.internal_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
src_ip_address="10.0.0.2",
|
||||
dst_port=Port.SSH,
|
||||
dst_port=Port["SSH"],
|
||||
dst_ip_address="192.168.1.10",
|
||||
position=5
|
||||
)
|
||||
@@ -212,9 +212,9 @@ To limit database server access to selected external IP addresses:
|
||||
# Allow PostgreSQL traffic from an authorized external IP to the internal DB server
|
||||
firewall.internal_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
src_ip_address="10.0.0.3",
|
||||
dst_port=Port.POSTGRES_SERVER,
|
||||
dst_port=Port["POSTGRES_SERVER"],
|
||||
dst_ip_address="192.168.1.20",
|
||||
position=6
|
||||
)
|
||||
@@ -222,8 +222,8 @@ To limit database server access to selected external IP addresses:
|
||||
# Deny all other PostgreSQL traffic from external sources
|
||||
firewall.internal_inbound_acl.add_rule(
|
||||
action=ACLAction.DENY,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.POSTGRES_SERVER,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["POSTGRES_SERVER"],
|
||||
dst_ip_address="192.168.1.0",
|
||||
dst_wildcard_mask="0.0.0.255",
|
||||
position=7
|
||||
@@ -247,15 +247,15 @@ To authorize HTTP/HTTPS access to a DMZ-hosted web server, excluding known malic
|
||||
# Allow HTTP/HTTPS traffic to the DMZ web server
|
||||
firewall.dmz_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.HTTP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["HTTP"],
|
||||
dst_ip_address="172.16.0.2",
|
||||
position=9
|
||||
)
|
||||
firewall.dmz_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.HTTPS,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["HTTPS"],
|
||||
dst_ip_address="172.16.0.2",
|
||||
position=10
|
||||
)
|
||||
@@ -269,9 +269,9 @@ To facilitate restricted access from the internal network to DMZ-hosted services
|
||||
# Permit specific internal application server HTTPS access to a DMZ-hosted API
|
||||
firewall.internal_outbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
src_ip_address="192.168.1.30", # Internal application server IP
|
||||
dst_port=Port.HTTPS,
|
||||
dst_port=Port["HTTPS"],
|
||||
dst_ip_address="172.16.0.3", # DMZ API server IP
|
||||
position=11
|
||||
)
|
||||
@@ -289,9 +289,9 @@ To facilitate restricted access from the internal network to DMZ-hosted services
|
||||
# Corresponding rule in DMZ inbound ACL to allow the traffic from the specific internal server
|
||||
firewall.dmz_inbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
src_ip_address="192.168.1.30", # Ensuring this specific source is allowed
|
||||
dst_port=Port.HTTPS,
|
||||
dst_port=Port["HTTPS"],
|
||||
dst_ip_address="172.16.0.3", # DMZ API server IP
|
||||
position=13
|
||||
)
|
||||
@@ -301,7 +301,7 @@ To facilitate restricted access from the internal network to DMZ-hosted services
|
||||
action=ACLAction.DENY,
|
||||
src_ip_address="192.168.1.0",
|
||||
src_wildcard_mask="0.0.0.255",
|
||||
dst_port=Port.HTTPS,
|
||||
dst_port=Port["HTTPS"],
|
||||
dst_ip_address="172.16.0.3", # DMZ API server IP
|
||||
position=14
|
||||
)
|
||||
@@ -315,8 +315,8 @@ To block all SSH access attempts from the external network:
|
||||
# Deny all SSH traffic from any external source
|
||||
firewall.external_inbound_acl.add_rule(
|
||||
action=ACLAction.DENY,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.SSH,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["SSH"],
|
||||
position=1
|
||||
)
|
||||
|
||||
@@ -329,8 +329,8 @@ To allow the internal network to initiate HTTP connections to the external netwo
|
||||
# Permit outgoing HTTP traffic from the internal network to any external destination
|
||||
firewall.external_outbound_acl.add_rule(
|
||||
action=ACLAction.PERMIT,
|
||||
protocol=IPProtocol.TCP,
|
||||
dst_port=Port.HTTP,
|
||||
protocol=IPProtocol["TCP"],
|
||||
dst_port=Port["HTTP"],
|
||||
position=2
|
||||
)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
#########
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
############
|
||||
Network Node
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
######
|
||||
Router
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
######
|
||||
Switch
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
######
|
||||
Wireless Router
|
||||
@@ -49,7 +49,7 @@ additional steps to configure wireless settings:
|
||||
wireless_router.configure_wireless_access_point(
|
||||
port=1, ip_address="192.168.2.1",
|
||||
subnet_mask="255.255.255.0",
|
||||
frequency=AirSpaceFrequency.WIFI_2_4,
|
||||
frequency="WIFI_2_4",
|
||||
)
|
||||
|
||||
|
||||
@@ -102,7 +102,8 @@ ICMP traffic, ensuring basic network connectivity and ping functionality.
|
||||
network.connect(pc_a.network_interface[1], router_1.router_interface)
|
||||
|
||||
# Configure Router 1 ACLs
|
||||
router_1.acl.add_rule(action=ACLAction.PERMIT, protocol=IPProtocol.ICMP, position=23)
|
||||
router_1.acl.add_rule(action=ACLAction.PERMIT, src_port=PORT_LOOKUP["ARP"], dst_port=PORT_LOOKUP["ARP"], position=22)
|
||||
router_1.acl.add_rule(action=ACLAction.PERMIT, protocol=PROTOCOL_LOOKUP["ICMP"], position=23)
|
||||
|
||||
# Configure PC B
|
||||
pc_b = Computer(
|
||||
@@ -129,13 +130,13 @@ ICMP traffic, ensuring basic network connectivity and ping functionality.
|
||||
port=1,
|
||||
ip_address="192.168.1.1",
|
||||
subnet_mask="255.255.255.0",
|
||||
frequency=AirSpaceFrequency.WIFI_2_4,
|
||||
frequency="WIFI_2_4",
|
||||
)
|
||||
router_2.configure_wireless_access_point(
|
||||
port=1,
|
||||
ip_address="192.168.1.2",
|
||||
subnet_mask="255.255.255.0",
|
||||
frequency=AirSpaceFrequency.WIFI_2_4,
|
||||
frequency="WIFI_2_4",
|
||||
)
|
||||
|
||||
# Configure routes for inter-router communication
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Transport Layer to Data Link Layer
|
||||
==================================
|
||||
@@ -104,7 +104,7 @@ address of 'aa:bb:cc:dd:ee:ff' to port 8080 on the host 10.0.0.10 which has a NI
|
||||
ip_packet = IPPacket(
|
||||
src_ip_address="192.168.0.100",
|
||||
dst_ip_address="10.0.0.10",
|
||||
protocol=IPProtocol.TCP
|
||||
protocol=IPProtocol["TCP"]
|
||||
)
|
||||
# Data Link Layer
|
||||
ethernet_header = EthernetHeader(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _C2_Suite:
|
||||
|
||||
@@ -183,7 +183,7 @@ Python
|
||||
# Example command: Installing and configuring Ransomware:
|
||||
|
||||
ransomware_installation_command = { "commands": [
|
||||
["software_manager","application","install","RansomwareScript"],
|
||||
["software_manager","application","install","ransomware-script"],
|
||||
],
|
||||
"username": "admin",
|
||||
"password": "admin",
|
||||
@@ -229,7 +229,7 @@ Via Configuration
|
||||
type: computer
|
||||
...
|
||||
applications:
|
||||
type: C2Server
|
||||
type: c2-server
|
||||
...
|
||||
hostname: computer_b
|
||||
type: computer
|
||||
@@ -238,7 +238,7 @@ Via Configuration
|
||||
# Either an agent must use application_execute.
|
||||
# Or a if using the simulation layer - .establish().
|
||||
applications:
|
||||
type: C2Beacon
|
||||
type: c2-beacon
|
||||
options:
|
||||
c2_server_ip_address: ...
|
||||
keep_alive_frequency: 5
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _DataManipulationBot:
|
||||
|
||||
@@ -77,7 +77,7 @@ Python
|
||||
network.connect(endpoint_b=client_1.network_interface[1], endpoint_a=switch_2.network_interface[1])
|
||||
client_1.software_manager.install(DatabaseClient)
|
||||
client_1.software_manager.install(DataManipulationBot)
|
||||
data_manipulation_bot: DataManipulationBot = client_1.software_manager.software.get("DataManipulationBot")
|
||||
data_manipulation_bot: DataManipulationBot = client_1.software_manager.software.get("data-manipulation-bot")
|
||||
data_manipulation_bot.configure(server_ip_address=IPv4Address("192.168.1.14"), payload="DELETE")
|
||||
data_manipulation_bot.run()
|
||||
|
||||
@@ -95,39 +95,7 @@ If not using the data manipulation bot manually, it needs to be used with a data
|
||||
agents:
|
||||
- ref: data_manipulation_red_bot
|
||||
team: RED
|
||||
type: RedDatabaseCorruptingAgent
|
||||
|
||||
observation_space:
|
||||
type: UC2RedObservation
|
||||
options:
|
||||
nodes:
|
||||
- node_name: client_1
|
||||
observations:
|
||||
- logon_status
|
||||
- operating_status
|
||||
applications:
|
||||
- application_ref: data_manipulation_bot
|
||||
observations:
|
||||
operating_status
|
||||
health_status
|
||||
folders: {}
|
||||
|
||||
action_space:
|
||||
action_list:
|
||||
- type: DONOTHING
|
||||
- type: NODE_APPLICATION_EXECUTE
|
||||
options:
|
||||
nodes:
|
||||
- node_name: client_1
|
||||
applications:
|
||||
- application_ref: data_manipulation_bot
|
||||
max_folders_per_node: 1
|
||||
max_files_per_folder: 1
|
||||
max_services_per_node: 1
|
||||
|
||||
reward_function:
|
||||
reward_components:
|
||||
- type: DUMMY
|
||||
type: red-database-corrupting-agent
|
||||
|
||||
agent_settings:
|
||||
start_settings:
|
||||
@@ -144,14 +112,14 @@ If not using the data manipulation bot manually, it needs to be used with a data
|
||||
# ... additional configuration here
|
||||
applications:
|
||||
- ref: data_manipulation_bot
|
||||
type: DataManipulationBot
|
||||
type: data-manipulation-bot
|
||||
options:
|
||||
port_scan_p_of_success: 0.1
|
||||
data_manipulation_p_of_success: 0.1
|
||||
payload: "DELETE"
|
||||
server_ip: 192.168.1.14
|
||||
- ref: web_server_database_client
|
||||
type: DatabaseClient
|
||||
type: database-client
|
||||
options:
|
||||
db_server_ip: 192.168.1.14
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _DatabaseClient:
|
||||
|
||||
@@ -59,7 +59,7 @@ Python
|
||||
# install DatabaseClient
|
||||
client.software_manager.install(DatabaseClient)
|
||||
|
||||
database_client: DatabaseClient = client.software_manager.software.get("DatabaseClient")
|
||||
database_client: DatabaseClient = client.software_manager.software.get("database-client")
|
||||
|
||||
# Configure the DatabaseClient
|
||||
database_client.configure(server_ip_address=IPv4Address("192.168.0.1")) # address of the DatabaseService
|
||||
@@ -83,7 +83,7 @@ Via Configuration
|
||||
...
|
||||
applications:
|
||||
- ref: database_client
|
||||
type: DatabaseClient
|
||||
type: database-client
|
||||
options:
|
||||
db_server_ip: 192.168.0.1
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _DoSBot:
|
||||
|
||||
DoSBot
|
||||
dos-bot
|
||||
######
|
||||
|
||||
The ``DoSBot`` is an implementation of a Denial of Service attack within the PrimAITE simulation.
|
||||
The ``dos-bot`` is an implementation of a Denial of Service attack within the PrimAITE simulation.
|
||||
This specifically simulates a `Slow Loris attack`_.
|
||||
|
||||
.. _Slow Loris Attack: https://en.wikipedia.org/wiki/Slowloris_(computer_security)
|
||||
@@ -15,20 +15,20 @@ This specifically simulates a `Slow Loris attack`_.
|
||||
Key features
|
||||
============
|
||||
|
||||
- Connects to the :ref:`DatabaseService` via the ``SoftwareManager``.
|
||||
- Makes many connections to the :ref:`DatabaseService` which ends up using up the available connections.
|
||||
- Connects to the :ref:`database-service` via the ``SoftwareManager``.
|
||||
- Makes many connections to the :ref:`database-service` which ends up using up the available connections.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
- Configure with target IP address and optional password.
|
||||
- use ``run`` to run the application_loop of DoSBot to begin attacks
|
||||
- DoSBot runs through different actions at each timestep
|
||||
- use ``run`` to run the application_loop of dos-bot to begin attacks
|
||||
- dos-bot runs through different actions at each timestep
|
||||
|
||||
Implementation
|
||||
==============
|
||||
|
||||
- Leverages :ref:`DatabaseClient` to create connections with :ref`DatabaseServer`.
|
||||
- Leverages :ref:`database-client` to create connections with :ref`DatabaseServer`.
|
||||
- Extends base Application class.
|
||||
|
||||
Examples
|
||||
@@ -42,7 +42,7 @@ Python
|
||||
from ipaddress import IPv4Address
|
||||
|
||||
from primaite.simulator.network.hardware.nodes.host.computer import Computer
|
||||
from primaite.simulator.system.applications.red_applications.dos_bot import DoSBot
|
||||
from primaite.simulator.system.applications.red_applications.dos_bot import dos-bot
|
||||
|
||||
# Create Computer
|
||||
computer = Computer(
|
||||
@@ -54,11 +54,11 @@ Python
|
||||
)
|
||||
computer.power_on()
|
||||
|
||||
# Install DoSBot on computer
|
||||
computer.software_manager.install(DoSBot)
|
||||
dos_bot: DoSBot = computer.software_manager.software.get("DoSBot")
|
||||
# Install dos-bot on computer
|
||||
computer.software_manager.install(dos-bot)
|
||||
dos_bot: dos-bot = computer.software_manager.software.get("dos-bot")
|
||||
|
||||
# Configure the DoSBot
|
||||
# Configure the dos-bot
|
||||
dos_bot.configure(
|
||||
target_ip_address=IPv4Address("192.168.0.10"),
|
||||
payload="SPOOF DATA",
|
||||
@@ -68,7 +68,7 @@ Python
|
||||
max_sessions=1000
|
||||
)
|
||||
|
||||
# run DoSBot
|
||||
# run dos-bot
|
||||
dos_bot.run()
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ Via Configuration
|
||||
...
|
||||
applications:
|
||||
- ref: dos_bot
|
||||
type: DoSBot
|
||||
type: dos-bot
|
||||
options:
|
||||
target_ip_address: 192.168.0.10
|
||||
payload: SPOOF DATA
|
||||
@@ -101,7 +101,7 @@ Configuration
|
||||
``target_ip_address``
|
||||
"""""""""""""""""""""
|
||||
|
||||
IP address of the :ref:`DatabaseService` which the ``DataManipulationBot`` will try to attack.
|
||||
IP address of the :ref:`database-service` which the ``data-manipulation-bot`` will try to attack.
|
||||
|
||||
This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``.
|
||||
|
||||
@@ -119,7 +119,7 @@ See :ref:`List of IPProtocols <List of IPProtocols>` for a list of protocols.
|
||||
|
||||
Optional. Default value is ``None``.
|
||||
|
||||
The payload that the ``DoSBot`` sends as part of its attack.
|
||||
The payload that the ``dos-bot`` sends as part of its attack.
|
||||
|
||||
.. include:: ../common/db_payload_list.rst
|
||||
|
||||
@@ -128,14 +128,14 @@ The payload that the ``DoSBot`` sends as part of its attack.
|
||||
|
||||
Optional. Default value is ``False``.
|
||||
|
||||
If ``True`` the ``DoSBot`` will maintain its attack.
|
||||
If ``True`` the ``dos-bot`` will maintain its attack.
|
||||
|
||||
``port_scan_p_of_success``
|
||||
""""""""""""""""""""""""""
|
||||
|
||||
Optional. Default value is ``0.1``.
|
||||
|
||||
The chance of the ``DoSBot`` to succeed with a port scan (and therefore continue the attack).
|
||||
The chance of the ``dos-bot`` to succeed with a port scan (and therefore continue the attack).
|
||||
|
||||
This must be a float value between ``0`` and ``1``.
|
||||
|
||||
@@ -153,7 +153,7 @@ This must be a float value between ``0`` and ``1``.
|
||||
|
||||
Optional. Default value is ``1000``.
|
||||
|
||||
The maximum number of sessions the ``DoSBot`` is able to make.
|
||||
The maximum number of sessions the ``dos-bot`` is able to make.
|
||||
|
||||
This must be an integer value equal to or greater than ``0``.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _NMAP:
|
||||
|
||||
@@ -165,8 +165,8 @@ Perform a horizontal port scan on port 5432 across multiple IP addresses:
|
||||
|
||||
{
|
||||
IPv4Address('192.168.1.12'): {
|
||||
<IPProtocol.TCP: 'tcp'>: [
|
||||
<Port.POSTGRES_SERVER: 5432>
|
||||
<IPProtocol["TCP"]: 'tcp'>: [
|
||||
<Port["POSTGRES_SERVER"]: 5432>
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ Perform a vertical port scan on multiple ports on a single IP address:
|
||||
|
||||
vertical_scan_results = pc_1_nmap.port_scan(
|
||||
target_ip_address=[IPv4Address("192.168.1.12")],
|
||||
target_port=[Port(21), Port(22), Port(80), Port(443)]
|
||||
target_port=[21, 22, 80, 443]
|
||||
)
|
||||
|
||||
.. code-block:: python
|
||||
@@ -200,9 +200,9 @@ Perform a vertical port scan on multiple ports on a single IP address:
|
||||
|
||||
{
|
||||
IPv4Address('192.168.1.12'): {
|
||||
<IPProtocol.TCP: 'tcp'>: [
|
||||
<Port.FTP: 21>,
|
||||
<Port.HTTP: 80>
|
||||
<IPProtocol["TCP"]: 'tcp'>: [
|
||||
<Port["FTP"]: 21>,
|
||||
<Port["HTTP"]: 80>
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -233,7 +233,7 @@ Perform a box scan on multiple ports across multiple IP addresses:
|
||||
|
||||
box_scan_results = pc_1_nmap.port_scan(
|
||||
target_ip_address=[IPv4Address("192.168.1.12"), IPv4Address("192.168.1.13")],
|
||||
target_port=[Port(21), Port(22), Port(80), Port(443)]
|
||||
target_port=[21, 22, 80, 443]
|
||||
)
|
||||
|
||||
.. code-block:: python
|
||||
@@ -241,15 +241,15 @@ Perform a box scan on multiple ports across multiple IP addresses:
|
||||
|
||||
{
|
||||
IPv4Address('192.168.1.13'): {
|
||||
<IPProtocol.TCP: 'tcp'>: [
|
||||
<Port.FTP: 21>,
|
||||
<Port.HTTP: 80>
|
||||
<IPProtocol["TCP"]: 'tcp'>: [
|
||||
<Port["FTP"]: 21>,
|
||||
<Port["HTTP"]: 80>
|
||||
]
|
||||
},
|
||||
IPv4Address('192.168.1.12'): {
|
||||
<IPProtocol.TCP: 'tcp'>: [
|
||||
<Port.FTP: 21>,
|
||||
<Port.HTTP: 80>
|
||||
<IPProtocol["TCP"]: 'tcp'>: [
|
||||
<Port["FTP"]: 21>,
|
||||
<Port["HTTP"]: 80>
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -289,36 +289,36 @@ Perform a full box scan on all ports, over both TCP and UDP, on a whole subnet:
|
||||
|
||||
{
|
||||
IPv4Address('192.168.1.11'): {
|
||||
<IPProtocol.UDP: 'udp'>: [
|
||||
<Port.ARP: 219>
|
||||
<IPProtocol["UDP"]: 'udp'>: [
|
||||
<Port["ARP"]: 219>
|
||||
]
|
||||
},
|
||||
IPv4Address('192.168.1.1'): {
|
||||
<IPProtocol.UDP: 'udp'>: [
|
||||
<Port.ARP: 219>
|
||||
<IPProtocol["UDP"]: 'udp'>: [
|
||||
<Port["ARP"]: 219>
|
||||
]
|
||||
},
|
||||
IPv4Address('192.168.1.12'): {
|
||||
<IPProtocol.TCP: 'tcp'>: [
|
||||
<Port.HTTP: 80>,
|
||||
<Port.DNS: 53>,
|
||||
<Port.POSTGRES_SERVER: 5432>,
|
||||
<Port.FTP: 21>
|
||||
<IPProtocol["TCP"]: 'tcp'>: [
|
||||
<Port["HTTP"]: 80>,
|
||||
<Port["DNS"]: 53>,
|
||||
<Port["POSTGRES_SERVER"]: 5432>,
|
||||
<Port["FTP"]: 21>
|
||||
],
|
||||
<IPProtocol.UDP: 'udp'>: [
|
||||
<Port.NTP: 123>,
|
||||
<Port.ARP: 219>
|
||||
<IPProtocol["UDP"]: 'udp'>: [
|
||||
<Port["NTP"]: 123>,
|
||||
<Port["ARP"]: 219>
|
||||
]
|
||||
},
|
||||
IPv4Address('192.168.1.13'): {
|
||||
<IPProtocol.TCP: 'tcp'>: [
|
||||
<Port.HTTP: 80>,
|
||||
<Port.DNS: 53>,
|
||||
<Port.FTP: 21>
|
||||
<IPProtocol["TCP"]: 'tcp'>: [
|
||||
<Port["HTTP"]: 80>,
|
||||
<Port["DNS"]: 53>,
|
||||
<Port["FTP"]: 21>
|
||||
],
|
||||
<IPProtocol.UDP: 'udp'>: [
|
||||
<Port.NTP: 123>,
|
||||
<Port.ARP: 219>
|
||||
<IPProtocol["UDP"]: 'udp'>: [
|
||||
<Port["NTP"]: 123>,
|
||||
<Port["ARP"]: 219>
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _RansomwareScript:
|
||||
|
||||
@@ -62,7 +62,7 @@ Python
|
||||
network.connect(endpoint_b=client_1.network_interface[1], endpoint_a=switch_2.network_interface[1])
|
||||
client_1.software_manager.install(DatabaseClient)
|
||||
client_1.software_manager.install(RansomwareScript)
|
||||
RansomwareScript: RansomwareScript = client_1.software_manager.software.get("RansomwareScript")
|
||||
RansomwareScript: RansomwareScript = client_1.software_manager.software.get("ransomware-script")
|
||||
RansomwareScript.configure(server_ip_address=IPv4Address("192.168.1.14"))
|
||||
RansomwareScript.execute()
|
||||
|
||||
@@ -70,7 +70,7 @@ Python
|
||||
Configuration
|
||||
=============
|
||||
|
||||
The RansomwareScript inherits configuration options such as ``fix_duration`` from its parent class. However, for the ``RansomwareScript`` the most relevant option is ``server_ip``.
|
||||
The RansomwareScript inherits configuration options such as ``fixing_duration`` from its parent class. However, for the ``RansomwareScript`` the most relevant option is ``server_ip``.
|
||||
|
||||
|
||||
``server_ip``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _WebBrowser:
|
||||
|
||||
@@ -61,7 +61,7 @@ The :ref:`DNSClient` must be configured to use the :ref:`DNSServer`. The :ref:`D
|
||||
|
||||
# Install WebBrowser on computer
|
||||
computer.software_manager.install(WebBrowser)
|
||||
web_browser: WebBrowser = computer.software_manager.software.get("WebBrowser")
|
||||
web_browser: WebBrowser = computer.software_manager.software.get("web-browser")
|
||||
web_browser.run()
|
||||
|
||||
# configure the WebBrowser
|
||||
@@ -85,7 +85,7 @@ Via Configuration
|
||||
...
|
||||
applications:
|
||||
- ref: web_browser
|
||||
type: WebBrowser
|
||||
type: web-browser
|
||||
options:
|
||||
target_url: http://arcd.com/
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _Common Configuration:
|
||||
|
||||
@@ -22,8 +22,8 @@ options
|
||||
|
||||
The configuration options are the attributes that fall under the options for an application or service.
|
||||
|
||||
fix_duration
|
||||
""""""""""""
|
||||
fixing_duration
|
||||
"""""""""""""""
|
||||
|
||||
Optional. Default value is ``2``.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _Database Payload List:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _internal_frame_processing:
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
``system applications``
|
||||
"""""""""""""""""""""""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
``system services``
|
||||
"""""""""""""""""""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
PCAP
|
||||
====
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _DatabaseService:
|
||||
|
||||
@@ -66,7 +66,7 @@ Python
|
||||
|
||||
# Install DatabaseService on server
|
||||
server.software_manager.install(DatabaseService)
|
||||
db_service: DatabaseService = server.software_manager.software.get("DatabaseService")
|
||||
db_service: DatabaseService = server.software_manager.software.get("database-service")
|
||||
db_service.start()
|
||||
|
||||
# configure DatabaseService
|
||||
@@ -87,7 +87,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: database_service
|
||||
type: DatabaseService
|
||||
type: database-service
|
||||
options:
|
||||
backup_server_ip: 192.168.0.10
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _DNSClient:
|
||||
|
||||
@@ -56,7 +56,7 @@ Python
|
||||
|
||||
# Install DNSClient on server
|
||||
server.software_manager.install(DNSClient)
|
||||
dns_client: DNSClient = server.software_manager.software.get("DNSClient")
|
||||
dns_client: DNSClient = server.software_manager.software.get("dns-client")
|
||||
dns_client.start()
|
||||
|
||||
# configure DatabaseService
|
||||
@@ -77,7 +77,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: dns_client
|
||||
type: DNSClient
|
||||
type: dns-client
|
||||
options:
|
||||
dns_server: 192.168.0.10
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _DNSServer:
|
||||
|
||||
@@ -53,7 +53,7 @@ Python
|
||||
|
||||
# Install DNSServer on server
|
||||
server.software_manager.install(DNSServer)
|
||||
dns_server: DNSServer = server.software_manager.software.get("DNSServer")
|
||||
dns_server: DNSServer = server.software_manager.software.get("dns-server")
|
||||
dns_server.start()
|
||||
|
||||
# configure DatabaseService
|
||||
@@ -74,7 +74,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: dns_server
|
||||
type: DNSServer
|
||||
type: dns-server
|
||||
options:
|
||||
domain_mapping:
|
||||
arcd.com: 192.168.0.10
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _FTPClient:
|
||||
|
||||
@@ -15,7 +15,7 @@ Key features
|
||||
- Connects to the :ref:`FTPServer` via the ``SoftwareManager``.
|
||||
- Simulates FTP requests and FTPPacket transfer across a network
|
||||
- Allows the emulation of FTP commands between an FTP client and server:
|
||||
- PORT: specifies the port that server should connect to on the client (currently only uses ``Port.FTP``)
|
||||
- PORT: specifies the port that server should connect to on the client (currently only uses ``Port["FTP"]``)
|
||||
- STOR: stores a file from client to server
|
||||
- RETR: retrieves a file from the FTP server
|
||||
- QUIT: disconnect from server
|
||||
@@ -60,7 +60,7 @@ Python
|
||||
|
||||
# Install FTPClient on server
|
||||
server.software_manager.install(FTPClient)
|
||||
ftp_client: FTPClient = server.software_manager.software.get("FTPClient")
|
||||
ftp_client: FTPClient = server.software_manager.software.get("ftp-client")
|
||||
ftp_client.start()
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: ftp_client
|
||||
type: FTPClient
|
||||
type: ftp-client
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _FTPServer:
|
||||
|
||||
@@ -55,7 +55,7 @@ Python
|
||||
|
||||
# Install FTPServer on server
|
||||
server.software_manager.install(FTPServer)
|
||||
ftp_server: FTPServer = server.software_manager.software.get("FTPServer")
|
||||
ftp_server: FTPServer = server.software_manager.software.get("ftp-server")
|
||||
ftp_server.start()
|
||||
|
||||
ftp_server.server_password = "test"
|
||||
@@ -74,7 +74,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: ftp_server
|
||||
type: FTPServer
|
||||
type: ftp-server
|
||||
options:
|
||||
server_password: test
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _NTPClient:
|
||||
|
||||
@@ -53,7 +53,7 @@ Python
|
||||
|
||||
# Install NTPClient on server
|
||||
server.software_manager.install(NTPClient)
|
||||
ntp_client: NTPClient = server.software_manager.software.get("NTPClient")
|
||||
ntp_client: NTPClient = server.software_manager.software.get("ntp-client")
|
||||
ntp_client.start()
|
||||
|
||||
ntp_client.configure(ntp_server_ip_address=IPv4Address("192.168.0.10"))
|
||||
@@ -73,7 +73,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: ntp_client
|
||||
type: NTPClient
|
||||
type: ntp-client
|
||||
options:
|
||||
ntp_server_ip: 192.168.0.10
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _NTPServer:
|
||||
|
||||
@@ -55,7 +55,7 @@ Python
|
||||
|
||||
# Install NTPServer on server
|
||||
server.software_manager.install(NTPServer)
|
||||
ntp_server: NTPServer = server.software_manager.software.get("NTPServer")
|
||||
ntp_server: NTPServer = server.software_manager.software.get("ntp-server")
|
||||
ntp_server.start()
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: ntp_server
|
||||
type: NTPServer
|
||||
type: ntp-server
|
||||
|
||||
|
||||
``Common Attributes``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _Terminal:
|
||||
|
||||
@@ -78,16 +78,16 @@ The below code examples demonstrate how to use terminal related actions in yaml
|
||||
yaml
|
||||
""""
|
||||
|
||||
``NODE_SEND_LOCAL_COMMAND``
|
||||
``node-send-local-command``
|
||||
"""""""""""""""""""""""""""
|
||||
|
||||
Agents can execute local commands without needing to perform a separate remote login action (``SSH_TO_REMOTE``).
|
||||
Agents can execute local commands without needing to perform a separate remote login action (``node-session-remote-login``).
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
...
|
||||
...
|
||||
action: NODE_SEND_LOCAL_COMMAND
|
||||
action: node-send-local-command
|
||||
options:
|
||||
node_id: 0
|
||||
username: admin
|
||||
@@ -101,7 +101,7 @@ Agents can execute local commands without needing to perform a separate remote l
|
||||
- "False"
|
||||
|
||||
|
||||
``SSH_TO_REMOTE``
|
||||
``node-session-remote-login``
|
||||
"""""""""""""""""
|
||||
|
||||
Agents are able to use the terminal to login into remote nodes via ``SSH`` which allows for agents to execute commands on remote hosts.
|
||||
@@ -110,7 +110,7 @@ Agents are able to use the terminal to login into remote nodes via ``SSH`` which
|
||||
|
||||
...
|
||||
...
|
||||
action: SSH_TO_REMOTE
|
||||
action: node-session-remote-login
|
||||
options:
|
||||
node_id: 0
|
||||
username: admin
|
||||
@@ -118,16 +118,16 @@ Agents are able to use the terminal to login into remote nodes via ``SSH`` which
|
||||
remote_ip: 192.168.0.10 # Example Ip Address. (The remote host's IP that will be used by ssh)
|
||||
|
||||
|
||||
``NODE_SEND_REMOTE_COMMAND``
|
||||
``node-send-remote-command``
|
||||
""""""""""""""""""""""""""""
|
||||
|
||||
After remotely logging into another host, an agent can use the ``NODE_SEND_REMOTE_COMMAND`` to execute commands across the network remotely.
|
||||
After remotely logging into another host, an agent can use the ``node-send-remote-command`` to execute commands across the network remotely.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
...
|
||||
...
|
||||
action: NODE_SEND_REMOTE_COMMAND
|
||||
action: node-send-remote-command
|
||||
options:
|
||||
node_id: 0
|
||||
remote_ip: 192.168.0.10
|
||||
@@ -166,7 +166,7 @@ Python
|
||||
operating_state=NodeOperatingState.ON,
|
||||
)
|
||||
|
||||
terminal: Terminal = client.software_manager.software.get("Terminal")
|
||||
terminal: Terminal = client.software_manager.software.get("terminal")
|
||||
|
||||
Creating Remote Terminal Connection
|
||||
"""""""""""""""""""""""""""""""""""
|
||||
@@ -187,7 +187,7 @@ Creating Remote Terminal Connection
|
||||
node_b.power_on()
|
||||
network.connect(node_a.network_interface[1], node_b.network_interface[1])
|
||||
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("Terminal")
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("terminal")
|
||||
|
||||
|
||||
term_a_term_b_remote_connection: RemoteTerminalConnection = terminal_a.login(username="admin", password="Admin123!", ip_address="192.168.0.11")
|
||||
@@ -213,12 +213,12 @@ Executing a basic application install command
|
||||
node_b.power_on()
|
||||
network.connect(node_a.network_interface[1], node_b.network_interface[1])
|
||||
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("Terminal")
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("terminal")
|
||||
|
||||
|
||||
term_a_term_b_remote_connection: RemoteTerminalConnection = terminal_a.login(username="admin", password="Admin123!", ip_address="192.168.0.11")
|
||||
|
||||
term_a_term_b_remote_connection.execute(["software_manager", "application", "install", "RansomwareScript"])
|
||||
term_a_term_b_remote_connection.execute(["software_manager", "application", "install", "ransomware-script"])
|
||||
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ Creating a folder on a remote node
|
||||
node_b.power_on()
|
||||
network.connect(node_a.network_interface[1], node_b.network_interface[1])
|
||||
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("Terminal")
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("terminal")
|
||||
|
||||
|
||||
term_a_term_b_remote_connection: RemoteTerminalConnection = terminal_a.login(username="admin", password="Admin123!", ip_address="192.168.0.11")
|
||||
@@ -268,7 +268,7 @@ Disconnect from Remote Node
|
||||
node_b.power_on()
|
||||
network.connect(node_a.network_interface[1], node_b.network_interface[1])
|
||||
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("Terminal")
|
||||
terminal_a: Terminal = node_a.software_manager.software.get("terminal")
|
||||
|
||||
|
||||
term_a_term_b_remote_connection: RemoteTerminalConnection = terminal_a.login(username="admin", password="Admin123!", ip_address="192.168.0.11")
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _WebServer:
|
||||
|
||||
@@ -56,7 +56,7 @@ Python
|
||||
|
||||
# Install WebServer on server
|
||||
server.software_manager.install(WebServer)
|
||||
web_server: WebServer = server.software_manager.software.get("WebServer")
|
||||
web_server: WebServer = server.software_manager.software.get("web-server")
|
||||
web_server.start()
|
||||
|
||||
Via Configuration
|
||||
@@ -73,7 +73,7 @@ Via Configuration
|
||||
...
|
||||
services:
|
||||
- ref: web_server
|
||||
type: WebServer
|
||||
type: web-server
|
||||
|
||||
|
||||
``Common Attributes``
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Session and Software Manager
|
||||
============================
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
.. _software:
|
||||
|
||||
@@ -30,7 +30,7 @@ See :ref:`Node Start up and Shut down`
|
||||
|
||||
node.software_manager.install(WebServer)
|
||||
|
||||
web_server: WebServer = node.software_manager.software.get("WebServer")
|
||||
web_server: WebServer = node.software_manager.software.get("web-server")
|
||||
assert web_server.operating_state is ServiceOperatingState.RUNNING # service is immediately ran after install
|
||||
|
||||
node.power_off()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
SysLog
|
||||
======
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
|
||||
Simulation Structure
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Simulation State
|
||||
================
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. only:: comment
|
||||
|
||||
© Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
© Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
|
||||
Defining variations in the config files
|
||||
=======================================
|
||||
|
||||
@@ -7,7 +7,7 @@ name = "primaite"
|
||||
description = "PrimAITE (Primary-level AI Training Environment) is a simulation environment for training AI under the ARCD programme."
|
||||
authors = [{name="Defence Science and Technology Laboratory UK", email="oss@dstl.gov.uk"}]
|
||||
license = {file = "LICENSE"}
|
||||
requires-python = ">=3.9, <3.12"
|
||||
requires-python = ">=3.9, <3.13"
|
||||
dynamic = ["version", "readme"]
|
||||
classifiers = [
|
||||
"Development Status :: 5 - Production/Stable",
|
||||
@@ -26,15 +26,15 @@ dependencies = [
|
||||
"gymnasium==0.28.1",
|
||||
"jupyterlab==3.6.1",
|
||||
"kaleido==0.2.1",
|
||||
"matplotlib==3.7.1",
|
||||
"matplotlib>=3.7.1",
|
||||
"networkx==3.1",
|
||||
"numpy==1.23.5",
|
||||
"numpy~=1.23",
|
||||
"platformdirs==3.5.1",
|
||||
"plotly==5.15.0",
|
||||
"polars==0.20.30",
|
||||
"prettytable==3.8.0",
|
||||
"PyYAML==6.0",
|
||||
"typer[all]==0.9.0",
|
||||
"PyYAML>=6.0",
|
||||
"typer[all]>=0.9",
|
||||
"pydantic==2.7.0",
|
||||
"ipywidgets",
|
||||
"deepdiff"
|
||||
@@ -53,8 +53,8 @@ license-files = ["LICENSE"]
|
||||
[project.optional-dependencies]
|
||||
rl = [
|
||||
"ray[rllib] >= 2.20.0, <2.33",
|
||||
"tensorflow==2.12.0",
|
||||
"stable-baselines3[extra]==2.1.0",
|
||||
"tensorflow~=2.12",
|
||||
"stable-baselines3==2.1.0",
|
||||
"sb3-contrib==2.1.0",
|
||||
]
|
||||
dev = [
|
||||
@@ -69,7 +69,7 @@ dev = [
|
||||
"pytest-xdist==3.3.1",
|
||||
"pytest-cov==4.0.0",
|
||||
"pytest-flake8==1.1.1",
|
||||
"setuptools==66",
|
||||
"setuptools==75.6.0",
|
||||
"Sphinx==7.1.2",
|
||||
"sphinx-copybutton==0.5.2",
|
||||
"wheel==0.38.4",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
import subprocess
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.4.0-dev
|
||||
4.0.0-dev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
import datetime as datetime
|
||||
import logging
|
||||
import logging.config
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
"""Provides a CLI using Typer as an entry point."""
|
||||
import logging
|
||||
import os
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
# © Crown-owned copyright 2024, Defence Science and Technology Laboratory UK
|
||||
# © Crown-owned copyright 2025, Defence Science and Technology Laboratory UK
|
||||
"""Configuration parameters for running experiments."""
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
metadata:
|
||||
version: 3.0
|
||||
|
||||
game:
|
||||
ports:
|
||||
- ARP
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
metadata:
|
||||
version: 3.0
|
||||
|
||||
game:
|
||||
ports:
|
||||
- ARP
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user