## Summary
Updates Pre-commit with the a check to ensure valid copyright headers
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2646
## Summary
- Integrates the NIC traffic into the observation space
- Added `monitored_traffic` property into agent config which specifies which traffic is going to be included in observation
## Test process
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/419?_a=files&path=/tests/integration_tests/game_layer/observations/test_nic_observations.py
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2658
## Summary
Add to the config placeholder notebook. Now we also explain how to vary the simulation between episodes.
## Test process
precommit pass. notebook runs.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2502 add more info about config placeholders
Related work items: #2502
## Summary
The build-docs pipeline has been failing to run. This PR corrects it.
## Test process
Link to successfully running:
https://dev.azure.com/ma-dev-uk/PrimAITE/_build/results?buildId=4849&view=results
Previous failures can be seen in the pipeline history.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
One line change to try and resolve build docs pipeline failure
Related work items: #2659
## Summary
Change the way db client uninstall happens.
Now if a client_connection disconnect fails, we just drop it anyway, not sure if this causes other issues so pls review this diligently, especially @<Charlie Crane> . in case there's a potential issue with not fully dropping connections.
## Test process
pytest is running very nicely
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Fix database client uninstall failing due to persistent connection
## Summary
NMAP application added which will be utilised by red agents
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1847, #2618, #2628
## Summary
Updated the benchmark script so that it's compatible with PrimAITE v3.0.0
Chris also ran the benchmark and included the results
the script should also now work via cli (`python ./benchmark/primaite_benchmark.py`)
## Test process
n/a
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2628
## Summary
Added NMAP application, documentation, and tests.
## Test process
*Multiple tests for ping and port scan. Predefined expected results against actual results.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [X] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2618 - Added NMAP application, documentation, and tests.
Related work items: #2618
## Summary
Removed irrelevant stages from the ransomware script application
## Test process
no big changes, so existing tests were used. only a minor change in test, which no longer applies
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2610: removed tap logic from ransomware script
Related work items: #2610
- Merge branch 'feature/2588-minimal-deps' into bugfix/2626-too-many-open-files
- #2626 fix too many open files bug
- Merge remote-tracking branch 'origin/dev' into bugfix/reward-logging
- fix reward logging
- Merge remote-tracking branch 'origin/dev' into bugfix/reward-logging
- get ray to stop crashing
- Merged PR 394: Fix 'too many open files'
- Merged PR 395: Fix reward logging and get ray to stop complaining
- Fix firewall diagram
Related work items: #2588, #2626
## Summary
Change the agent history log to also spit out rewards correctly.
Make ray adhere to new ray API
## Test process
Unit test pass
All notebooks run without crash
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
## Summary
Add a method to PCAP to clear file handlers. Invoke this method while resetting environment.
## Test process
no longer crashes on windows when i run too many episodes
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [n] written **tests** for any new functionality added with this PR
- [n] updated the **documentation** if this PR changes or adds functionality
- [n] written/updated **design docs** if this PR implements new functionality
- [n] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2588, #2626
## Summary
Make it optional to install ray, sb3, and their dependencies.
## Test process
pytest and notebooks
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2588 optional RL deps
Related work items: #2588
Feedback Issues left:
1.Issues with red-agent image not embeded correctly in data_manipulation_e2e notebook
2._autosummary/tests.unit_tests.html is still completely blank.
3. _index.html is not updated with new 2-pager
4. _dependencies is not updated to just include tier-1 and primary for v3.
5. definiton of user_app_home is not confirmed
## Summary
*Replace this text with an explanation of what the changes are and how you implemented them. Can this impact any other parts of the codebase that we should keep in mind?*
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2563: notebook explaining how to get simulation information from PrimAITE
Related work items: #2563
## Summary
This PR removes the hardcoding of Link bandwidth, and makes it possible to be configured via the network yaml definitions.
Link bandwidth will still default to 100 if this is not present, to prevent breaking all previous defined networks.
## Test process
All tests continue to pass.
`basic_network_config.yaml` now provides a non-default link bandwidth which is confirmed within unit tests.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2457
## Summary
Some minor changes to the network_simulator_demo jupyter notebook so that all cells run.
I've updated the notebook to use a **very lightly** modified version of the ARCD UC2 network that it has been using.
_I've added a single route into the router_1 route table so that `network.get_node_by_hostname("router_1").route_table.show()` returns something visible. I didn't want to have this within the 'normal' uc2 network. Don't @ me._

Corrected a path typo in `basic_lan_network_example()` so it correctly loads that network config.
## Test process
I've not broken any existing tests, and the notebook now runs with fully populated cells.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [X] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2560
## Summary
Added requests in file system that allows:
- file to be created
- folder to be created
- file to be "accessed"
## Test process
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/378?_a=files&path=/tests/integration_tests/test_simulation/test_request_response.py
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2606
## Summary
- Set the DatabaseServer service to automatically install the upon install to enable backup. Added some defensive statements that gracefully handle backup/restore requests when FTPClient is not installed.
## Test process
Added test that installs `DatabaseServer` on a new node then checks for an installed `FTPClient`.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2561 - Set the DatabaseServer service to automatically install the upon install to enable backup. Added some defensive statements that gracefully handle backup/restore requests when FTPClient is not
Related work items: #2561, #2570
## Summary
Integrating the notebooks into the primaite sphinx socumentation
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2472
## Summary
Removed 'real files' from FileSystem and FTP
## Test process
- Dropped any tests that contain 'real files'
- Ran remaining tests to check that everything still works
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
2536 - Removed 'real files' from FileSystem and FTP
Related work items: #2536
## Summary
Backport changes from sensitive into core.
Mainly the application install and a couple of test changes.
## Test process
pytest
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2550 Backport changes into core
Related work items: #2549, #2550
## Summary
This is a two line change to `README.md` to correct the Python versions listed as a pre-requisite for PrimAITE, contradicting what is in `pyproject.toml`
We do not currently support Python3.11, which the README suggests we do.
## Test process
Not Applicable - Although I have installed v3b7 using Python3.11 as part of the bugfix investigation on a blank Ubuntu VM, and the install looks to of ran smoothly.
`Data-Manipulation-E2E-Demonstration` & `Training-an-SB3-Agent` both ran fine.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [X] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
#2464 - Correcting Python versioning pre-req range on README.md as we do not currently support Python3.11
Related work items: #2464
## Summary
Demonstration notebook show how to use SB3 SubprocVecEnv to vectorise environments to speed up training.
## Test process
Successfully run notebook on Windows and Linux.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2442
## Summary
REMOVE ftp client from host node default software and add it to computer default software, effectively removing it from servers.
Ensure tests are using the uc2 yaml file instead of outdated network generator function.
Fix some tests to make sure it all passing
## Test process
I have tested it.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Make ftp client only default on computers, not servers
Related work items: #2546
## Summary
Improved dev tools:
- can configure what the dev mode can override
- sys log level
- outputting sys log
- outputting pcap logs
- outputting to terminal
- the location where to output session (by default will print to the primaite repo root)
## Test process
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/359?_a=files&path=/tests/integration_tests/cli/test_dev_cli.py
and a lot of manually checking if the thing outputs to the correct directories
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2447, #2533
## Summary
- Refactored all air-space usage to that a new instance of `AirSpace` is created for each instance of Network. This 1:1 relationship between network and airspace will allow parallelization.
## Test process
- Original test remains the same. TDD, init.
- Added additional `WirelessRouter` test that tests wireless connectivity from config file too.
``` text
C:\Users\ChristopherMcCarthy\source\azure_devops\ma-dev-uk\PrimAITE\venv\Scripts\python.exe "C:/Program Files/JetBrains/PyCharm 2023.3.5/plugins/python/helpers/pycharm/_jb_pytest_runner.py" --path C:\Users\ChristopherMcCarthy\source\azure_devops\ma-dev-uk\PrimAITE\tests\integration_tests\network\test_wireless_router.py
Testing started at 15:33 ...
Launching pytest with arguments C:\Users\ChristopherMcCarthy\source\azure_devops\ma-dev-uk\PrimAITE\tests\integration_tests\network\test_wireless_router.py --no-header --no-summary -q in C:\Users\ChristopherMcCarthy\source\azure_devops\ma-dev-uk\PrimAITE\tests\integration_tests\network
============================= test session starts =============================
collecting ... collected 2 items
test_wireless_router.py::test_cross_wireless_wan_connectivity
test_wireless_router.py::test_cross_wireless_wan_connectivity_from_yaml
======================== 2 passed, 1 warning in 0.14s =========================
+----------------+-------------------+-------------+---------------+--------------+---------+
| Connected Node | MAC Address | IP Address | Subnet Mask | Frequency | Status |
+----------------+-------------------+-------------+---------------+--------------+---------+
| router_1 | da:9a:08:17:80:a4 | 192.168.1.1 | 255.255.255.0 | WiFi 2.4 GHz | Enabled |
| router_2 | 0d:67:76:5e:c2:fb | 192.168.1.2 | 255.255.255.0 | WiFi 2.4 GHz | Enabled |
+----------------+-------------------+-------------+---------------+--------------+---------+
PASSED [ 50%]+----------------+-------------------+-------------+---------------+--------------+---------+
| Connected Node | MAC Address | IP Address | Subnet Mask | Frequency | Status |
+----------------+-------------------+-------------+---------------+--------------+---------+
| router_1 | 1a:46:f6:cb:8c:15 | 192.168.1.1 | 255.255.255.0 | WiFi 2.4 GHz | Enabled |
| router_2 | 7a:9f:d8:2b:4b:90 | 192.168.1.2 | 255.255.255.0 | WiFi 2.4 GHz | Enabled |
+----------------+-------------------+-------------+---------------+--------------+---------+
PASSED [100%]
Process finished with exit code 0
```
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] atte...
## Summary
This PR updates `PrimaiteGymEnv` and `PrimaiteRayMARLEnv` within `environment.py` to log reward values per step and per episode.
Corrects an import statement within `io.py` - removing the use of `src`.
Fixes an error within notebooks that saw them failing following a rename of `game_config` to `env_config`.
## Test process
- Tests all continue to pass, and notebooks now run without error. This PR does not change any functionality, just adds some logging.
- Searched for the catch-22 that would trip me up as part of this ticket. A 3 line change felt like too simple an implementation...
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2523
## Summary
Built three networks, one is the minimal network, one is a basic LAN, and another is a nice beefy multi-LAN setup with ISP and DNS along with applications, services. Documented the process when building the config files. Included the config files as example configs for use.
## Test process
Tested the shit out of the big multi-lan network.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2266
## Summary
The current implementation of check_hash() as triggered by NODE_FILE_CHECKHASH and NODE_FOLDER_CHECKHASH is incorrect. However, a correct implementation is a future task so the code is disabled and a deprecation warning has been added.
## Test process
Disabled tests that exercise check_hash() functionality. Added tests to show that deprecation warning is present.
## Checklist
- [X ] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
2299: Remove calls to corrupt.
Related work items: #2299
## Summary
Add a doc page and a notebook to go over the request manager.
## Test process
Notebook runs.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [na] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [x] written/updated **design docs** if this PR implements new functionality
- [na] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2514
## Summary
* Made It Possible™ to vary the layout and agents between episodes.
* Standardised the environments to all use `env_config` as the __init__ parameter name, previously PrimaiteGymEnv was using `game_config`
* Added a notebook that demonstrates how to use the variable episodes.
## Test process
Checked that existing pytests run. Added more tests. Checked that notebooks run.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2269, #2334, #2336, #2475, #2476
## Summary
Refactor of `DatabaseClient` and `DatabaseService` to update how connection IDs are generated. These are now provided by DatabaseService when establishing a connection.
Creation of `DatabaseClientConnection` class. This is used by `DatabaseClient` to hold a dictionary of active db connections.
## Test process
Tests have been updated to reflect the changes and all pass
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2462
## Summary
- Implementation of log levels
- log levels can be set via io_settings.log_level in the yaml config file
## Test process
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/347?_a=files&path=/tests/unit_tests/_primaite/_simulator/_system/core/test_sys_log.py
set up a test where the test checks the contents of the terminal so make sure that specific log level messages appear (or not) depending on the log level
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2470
## Summary
- Cleaning up multiple logs that say the same thing
- Added Nick's suggestion to clear log handlers before adding a handler on SysLog initialisation
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2510: cleaning up logs and add logging handler clearing to prevent duplicate logs
Related work items: #2510
## Summary
- Upgraded pydantic to version 2.7.0.
- Added ipywidgets to the dependencies (for #2300)
## Test process
N/A
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2511 - Upgraded pydantic to version 2.7.0. Added ipywidgets to the dependencies (for #2300)
Related work items: #2300, #2511
## Summary
Fixed small typo in data_manipulation_marl.yaml. Correct database key in Data-Manipulation-Customising-Red-Agent notebook.
## Test process
Successfully re-ran all notebooks in src/primaite/notebooks on Windows and Linux (WSL).
Successfully re-ran all tests in primaite/tests.
Also checked that Ransomware-Kill-Chain-E2E and UC6-E2E-Demo ran correctly in PrimAITE Sensitive repo.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2455: Fix typo in config file and notebook
Related work items: #2455
## Summary
Updates to `create-simulation_demo.ipynb` and `network_simulator_demo.ipynb` to reflect changes within repo.
- Corrected import paths
- Corrected typo in create-simulation_demo: my_swtich -> my_switch and switch.sys_log.show -> computer.sys_log.show()
- Changes to ARP implementation within nodes. Now defined as a property within HostNode and NetworkNode, allowing router.arp.show() to work as intended within the notebook.
## Test process
- Both notebooks now run without issue when ran.
- All tests pass
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2453, #2477, #2478
## Summary
A while ago we have added several notebooks to get users started training their own agents. These notebooks overlap in functionality with PrimAITE session but they are more suitable.
* removed primaite session
* removed any tests relying on primaite session (except some tests were converted into environment tests.
* removed any CLI commands that rely on `PrimaiteSession`
* Added deprecation warnings to any benchmarking code that will break now because they rely on the old Primaite 2 session. (I left the code in because when we update benchmarking to v3, this will be a useful starting point)
* added similar deprecation warnings to Session metadata writer, reader and transaction stuff, for the same reason.
* removed parts of the documentation that are no longer relevant (session, training config, policy)
* went through all existing yaml config files and removed training options (as they were for session only)
## Test process
Checked that existing pytests all pass, and updated some pytests to use environment instead of session.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2374
- create_simulation_demo and network_simulator_demo notebooks have been updated with correct import paths to reflect refactoring within condebase.
- Corrected typo within create-simulation_demo: my_swtich -> my_switch
- updates to ARP implementation. This is now a property in HostNode and NetworkNode, meaning router.arp.show() now works in network_simulator_demo notebook as intended.
## Summary
Required to complete #2448
DB Client will store last query response - Data Fusion Service will use this to know the difference between no response and invalid response
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2448: store last query response for db client
Related work items: #2448
instead of UUID for link primary key in describe state, we are using something more like
router_1:eth-3<->switch_1:eth-8
**all configs need to change the observation space link schema as a result of this change**
It looks like there are a lot of changed files, but it's mostly just removing the `game` parameter from observations and removing 'ref' from config files.
:)
also we no longer need to specify `ref` for nodes, services, or applications. (**but existing configs will not break based on this change!**)
Related work items: #2450
Tiny small bugfix.
make sure IO settings are read before the game config in the environments. This is so that SIM_OUTPUT global variable is set before constructing game objects.
Related work items: #2446
## Summary
The file being backed up by the database service does not restore the last visible health status of the db file before being restored
## Test process
- Tests that the visible health status is carried forward when the file is corrupted and then restored
- Tests that the visible health status is carried forward when the file is corrupted, deleted and then restored
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2437: fix the visible health status not being carried on after restoring backup file
Related work items: #2437
## Summary
* Remove the usecase-specific and agent-specific observation classes, replacing with a more flexible system
* Add configuration schemas to every observation class
* Add router, firewall, port, and application observation
* Re-shape the dict structure of observations to make it adhere to CAOS 0.8
* Change existing configs to use the new structure
* make host observation separate
## Test process
existing and new unit tests as well as ad hoc notebooks
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2417
## Summary
Added ACL addrule and removerule for routers and firewalls
## Test process
New test created to cover all possibilities
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2402, #2415
## Summary
Add application install and remove (uninstall) actions
## Test process
Both actions are tested in the same (new) test
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2405
## Summary
Add ability to parse printers and wireless routers from yaml config.
## Test process
Existing unit tests pass. Added a printer to one of the test yamls. Adding a wireless router as well now.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2418
## Summary
Added actions for application close, scan and fix
Renamed software patch to software fix
Fixed and enabled `test_node_service_scan_integration`
## Test process
All tests passed locally
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2404
## Summary
Added actions to enable/disable ports for routers/firewalls
Added tests for routers and added ticket in the backlog to test on firewalls (it's not possible to test at the moment because the game_and_agent fixture cannot build from a yaml file)
Improved the notebook for training sb3 agents on UC2 to include validated value for learning rate and fix for loading sb3 PPO from IY as well as code to evaluate agents
## Test process
Run new tests locally
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2403
## Summary
the step label for actions was off by one from the step label in the step metadata log. Also the last episode was not outputting an action log because the reset method wasn't being called (there's a close method for this instead).
## Test process
Notebooks, pytests
## Checklist
- [~] PR is linked to a **work item**
- [~] **acceptance criteria** of linked ticket are met
- [y] performed **self-review** of the code
- [n] written **tests** for any new functionality added with this PR
- [n] updated the **documentation** if this PR changes or adds functionality
- [n] written/updated **design docs** if this PR implements new functionality
- [n] updated the **change log**
- [y] ran **pre-commit** checks for code style
- [y] attended to any **TO-DOs** left in the code
Related work items: #2230
## Summary
Added a page to explain how to use the Jupyter notebooks via jupyter command and VSCode
Also added Nick's suggestion to fix#2226
Going to be honest - not my finest pull request
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2369: commiting work done so far
Related work items: #2369
## Summary
Updated CHANGELOG.md, lightly edited and corrected.
## Test process
N/A
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
2384: Updates for 3.0.0b7 release.
Related work items: #2384
## Summary
Ensure that the logging options are being read correctly from the config. Makes logs actually optional.
Also temporarily disable checkhash and replace it with file scan because checkhash is buggy.
## Test process
By inspection
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Fix some stuff
Related work items: #2382
## Summary
* add ability for agents to share rewards - the calculated reward value for one agent can be used as a component of another agent's reward.
* Update UC2 configs to use the reward sharing functionality - green agents have a reward based on their two actions. Blue agent reward adds green agent rewards to itself.
* Add agent action history - This allows the rewards to react to agent actions.
* Make action logging use the new agent history.
* Make the webpage and database reward components treat failed requests the same as if the webpage was unavailable / database was unreachable.
* reorder the PrimaiteGame step to be the same as the Gymnasium env step
* update uc2 notebook accordingly.
## Test process
Tested with ad-hoc notebooks and debugging tool to verify correct data is being used. Tested notebooks run properly and pytests pass. Added unit and integration tests.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2372
## Summary
### **work related to v0.7 CAOS**
- Split observations.py into:
- agent_observations.py
- file_system_observations.py
- node_observations.py
- nic_observations.py
- observation_manager.py
- observations.py
- software_observations.py
- added tests to ensure that the observations align with [QTSL-820-2450 - ARCD Track 2 Common Action Observation Space Definition v0.7](https://nscuk.sharepoint.com/❌/r/sites/SSE32ARCDIDT/Shared%20Documents/General/ARCD/Architecture%20%26%20Design%20Documentation/Common/CAOS%20Related%20Documents/QTSL-820-2450%20-%20ARCD%20Track%202%20Common%20Action%20Observation%20Space%20Definition%20v0.7.xlsx?d=wee5713d8640b4b5bb3cb5624936e417e&csf=1&web=1&e=lByVQ5)
### preparation for v0.8 CAOS
WILL NOT AFFECT OBSERVATION SPACE FOR V0.7
**DO NOT PANIC**
these features are needed for v0.8
- integrated `num_access` to file (not used yet in file observations)
- integrated `num_file_deletions` and `num_file_creations` to file_system (not used yet in node observations)
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2350
this PR is a pre-requisite to the work im doing today where green agents actions that fail to reach their target still incur a negative reward.
## Summary
- Requests now return a response.
- Added the request response to the agent logging and info output of env step.
- Changed all request types in the simulator to return a response
- Added a new 'validator' that allows nodes to execute actions only if the node is on (this check happens at the request level rather than in every single function)
- Fixed NMNE - made nic observation responsible for converting total NMNE this episode to NMNE last step because apply_timestep is applied after actions but before observations in the step method.
- Fixed arcd_uc2_network to configure the db clients and web browsers correctly
- Added tests for request responses
## Test process
New tests, existing tests pass.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2372
## Summary
Change the default rewards for the data manipulation configs
Also I renamed the config files to make their names more descriptive.
## Test process
Pytests and all notebooks run without fail.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2365
## Summary
The NMNE counts MNEs since last step rather than since last episode.
## Test process
Updated unit tests to check for the new behaviour and added new test.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
There's no update necessary to the docs or change log because it NMNE is already documented, and the text is still correct given this minor change.
Related work items: #2348
## Summary
Added a new optional capability to create a JSON log each episode with a list of action each agent took each step (including scripted, RL, and red agents).
Also I had to slightly refactor the IO system to not rely on PrimaiteSession, as it's gonna be deprecated soon. Therefore the IO module is now linked to the gym environment. Each time you init a gym environment, it creates a session directory.
## Test process
Tried the SB3, Ray SARL and Ray MARL notebooks to see that the outputs get generated.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Move IO to environments from session and add agent logging
Related work items: #2278
## Summary
just run the notebook and see if the explanation makes sense.
I also renamed some stuff to make it more user friendly
Related work items: #2343
## Summary
Expand the available actions.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2243
## Summary
* removed `GreenWebBrowsingAgent` because it was replaced by probabilistic agent
* created new 'probabilistic agent' which selects actions randomly from its action map, with configurable probabilities
* slightly refactored action manager to decouple it from `PrimaiteGame` (as a consequence, agents should be given the current timestep if their `get_action()` method is time-dependent)
* refactored `data_manipulation_bot` to use an existing db client on the host rather than inheriting from it
* added new type of SQL query to databases: `"SELECT * FROM pg_stat_activity"` to model checking connection status
* added new execution definition on the `DatabaseClient` app which just performs that new SQL query
* added reward for the green admin being able to connect to the db
* updated uc2 notebook to reflect new changes.
* updated documentation for data manipulation bot
* added new test for probabilistic agent
* added test for new reward
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2319
## Summary
Allowed the config to not have nodes, links and agents and still be parsed
## Test process
Tested with config file that doesn't have any simulation key/value pair
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2357 - Allowed the config to not have nodes, links and agents and still be parsed
Related work items: #2357
## Summary
The node-specific properties in Network class now simply use node.__class__.__name__ to check their type for filtering by type
## Test process
Tests updated to use the new property function names
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2358 - the node-specific properties in Network class now simply use node.__class__.__name__ to check their type for filtering by type. Tests updated to use the new property function names
Related work items: #2358
## Summary
Bug fix to allow firewall dmz port to be optional as well as external acl rules to be optional
## Test process
See https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/290?_a=files&path=/tests/integration_tests/configuration_file_parsing/nodes/network/test_firewall_config.py
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2356: optional dmz port + optional external acl rules
Related work items: #2356
## Summary
- Updated Sphinx 6.1.3 => 7.1.2
- Updated furo 2023.3.27 => 2024.01.29
- Added tests to check that firewall, routers and nodes are properly added via config (config parser tests)
- Added some reference points in code comments for Sphinx documentation to reference
- Created a list of System Software so it can be referenced in docs and by code
- Added default values to config within game.py (The defaults are pulled from example_config.yaml)
- Created a section for creating a session via config files:
- set up a lot of stuff so documentation is easier to maintain
- Template for things that are repeated in places
- added how to create nodes via config
- added how to install applications and services via config
- diagrams to make it easier to understand some stuff e.g. ACL rules for firewall
see https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/280?_a=files&path=/CHANGELOG.md
## Test process
- Firewall:
- Created a DMZ Network example config
- Tested the creation of Firewall
- Tested the ACL Rules of Firewall
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/280?_a=files&path=/tests/integration_tests/configuration_file_parsing/nodes/network/test_firewall_config.pyhttps://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/280?_a=files&path=/tests/integration_tests/configuration_file_parsing/nodes/network/test_router_config.py
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2257
## Summary
Instead of setting all attributes back to a snapshot, simply recreate the entire game and all agents from a cached copy of the config.
This removes the need for `set_original_state` and `reset_component_for_episode` methods on SimComponents.
## Test process
* Unit tests passing
* I've also tried adding a `__del__` method to simcomponent and agent and press env.reset() to verify that the ref count reaches 0, and nothing is secretly keeping using an old part of the simulation.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2317
## Summary
This pull request introduces new features for capturing Malicious Network Events (NMNE) within the `NetworkInterface` class and extends the functionality to the `NicObservation` class .Additionally, it updates the simulation configuration to allow customizable NMNE capturing settings.
### Changes
- `NetworkInterface` Enhancements: Added NMNE capturing capabilities to detect and log specified malicious activities.
- `NicObservation` Integration: Updated to support detailed monitoring and analysis based on NMNE capturing results.
- Simulation Configuration: Introduced nmne_config options allowing users to enable NMNE capturing and define specific keywords, enhancing the adaptability of network security measures.
### New Configuration Options
Added to simulation.yml:
``` yaml
simulation:
network:
nmne_config:
capture_nmne: true
nmne_capture_keywords:
- DELETE
```
Tests
Documentation
Updated README and related documentation to guide users on how to utilize the new NMNE capturing features and configure them in their simulations.
## Test process
- **NMNE Capture Testing**: Implemented tests using the UC2 network setup, where DELETE SQL queries are initiated by the database client residing on the web server and targeted towards the database service on the database server. Post-query, the network interface cards (NICs) on both servers are examined to verify accurate counting and logging of NMNE (Malicious Network Events) as expected per configuration.
- **NicObservation Testing**: Introduced additional tests to ensure proper integration of the `NicObservation `class, focusing on its ability to accurately observe and report NMNE occurrences.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [X] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
#2238
Related work items: #2238
- Enhance NicObservation for detailed NMNE event monitoring.
- Add nmne_config options to simulation settings for customizable NMNE capturing.
- Update documentation and tests for new NMNE features and simulation config.
## Summary
- Made the data manipulation red agent be able to choose between the two clients to start operating on
- changed the attacker name in the config to 'data_manipulation_attacker' to because it is no longer tied to any client
- Updated the documentation notebook accordingly.
- Fixed a bug where the database client made a new connection every time it sent a SQL query (it tries to reuse its most recent one instead)
- Fixed a bug where link loads were not being cleared between episodes (?)
**warning** - the green agents are not working properly after reset right now, but I'm gonna fix this in the next ticket where I refactor episode reset.
## Test process
- unit tests pass
- UC2 notebook passes with both clients. (currently this doesn't work after an episode reset, but the very next thing I'm gonna work on is refactoring the reset, so I don't want to waste time fixing this.)
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [n] attended to any **TO-DOs** left in the code
Related work items: #2232
## Summary
- Added ability to set DoSBot in nodes via config file
- Fixed missing configuration items in other services/applications
- Created a variable which contains the list of applications and services
- Moved `DatabaseClient` from list of services to list of applications
## Test process
Created a configuration file where a node has all services and applications installed, this is then used by an integration test which loads the configuration file. The test checks to make sure that the configuration file is correctly read and the Service and Application objects are properly created
## Checklist
- [X] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2258
## Summary
Add support for SQL INSERT query in database_service.py.
## Test process
Updated test_database_on_node.py to test for database INSERTions.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2306
## Description:
This pull request introduces the Firewall class and extends the ACLRule functionality within PrimAITE to provide comprehensive network traffic management and security capabilities. These enhancements enable detailed control over data flow through network simulations, mimicking real-world firewall operations and ACL configurations. The updates focus on the addition of a Firewall node that extends the Router class functionalities and the enhancement of ACLRule to support IP ranges through wildcard masking, thus offering granular traffic filtering based on IP addresses, protocols, ports, and more.
## Key Features:
**Firewall Class:** A new class that extends the Router class, incorporating firewall-specific logic for inspecting, directing, and filtering traffic between the internal, external, and DMZ (De-Militarized Zone) network interfaces. The Firewall class supports configuring network interfaces and applying Access Control Lists (ACLs) for inbound and outbound traffic control.
**Enhanced ACLRule:** The ACLRule class has been updated to support IP ranges using wildcard masking. This allows for more flexible rule definitions, enabling users to specify broad network ranges or individual IP addresses in ACL rules.
**Comprehensive ACL Configuration:** Six distinct ACLs (internal inbound, internal outbound, DMZ inbound, DMZ outbound, external inbound, and external outbound) provide meticulous control over traffic flow, ensuring robust network security. Examples included in the documentation illustrate how to configure ACLs for common scenarios, such as blocking external threats, permitting specific services, and restricting access to sensitive internal resources.
**Intuitive Interface and ACL Management:** Simplified methods for configuring firewall interfaces and ACL rules enhance usability. The Firewall class offers intuitive functions for rule management, including adding, removing, and listing ACL rules.
**Detailed Documentation and Examples:** Accompanying the code updates, comprehensive documentation and example configurations are provided, detailing the use and configuration of the Firewall node and ACL rules within PrimAITE simulations.
## Impact:
The introduction of the Firewall class and the enhancement of ACLRule significantly broaden PrimAITE's capabilities for simulating realistic network security scenarios. Users can now accurately model the behavior of firewalls in their network simulations, applying complex ACLs to control traffic flow and enforce security policies. This update enables more detailed network security analyses, teaching, and experimentation within the PrimAITE environment.
## Test process
Extensive unit tests have been added to cover the new functionality, ensuring reliability and correctness. Tests include scenarios for firewall configuration, ACL rule application, traffic filtering based on various criteria, and interaction between different network zones.
## Checklist
- [X] PR is linked to ...
## Summary
Replaced references to TCP with UDP in NTP client and server code. Updated docs.
## Test process
Re-ran and passed existing tests.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
2297: Convert NTP Client and Server to UDP
Related work items: #2297
This commit introduces the AirSpace and WirelessRouter classes, expanding the PrimAITE's capabilities to simulate wireless networking environments. The AirSpace class manages wireless communications, ensuring seamless transmission across different frequencies. Meanwhile, the WirelessRouter class integrates both wired and wireless networking functionalities.
## Summary
This pull request encompasses a series of significant refactoring and enhancements aimed at improving the network simulation framework's architecture and functionality. Central to these changes is the introduction of ARP and ICMP as standalone services, the creation of a structured hierarchy for network interfaces, and a comprehensive overhaul of the testing suite to align with these new developments.
### Key Changes:
ARP and ICMP as Services: Transitioned ARP into a dedicated service, laying the groundwork for more sophisticated network interaction simulations. This shift involved substantial refactoring but has resulted in the successful integration of ARP requests within the network service architecture. Following this, ICMP was also encapsulated as a service, utilizing the session manager for packet transmission, thereby enhancing modularity and interaction within the network.
Network Interface Hierarchy: Introduced a hierarchy for network interfaces, differentiating between wired (NIC, SwitchPort) and wireless (WirelessNIC, WirelessAccessPoint) interfaces. This structure is further enriched with the Layer3Interface abstract base class, facilitating IP-based communications across both wired and wireless mediums.
PCAPs (Packet Capture) are now logged separately for inbound and outbound frames.
Test Suite Overhaul: Undertook a significant refactor of the testing suite, shifting to utilize the newly introduced Node subclasses (Computer, Server, Router, Switch) and the Network() class for node management and connection setup. This effort ensures that tests more accurately reflect the intended usage patterns and configurations within the simulation framework.
IPV4Address Validation and Conversion: Added a new IPV4Address type with pre-validation and auto-conversion capabilities, streamlining the handling of IPv4 addresses throughout the framework.
### Commit Highlights:
1. Commenced by integrating ARP as a service, facing initial challenges but achieving a functional ARP request capability as a milestone (Initial crack at getting ARP into a Service).
1. Progressed to fully integrate ARP service and link it with ICMP operations, marking a significant advancement in service-based network interactions (Lots more progress).
1. Began the process of encapsulating ICMP within the service model, necessitating further adjustments and test fixes (Initial work has been done on moving ICMP into services).
1. Completed the ICMP service integration, enhancing PCAP logging for inbound and outbound frames, and began addressing test suite discrepancies (ICMP now working as a service).
1. Implemented a broad refactor of the base network model to introduce a clear network interface hierarchy and started troubleshooting routing tests affected by ARP integration issues (Big refactor of base).
### Conclusion:
These changes collectively represent a leap forward in the framework's architecture, laying a robust foundation for future enhancements and ...
## Summary
- added a second green agent on client 1
- added browser history
- added a reward component based on the most recent return code in browser history
- modified the UC2 notebook to adhere to new reward.
- (also there were some issues in example_config from a previous merge that I failed to notice prior)
## Test process
New unit tests. Ran uc2 notebook to check that it produces results aligning with what is described in the markdown cells.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Add second green agent and make rewards based on webbrowser
Related work items: #2247
## Summary
Make actions work with object names instead of UUIDs. This makes it possible to define action spaces which can act on network elements that don't exist yet (as long as you can anticipate what they will be called).
## Test process
Many new tests. Old tests pass. Notebooks run.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [no time] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2137
## Summary
Hotfixes from 3.0.0b4, b5, b6. These have all gone thru the PR process already we just need to sync dev back.
## Test process
Merge conflicts resolved and all automated tests pass.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [~] updated the **documentation** if this PR changes or adds functionality
- [~] written/updated **design docs** if this PR implements new functionality
- [~] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2161, #2173, #2174, #2175, #2176, #2179, #2208, #2218, #2219, #2220
Please run some of these changes locally. Read the notebook, check that it makes sense, and run the code cells to see if they produce the result you expect.
## Summary
Apologies that all these fixes are part of 1 massive PR instead of individual PRs. I thought it was going to be a quick job and it spiralled out of control.
Changes:
- Fixed a bug where ACL rules were not resetting on episode reset.
- Fixed a bug where blue agent's ACL actions were being applied against the wrong IP addresses
- Fixed a bug where deleted files and folders did not reset correctly on episode reset.
- Fixed a bug where service health status was using the actual health state instead of the visible health state
- Fixed a bug where the database file health status was using the incorrect value for negative rewards
- Fixed a bug preventing file actions from reaching their intended file
- Made database patch correctly take 2 timesteps instead of being immediate
- Made database patch only possible when the software is compromised or good, it's no longer possible when the software is OFF or RESETTING
- Temporarily disable the blue agent file delete action due to crashes. This issue is resolved in another branch that will be merged into dev soon.
- Fix a bug where ACLs were not showing up correctly in the observation space.
- Added a recap of agent actions to the `info` output of `step()`
- Added a notebook which explains UC2, demonstrates the attack, and shows off blue agent's action space, observation space, and reward function.
## Test process
New notebook verifies end-to-end UC2 functionality.
## Checklist
- [y] PR is linked to a **work item**
- [y] **acceptance criteria** of linked ticket are met
- [y] performed **self-review** of the code
- [~] written **tests** for any new functionality added with this PR
- [y] updated the **documentation** if this PR changes or adds functionality
- [n] written/updated **design docs** if this PR implements new functionality
- [y] updated the **change log**
- [y] ran **pre-commit** checks for code style
- [y] attended to any **TO-DOs** left in the code
Related work items: #2208, #2218, #2219, #2220
## Summary
**Changed:**
- Copying a file via FTP also copies its health status
- The database automatically attempts to make a backup on step 1
- make the db file a property that is fetched by name from the file system instead of a handle to a file (bruh)
- fixed ftp server re-sending requests back to the client
- fix issue where links with >100% bandwidth cause the observation space to crash
- fix issue where starting a node didn't start services. (not sure how that one passed tests previously)
**To align with Yak:**
- database service removed from uc2 observation space
- sql attack affects the file health status instead of the service
- when the web server fails to fetch data, it goes into compromised state until a successful data fetch
## Test process
Notebooks
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2176
## Fixed:
- data manipulation red agent now considers episode reset when calculating next action time
- Moved attack logic out of data manipulation bot `run` method into dedicated `attack` method, because `run` is triggered by episode reset logic. This means the attack no longer always happens at step 1 of every episode.
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [na] updated the **documentation** if this PR changes or adds functionality
- [na] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2173
## Summary
Removed the changing of health_state_actual from the actions - only few places where the health_state_actual is changed:
- compromised in specific scripted events
- set to good when started (if the state is still at UNUSED
- set to good after patching
## Test process
unit tests
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/254?_a=files&path=/tests/unit_tests/_primaite/_simulator/_system/_services/test_services.py
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2151: remove changing of health_state_actual in actions and tests
Related work items: #2151, #2166
## Summary
Same as other PR but this time we are merging into DEV.
The Proxy agent has a new config option, `flatten_obs`. If true, we use gymnasium flatten.
## Test process
Unit tests and inspection.
Related work items: #2143, #2154, #2161
## Summary
- Integrated the RouteTable into the Routers frame processing.
- Frames are now dropped when their TTL reaches 0
## Test process
Added five tests that check routing passes and fails with correct/incorrect route tables.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2139 - Implemented routing
Related work items: #2139
## Summary
Simple change that gives the user an option to turn on/off observation space flattening.
## Test process
Confirmed that if the new setting is set to 'false', SB3 complains about composite spaces, but RL agents notebook works fine.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Make flattening observation spaces optional.
Related work items: #2161
## Summary
Very straightforward change. Just added some config parameters to make pcap and sys logs optional. These options default to false.
## Test process
Verified that both options produce the desired result by running a primaite session with logs enabled and disabled in the config. Unit tests still pass.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2143, #2154
## Summary
Replaces Action ID 13 in UC2 with SERVICE.PATCH.
Fixes issue where apply_timestep was not happening at all
Fixes issue where file actions were not correctly being forwarded
## Test process
All pytests passing including a new one for service patch.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2143
## Summary
- Replaces Action ID 13 in UC2 with SERVICE.PATCH.
- Fixes issue where `apply_timestep` was not happening at all
- Fixes issue where file actions were not correctly being forwarded
## Test process
Unit tests passing
Running primaite session works without errors
Ran primaite session on UC2 in debug mode and inspected that correct changes are being reflected after actions are applied.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2143
## Summary
Tiny change to change the names of the keys in `software.describe_state()`
Also fixed the observation to use the visible health state instead of the actual health state (and therefore the blue agent will actually have to scan to learn the health state)
## Test process
Unit tests pass
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Change software describe state keys
Related work items: #2160
## Summary
- Refactor Simulator state to use service/application name instead of UUID, and node hostname instead of UUID.
- Refactor observations to read the hostname/name instead of UUID.
- Refactor rewards as well.
- Refactor configs to specify name instead of reference that will be translated to UUID.
## Test process
Existing unit tests pass. Inspected the printout from running 'describe_state' on arcd_uc2_network' to verify that names are used to report state.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [na] written **tests** for any new functionality added with this PR
- [na] updated the **documentation** if this PR changes or adds functionality
- [x] written/updated **design docs** if this PR implements new functionality
- [na] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #2131
## Summary
The NTP Server and Client are created as two separate classes NTPServer and NTPClient which define the methods used to send and receive time data. A set of classes used in the sending and receiving of requests and data is in ntp.py. A single file, test_ntp_client_server.py is used to run the unit tests.
The changes have no impact on other parts of the codebase.
## Test process
Created simple two node network representing NTP server and client. Created NTP server and client objects and client requests and receives date/time from server.
## Checklist
- [Y] PR is linked to a **work item**
- [Y] **acceptance criteria** of linked ticket are met
- [Y] performed **self-review** of the code
- [Y] written **tests** for any new functionality added with this PR
- [Y] updated the **documentation** if this PR changes or adds functionality
- [N] written/updated **design docs** if this PR implements new functionality
- [Y] updated the **change log**
- [Y] ran **pre-commit** checks for code style
- [N] attended to any **TO-DOs** left in the code
Related work items: #2041, #2042
## Summary
- Moved DataManipulationBot into red applications - these are applications, not services
- moved the connection handling from Service base class to the IOSoftware base class
- Applications and Services can track the connections they make
- increased default max sessions to 100
- made sure the services/applications that are dependent on connections use the IOSoftware connections
- DoSBot follows some sort of kill chain, although at the moment it just:
- runs a port scan with a 10% success chance (by default)
- runs a DoS attack that fills a service's max sessions
## Test process
unit test in https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/234?path=/tests/unit_tests/_primaite/_simulator/_system/_applications/_red_applications/test_dos_bot.py&_a=files
integration test in https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/234?path=/tests/integration_tests/system/red_applications/test_dos_bot_and_server.py&_a=files
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2059
## Summary
- Added step metadata json file dumps to the environments. Fixed serialization issues in the Switch and ACLRule classes.
## Test process
Nothing outside of a manual inspection for now.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2085
## Summary
*Replace this text with an explanation of what the changes are and how you implemented them. Can this impact any other parts of the codebase that we should keep in mind?*
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Add docpage for config
Related work items: #2088
## Summary
Fix ray episode issues. Allow ray to manage its environment fully - this fixes the perma-zero reward.
## Test process
Running notebooks and primaite sessions.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #2095
## Summary
Added a fail condition for coverage
## Test process
n/a
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2084: add coverage fail condition
Related work items: #2084
## Summary
Added tests and integrating code coverage checks - current target set to 80% of code to be covered by tests
## Test process
The pull request is literally to add more tests (lol)
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
#2084: beginning the introduction of code coverage + adding tests to try to meet the 80% code coverage target
Related work items: #2084
## Summary
After initial setup, get sim components to save their state. Then, during episode reset, set attributes to original values.
## Test process
Test script that checks for web client ability to resolve requests after a reset. Formal tests don't exist.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1859, #2087
## Summary
This is @<Jake Walker> 's and @<Christopher McCarthy> 's PR.
- The red agent now performs attacks in stages.
- There is now a random probability of each stage being successfully run.
- There are start settings for the red agent which set the start time, frequency and variance for both.
## Test process
Additional unit tests have been added to test new functionality.
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1859
## Summary
*Replace this text with an explanation of what the changes are and how you implemented them. Can this impact any other parts of the codebase that we should keep in mind?*
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [Y] PR is linked to a **work item**
- [Y] **acceptance criteria** of linked ticket are met
- [Y ] performed **self-review** of the code
- [N] written **tests** for any new functionality added with this PR
- [Y] updated the **documentation** if this PR changes or adds functionality
- [N] written/updated **design docs** if this PR implements new functionality
- [N] updated the **change log**
- [Y] ran **pre-commit** checks for code style
- [N] attended to any **TO-DOs** left in the code
Related work items: #2068
## Summary
- Added a check for services so that they should not do anything unless the node it is installed in is turned on
## Test process
- Added tests everywhere
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #2064
## Summary
- PrimaiteSession class was separated into 'game' and 'session' classes. Game manages the interfacing of agents and the simulator. Session manages the environment, IO, and RL algorithms, as well as the game.
- Add ray single and multi agent support
- Add environments that can be interacted with directly so that users who want to manually configure RL policies can do so.
- Add notebooks demonstrating manual environment interfacing.
## Test process
Unit tests added, all pass. Example notebooks run to demonstrate compatibility with SB3 and Ray.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code

Related work items: #1970, #1971
## Summary
Implemented the Simulation reset functionality by doing a deepcopy of the Simulation object inside the PrimaiteSession upon instantiation and assigning it to a `_simulation_initial_state` variable. Then when reset called, the sessions `simulation` variable is assigned the value of the `_simulation_initial_state` variable.
## Test process
Added a test that uninstalls a service before performing a reset then checks that the service reappears.
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
#2034 - Implemented the Simulation reset functionality by doing a deepcopy of the Simulation object inside the PrimaiteSession upon instantiation. Added a test that uninstalls a service before performing a reset then checks that the service reappears.
Related work items: #2034
## Summary
Remove SQLLite and real sql queries and replace them with `SELECT` and `DELETE` queries that interact with the node's file system and service operating status.
## Test process
Existing unit tests pass after logic was changed.
## Checklist
- [x] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #1971
## Summary
Remove gate and integrate SB3 agent natively.
This includes:
- agent saving
- checkpoints
- session output directory
- simulation output (such as syslogs) are now in the session output directory
- agent loading
- training progress bar (with `enlighten`)
## Test process
End to end tests that verify that a session is being created correctly with a network
They also check the outputs exist.
## Checklist
- [y] PR is linked to a **work item**
- [upcoming PR] **acceptance criteria** of linked ticket are met
- [y] performed **self-review** of the code
- [loading not tested but need to move onto Ray now] written **tests** for any new functionality added with this PR
- [n] updated the **documentation** if this PR changes or adds functionality
- [n] written/updated **design docs** if this PR implements new functionality
- [n] updated the **change log**
- [y] ran **pre-commit** checks for code style
- [n] attended to any **TO-DOs** left in the code
Related work items: #1971
## Summary
- Implement the folder/file restore
- Split the FileSystem and its classes into their own files so that it is easier to maintain.
- Reimplement how deleted folders and files are stored in a deleted list, so that it is possible to restore later
## Test process
See https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/206?_a=files&path=/tests/unit_tests/_primaite/_simulator/_file_system
- Unit tests written to make sure methods work as intended
- Integration tests with the apply_request method which tests that the agents can send the request to the simulation to affect it
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1962
## Summary
- Remove v2-specific code, documentation, and tests
- Reconnect CLI, to new v3 classes and functions
- Add Game layer
- Minor changes to simulation layer to ensure compatibility with game layer actions and observations
### Game layer
- Add a primaite session, which is the main entry point to running a session. This encompasses agents, the simulation, and a connection with GATE.
- Add an agent interface, random agents, and RL agents.
- Add new observation space management
- Add new action space management
- Add new reward function management
## Test process
Ran primaite session without crash. Majority of integration and unit tests have not been written yet. (sorry)
I know it's not ideal to merge in this not-tested-state, but it doesn't make sense to continue diverging `dev` and `dev-game-layer`.
Instead of reviewing the diff, I would recommend downloading this code and getting familiarised with the new `game` module by reading the code and playing around with it.
Related work items: #1622, #1759, #1760, #1761, #1764, #1765, #1766, #1767, #1768, #1879, #1924, #1986, #1987, #1988, #1989, #1990, #1998
## Summary
Installing GATE before running the primaite setup command so that the pipeline passes
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
#2025: added GATE installation as part of pipeline
Related work items: #2025
## Summary
Implementing the ability for the simulation to scan all node components as well as the ability for the red agent to reveal the node and its components.
Implementing the ability for the simulation to reset a node
## Test process
Unit tests added
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1961
## Summary
Make PrimAITE work with the new:
- configs
- CLI commands
## Test process
I ran primaite setup and primaite session to check that they work
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1987, #1998
* STILL IN PROGRESS *
## Summary
Delete old documentation, write some more up-to-date documentation.
## Test process
## Checklist
- [ ] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [ ] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [ ] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [ ] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Updates to documentation
Related work items: #1988, #1990
## Summary
* Delete many files which are not used with the new V3 approach. Including all the previous simulation files, as well as the old config, old session, etc.
* Delete tests for the removed functionality
* Note: this PR can only be merged after !195
## Test process
This PR Changes our Unit Test suite to only keep tests related to V3 code. All tests pass as of my recent attempt.
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [~] written **tests** for any new functionality added with this PR
- [~] updated the **documentation** if this PR changes or adds functionality
- [n] written/updated **design docs** if this PR implements new functionality
- [x] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [n] attended to any **TO-DOs** left in the code
Related work items: #1989, #1986
## Summary
* add a new module `game` to PrimAITE
* this includes a new PrimaiteSession which creates a simulation, and multiple agents, and talks to GATE
* agent interface
* agent actions to work with Simulator requests
* agent observations that work with Simulator State
* agent rewards also with Simulator state
**note** that this branch is currently still in a broken state. Still need to do things like updating readme, install instructions, refactoring some poorly designed classes, and removing legacy code. These will be done in subsequent PRs to avoid making this PR even bigger than it needs to be. Still, please review this to familiarise yourself.
## Test process
Some unit tests exist but their coverage will be expanded.
I performed some test runs with to train a SB3 agent in GATE with a primaite simulation.
## Checklist
- [y] PR is linked to a **work item**
- [y] **acceptance criteria** of linked ticket are met
- [~] performed **self-review** of the code
- [n] written **tests** for any new functionality added with this PR
- [~] updated the **documentation** if this PR changes or adds functionality
- [~] written/updated **design docs** if this PR implements new functionality
- [~] updated the **change log**
- [y] ran **pre-commit** checks for code style
- [n] attended to any **TO-DOs** left in the code
Related work items: #1622, #1759, #1760, #1761, #1764, #1765, #1766, #1767, #1768, #1879, #1924
## Summary
Finishes (?) the action system.
- Defines all UC2 common action space actions on SimComponents
- Links up SimComponents and their children, so actions can be passed from parent to child
- Add a function for enumerating all possible actions that exist on a SimComponent. (will be used for generating action space)
- add documentation for action management
note: I know that the way I approached this is a bit convoluted but It's just what I came up with to allow the actions to be as flexible and modular as the SimComponents themselves.
## Test process
Tested that the functionality works in scratch notebook. But also in the process of adding unit/integration tests now.
## Checklist
- [x] PR is linked to a **work item**
- [ ] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [ ] written **tests** for any new functionality added with this PR
- [x] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [ ] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1923
## Summary
Added a WebServer service and a Web Browser (client) so that the simulation can emulate HTTP requests across the network via HTTPPacket transfer
## Test process
Written an integration test that tests Web Server and Web Browser sending and returning requests
## Checklist
- [X] PR is linked to a **work item**
- [X] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [X] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [X] ran **pre-commit** checks for code style
- [X] attended to any **TO-DOs** left in the code
Related work items: #1752, #1816, #1866, #1916, #1943
## Summary
- Used FTP changes to allow the database service to create a copy of the database.db file in the backup server
- Used FTP changes to allow the database service to restore the database.db file from a copy made in the backup server
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [X] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [x] attended to any **TO-DOs** left in the code
Related work items: #1752, #1796, #1816, #1866, #1916
- changelog added
- added documentation + example of using web server + web browser
- extended web server so that it also accepts ip addresses
- web server can differentiate between a normal page request and one that propagates into a DB request
- rename WebServerService -> WebServer
## Summary
Initial implementation of an FTP Client/Server service used to emulate a transfer of files across nodes
## Test process
Added an integration and unit test
## Checklist
- [x] PR is linked to a **work item**
- [x] **acceptance criteria** of linked ticket are met
- [x] performed **self-review** of the code
- [x] written **tests** for any new functionality added with this PR
- [X] updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
- [X] updated the **change log**
- [x] ran **pre-commit** checks for code style
- [ ] attended to any **TO-DOs** left in the code
Related work items: #1752, #1816, #1916
## Summary
*Replace this text with an explanation of what the changes are and how you implemented them. Can this impact any other parts of the codebase that we should keep in mind?*
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [ ] This PR is linked to a **work item**
- [ ] I have performed **self-review** of the code
- [ ] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [ ] I have update the **change log**
- [ ] I have run **pre-commit** checks for code style
Updated pull_request_template.md
Related work items: #1866
Rename attributes like connected_link and connected_node to start with
an underscore.
This will prevent circular dependency and stack recursion depth error.
## Summary
Carrying on where Sunil left the task. Added more functionality to the DNS.
- DNS Server can keep a list of domain names that the DNS Client can request
- DNS Client has a cache of domain names that are valid from the DNS Server
## Test process
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/177?_a=files&path=/tests/unit_tests/_primaite/_simulator/_system/_services/test_dns.py
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [X] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [X] I have update the **change log**
- [x] I have run **pre-commit** checks for code style
Related work items: #1752
## Summary
This pull request focuses on implementing key functionalities needed for network frame processing and database interactions. The primary changes are:
1. **Internal Frame Processing:** The logic has been implemented in various components like `NIC`, `Node`, `SessionManager`, and `SoftwareManager`. These changes enable the system to process incoming and outgoing network frames in a structured manner.
2. **Database Service and Client:** The `DatabaseService` simulates a SQL database server, while the `DatabaseClient` provides a client interface for connecting to this service. These functionalities have been built and integrated into the existing architecture.
3. **Networking and Communication:** Tests have been added to confirm that database queries can be sent over the network, demonstrating end-to-end functionality.
## Commits
- #1816 Simplified a bunch of stuff in the file system in prep for services and applications. Started adding the database logic. Waiting for the software manager/session manager work from another tick. Merge branch 'dev' into feature/1816_Database-Service-(Network-and-User-Interaction)
- #1816 Added the final pieces of the puzzle to get data up from NIC → session manager → software manager → service.
- #1816 DatabaseService now uses the send function when responding.
- #1816 Added database client. Installed the database client on the Web Server node in the UC2 network. Updated the integration test to query the DB server using the DB client.
- #1816 Added full documentation on the database client/server, and the internal frame processing process
- #1816 Fixed tests. Used node and link added number (id) in observation space.
## Test process
For testing these functionalities, the following steps were taken:
1. **Unit Tests:** Tests have been written to confirm that database queries can be sent over the network successfully.
2. **Integration Tests:** Manually tested the frame processing flow from NIC to Service/Application, ensuring the functionality behaves as expected.
3. **Database Queries** Executed sample SQL queries using the `DatabaseClient` to make sure it interacts correctly with the `DatabaseService`.
## Checklist
- [ ] This PR is linked to a **work item**
- [ ] I have performed **self-review** of the code
- [ ] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [ ] I have update the **change log**
- [ ] I have run **pre-commit** checks for code style
Related work items: #1816
## Summary
Implementation of the Data Manipulation Bot. This service sends a SQL query payload to the database server (or a given machine IP and port)
## Test process
Added a test
https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/175?_a=files&path=/tests/unit_tests/_primaite/_simulator/_system/_services/_red_services/test_data_manipulator_service.py
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [X] I have update the **change log**
- [x] I have run **pre-commit** checks for code style
Related work items: #1814
## Summary
- add a database service
- change how `SimComponent` adds actions to allow inheritance of actions
- add service-based actions, like start, stop, pause, and compromise
## Test process
New test cases were added.
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [ ] I have update the **change log**
- [x] I have run **pre-commit** checks for code style
Related work items: #1801
**_*Disclaimer, I used AI to write this PR description for me, you know, for efficiency._**
## Summary
In this pull request, we've made several key enhancements and fixes to improve the routing and network simulation functionalities of our codebase. At the heart of this PR is the introduction of a `Router` class, complete with `ACLRule` and `RouteTableEntry` classes to facilitate easier management of routes and permissions. We've also fixed a lingering issue with the `.ping` functionality, ensuring that it properly checks for replies before returning a boolean value.
To make our `Router` class more inspectable, `.show()` methods have been added which can output information in both plain text and markdown formats. Additionally, we've removed the `gateway` field from the `NIC` class and relocated it to the `Node` class. This move allows each `Node` to have a single default gateway. To further refine the system, we've added `Computer` and `Server` classes, and updated our restructured text formatted docstrings and documentation. Finally, a UC2 network has been added.
Changes have been fully tested to ensure that the existing functionalities remain intact, and new unit tests have been added to verify routing between different subnets. The code has been synced with the dev branch.
## Test process
We've added new unit tests and integration tests to check the routing capabilities when a router is placed between different subnets. These tests specifically focus on the ping functionality to verify that it works as expected after the changes. Existing tests were also run to make sure no existing functionality was broken.
## Checklist
- [X] This PR is linked to a **work item**
- [X] I have performed **self-review** of the code
- [X] I have written **tests** for any new functionality added with this PR
- [X] I have updated the **documentation** if this PR changes or adds functionality
- [X] I have written/updated **design docs** if this PR implements new functionality
- [ ] I have update the **change log**
- [X] I have run **pre-commit** checks for code style
Related work items: #1800
- Added more switch tests.
- Updated ACL tests to use router acl.
- Updated more docs.
- Moved the Jupyter notebooks to _package_data and fixed up the setup to move all notebooks to ~/primaite/notebooks/example_notebooks.
## Summary
- Add public API for adding, removing, connecting and disconnecting nodes in the network.
- Introduce parent of simcomponent to keep track of parent as per this diagram 
- Update tutorial notebook with new way of doing things.
## Test process
Unit and integration tests written and passing.
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [x] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [ ] I have update the **change log**
- [x] I have run **pre-commit** checks for code style
Related work items: #1798
- Added .show() methods to new router classes to enable inspection of the components as you would a real router.
- Removed gateway from the NIC and added default_gateway to Node so that Node has a single default gateway.
- Added some routing tests to check that ping can be performed when router between subnets.
## Summary
- Add an object that holds the entire simulation, and a container for the network that keeps track of a list of nodes and links.
- Implement `describe_state()` for all existing sim components and take advantage of the inheritance relationships to avoid repetition.
- Fix some minor mistakes like typehints and indentation errors.
- Write a jupyter notebook which uses the python API to create a simulation and verify that it's `describe_state()` method outputs a correct value.
- Currently the notebook creates the simulation in a janky way, because the API for simulation creation is not fleshed out yet. Further tickets have been added to the backlog to address some of these shortcomings. They are:
- #1790
## Test process
I have tested that the notebook runs and that after populating a simulation, the describe_state function returns a dictionary full of only serialisable data types.
## Checklist
- [y] This PR is linked to a **work item**
- [y] I have performed **self-review** of the code
- [~] I have written **tests** for any new functionality added with this PR
- [n] I have updated the **documentation** if this PR changes or adds functionality
- [na] I have written/updated **design docs** if this PR implements new functionality
- [y] I have update the **change log**
- [y] I have run **pre-commit** checks for code style
Note:
This ticket also makes a small amount of progress against: #1705, it adds a shell of a network class, but only by creating the class, not implementing any functionality.
Related work items: #1787
## Summary
Attempting to fix a test which seems to be broken when integrated with https://dev.azure.com/ma-dev-uk/PrimAITE/_git/PrimAITE/pullrequest/160
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have written/updated **design docs** if this PR implements new functionality.
- [x] I have run **pre-commit** checks for code style
#1714: fixing minor error in test + adding a check for existing uuid when adding file
Related work items: #1714
## Summary
- Network Hardware - Added base hardware module with NIC, SwitchPort, Node, Switch, and Link. Nodes and Switches have
fundamental services like ARP, ICMP, and PCAP running them by default.
- Network Transmission - Modelled OSI Model layers 1 through to 5 with various classes for creating network frames and
transmitting them from a Service/Application, down through the layers, over the wire, and back up through the layers to
a Service/Application another machine.
- system - Added the core structure of Application, Services, and Components. Also added a SoftwareManager and
SessionManager.
- #1706 - Got the core Node class build and working with ARP and the ability to ping another node. Added some basic tests in. Next job is to create the Node subclasses. Then move ARP and ICMP into a ser
- #1706 - Added some extra logging
- #1706 - Started adding the core node software required by all nodes. Made some tweaks to the Frame to have send and receive timestamp.
- #1706 - Got the code services, application, and process base classes stubbed out. Need them now so that I can leverage them for core node services required.
- #1706 - Tidied up the SysLog ARPCache, and ICMP classes and integrated them into the Node. Tidied up the base implementation of SoftwareManager and SessionManager. Tidies up the public API for Service
## Test process
Tests really asses how components fit together and that it all does work. They tests don't yet check that things like ICMP work, as in the ping is received and responded to.
## Checklist
- [X] This PR is linked to a **work item**
- [X] I have performed **self-review** of the code
- [X] I have written **tests** for any new functionality added with this PR
- [X] I have updated the **documentation** if this PR changes or adds functionality
- [X] I have written/updated **design docs** if this PR implements new functionality.
- [X] I have run **pre-commit** checks for code style
Related work items: #1706
## Summary
This PR implements an outline of accounts and domain controller. However, the main contribution is the permissions system and the changes to `SimComponent`. The domain skeleton will probably change after the node/folder/file/app/service classes exist.
The big idea of the permissions is that the simulator itself is built in a way that permits everything, i.e. the methods of each component that make something happen don't have any permissions checking. Therefore, if you can use primaite without any agents and you will essentially have superadmin, any action you perform will go through. The permissions come into play when you try to interact with the components via the actions. Every action has a configurable permission validator attached to it that will either allow or block the action.
For this reason, I've had to modify the way actions work. To keep everything neatly contained, there is a new Action class that holds a reference to both the action function itself but also to a permission validation function.
## Test process
Unit tests and integration tests.
I will write the design documentation for permissions and update the design for SimComponent once others are happy that the design makes sense.
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [x] I have updated the **documentation** if this PR changes or adds functionality
- [x] I have updated the **changelog**
- [ ] I have written/updated **design docs** if this PR implements new functionality
- [x] I have run **pre-commit** checks for code style
Related work items: #1716
## Summary
- Added the primaite/simulator/network/transmission sub-package with modules for each layer. They come together to build a minimal but fairly realistic network Frame.
- A custom PrimaiteHeader has been included to hold primaite specific metadata required in transmission for reward function and RL agent downstream.
- Added some basic tests that check the proper configuration of Frames with matching headers for protocols.
- Updated the frame typehints in NIC and Link classes.
- Added documentation for the transport layer down to data link layer
## Test process
Unit tests check the frame has been configured correctly with the right headers for the right protocol.
## Checklist
- [X] This PR is linked to a **work item**
- [X] I have performed **self-review** of the code
- [X] I have written **tests** for any new functionality added with this PR
- [X] I have updated the **documentation** if this PR changes or adds functionality
- [X] I have written/updated **design docs** if this PR implements new functionality.
- [X] I have run **pre-commit** checks for code style
Related work items: #1724
## Summary
- #1715#1715 - Added Link class in physical_layer.py.- Also added NIC class in physical_layer.py for
#1672. Added attributes and public API functions.
- Added test_physical_layer.py with some basic tests ready to house the tests once logic has been implemented.
- Made use of the pydantic model_post_init function for proper ipv4 configuration checking.
- Added NetworkError to exceptions.py.
- Added timestep int as a param to the apply_timestep function in core.py. Also added a reset_component_for_episode function.
- Updated docs with details of Link and NIC.
## Test process
- Added basic unit tests for instantiation that look at proper config and error raising.
- Added an integration test for linking NICs to Link.
## Checklist
- [ ] This PR is linked to a **work item**
- [ ] I have performed **self-review** of the code
- [ ] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [ ] I have run **pre-commit** checks for code style
Related work items: #1672, #1715
## Summary
Added `flake8-annotations` to the pre-commit hooks. This ensures that we all write type hints for all new code.
There's also a minor unrelated addition to the pre-commit template.
## Test process
I tried adding a function with a parameter but no typehint. Git did not allow me to commit this.
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [x] I have updated the **documentation** if this PR changes or adds functionality
- [x] I have run **pre-commit** checks for code style
Related work items: #1721
## Summary
This introduces a base class for all simulation components. The idea behind this is to formalise the way in which data is extracted from the simulator and the way actions are applied to the different aspects of the simulator.
The intention is that any class that simulates something will inherit from SimComponent (which inherits from pydantic BaseModel).
Actions enter the simulator as a list of strings that is intended to be peeled back as you go down the layers of the simulation. For example we could have an action of `["network", "nodes", "node3", "network_interface_card", "disable"]` This list is passed to the `apply_action()` function of the overall simulation controller. The simulation controller looks at the first word on the list, `network` and uses this to select a method that can apply the function. It passes the remainder of the list as an argument to that function. In this case it will be `["nodes", "node3", "network_interface_card", "disable"]`.
To the reviewers, please validate that you're happy with the implicit design choices I've made while implementing this. Especially the contract passing actions down the components tree.
(also I changed some mentions of agent to agent_abc in the docs as it was complaining and refusing to build.)
## Test process
I have written basic unit tests to check that the custom functionality added to SimComponent doesn't interfere with basic pydantic functionality.
I also started doc pages that explains these concepts to potential developers, although once there are subclasses of this core class, it will be easier to populate the docs with concrete examples.
## Checklist
- [x] This PR is linked to a **work item**
- [x] I have performed **self-review** of the code
- [x] I have written **tests** for any new functionality added with this PR
- [x] I have updated the **documentation** if this PR changes or adds functionality
- [x] I have run **pre-commit** checks for code style
- [x] I have **type hinted** all the code I changed.
Related work items: #1709
## Summary
Added the ability to load legacy lay down config files. Added extensive unit testing and end-to-end testing. Also added the ability to set exactly how many num_train_steps, num_eval_steps, num_train_episodes, and num_eval_episode and used when converting a legacy training config.
## Test process
Full unit test and end-to-end test
## Checklist
- [X] This PR is linked to a **work item**
- [X] I have performed **self-review** of the code
- [X] I have written **tests** for any new functionality added with this PR
- [ ] I have updated the **documentation** if this PR changes or adds functionality
- [X] I have run **pre-commit** checks for code style
Related work items: #1711
*Replace this text with an explanation of what the changes are and how you implemented them. Can this impact any other parts of the codebase that we should keep in mind?*
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [ ] This PR is linked to a **work item**
- [ ]I have performed **self-review** of the code
- [ ]I have written **tests** for any new functionality added with this PR
- [ ]I have updated the **documentation** if this PR changes or adds functionality
- [ ]I have run **pre-commit** checks for code style
## Summary
*Replace this text with an explanation of what the changes are and how you implemented them. Can this impact any other parts of the codebase that we should keep in mind?*
## Test process
*How have you tested this (if applicable)?*
## Checklist
- [ ] PR is linked to a **work item**
- [ ]**acceptance criteria** of linked ticket are met
- [ ]performed **self-review** of the code
- [ ]written **tests** for any new functionality added with this PR
- [ ]updated the **documentation** if this PR changes or adds functionality
- [ ] written/updated **design docs** if this PR implements new functionality
@@ -5,7 +5,158 @@ 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.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 3.0.0b9
- Removed deprecated `PrimaiteSession` class.
- Added ability to set log levels via configuration.
- Upgraded pydantic to version 2.7.0
- Upgraded Ray to version >= 2.9
- Added ipywidgets to the dependencies
- Added ability to define scenarios that change depending on the episode number.
- Standardised Environment API by renaming the config parameter of `PrimaiteGymEnv` from `game_config` to `env_config`
- Database Connection ID's are now created/issued by DatabaseService and not DatabaseClient
- Updated DatabaseClient so that it can now have a single native DatabaseClientConnection along with a collection of DatabaseClientConnection's.
- Implemented the uninstall functionality for DatabaseClient so that all connections are terminated at the DatabaseService.
- Added the ability for a DatabaseService to terminate a connection.
- Added active_connection to DatabaseClientConnection so that if the connection is terminated active_connection is set to False and the object can no longer be used.
- Added additional show functions to enable connection inspection.
- Updates to agent logging, to include the reward both per step and per episode.
- Introduced Developer CLI tools to assist with developing/debugging PrimAITE
- Can be enabled via `primaite dev-mode enable`
- Activating dev-mode will change the location where the sessions will be output - by default will output where the PrimAITE repository is located
- Refactored all air-space usage to that a new instance of AirSpace is created for each instance of Network. This 1:1 relationship between network and airspace will allow parallelization.
- Added notebook to demonstrate use of SubprocVecEnv from SB3 to vectorise environments to speed up training.
## [Unreleased]
- Made requests fail to reach their target if the node is off
- Added responses to requests
- Made environment reset completely recreate the game object.
- Changed the red agent in the data manipulation scenario to randomly choose client 1 or client 2 to start its attack.
- Changed the data manipulation scenario to include a second green agent on client 1.
- Refactored actions and observations to be configurable via object name, instead of UUID.
- Made database patch correctly take 2 timesteps instead of being immediate
- Made database patch only possible when the software is compromised or good, it's no longer possible when the software is OFF or RESETTING
- Added a notebook which explains Data manipulation scenario, demonstrates the attack, and shows off blue agent's action space, observation space, and reward function.
- Made packet capture and system logging optional (off by default). To turn on, change the io_settings.save_pcap_logs and io_settings.save_sys_logs settings in the config.
- Made observation space flattening optional (on by default). To turn off for an agent, change the `agent_settings.flatten_obs` setting in the config.
- Added support for SQL INSERT command.
- Added ability to log each agent's action choices in each step to a JSON file.
- Removal of Link bandwidth hardcoding. This can now be configured via the network configuraiton yaml. Will default to 100 if not present.
- Added NMAP application to all host and layer-3 network nodes.
### Bug Fixes
- ACL rules were not resetting on episode reset.
- ACLs were not showing up correctly in the observation space.
- Blue agent's ACL actions were being applied against the wrong IP addresses
- Deleted files and folders did not reset correctly on episode reset.
- Service health status was using the actual health state instead of the visible health state
- Database file health status was using the incorrect value for negative rewards
- Preventing file actions from reaching their intended file
- The data manipulation attack was triggered at episode start.
- FTP STOR stored an additional copy on the client machine's filesystem
- The red agent acted to early
- Order of service health state
- Starting a node didn't start the services on it
- Fixed an issue where the services were still able to run even though the node the service is installed on is turned off
- The use of NODE_FILE_CHECKHASH and NODE_FOLDER_CHECKHASH in the current release is marked as 'Not Implemented'.
### Added
- Network Hardware - Added base hardware module with NIC, SwitchPort, Node, and Link. Nodes have
fundamental services like ARP, ICMP, and PCAP running them by default.
- Network Transmission - Modelled OSI Model layers 1 through to 5 with various classes for creating network frames and
transmitting them from a Service/Application, down through the layers, over the wire, and back up through the layers to
a Service/Application another machine.
- Introduced `Router` and `Switch` classes to manage networking routes more effectively.
- Added `ACLRule` and `RouteTableEntry` classes as part of the `Router`.
- New `.show()` methods in all network component classes to inspect the state in either plain text or markdown formats.
- Added `Computer` and `Server` class to better differentiate types of network nodes.
- Integrated a new Use Case 2 network into the system.
- New unit tests to verify routing between different subnets using `.ping()`.
- system - Added the core structure of Application, Services, and Components. Also added a SoftwareManager and
SessionManager.
- Permission System - each action can define criteria that will be used to permit or deny agent actions.
- File System - ability to emulate a node's file system during a simulation
- Example notebooks - There are 5 jupyter notebook which walk through using PrimAITE
1. Training a Stable Baselines 3 agent
2. Training a single agent system using Ray RLLib
3. Training a multi-agent system Ray RLLib
4. Data manipulation end to end demonstration
5. Data manipulation scenario with customised red agents
- Database:
-`DatabaseClient` and `DatabaseService` created to allow emulation of database actions
- Ability for `DatabaseService` to backup its data to another server via FTP and restore data from backup
- Red Agent Services:
- Data Manipulator Bot - A red agent service which sends a payload to a target machine. (By default this payload is a SQL query that breaks a database). The attack runs in stages with a random, configurable probability of succeeding.
-`DataManipulationAgent` runs the Data Manipulator Bot according to a configured start step, frequency and variance.
- DNS Services: `DNSClient` and `DNSServer`
- FTP Services: `FTPClient` and `FTPServer`
- HTTP Services: `WebBrowser` to simulate a web client and `WebServer`
- NTP Services: `NTPClient` and `NTPServer`
- **RouterNIC Class**: Introduced a new class `RouterNIC`, extending the standard `NIC` functionality. This class is specifically designed for router operations, optimizing the processing and routing of network traffic.
- **Custom Layer-3 Processing**: The `RouterNIC` class includes custom handling for network frames, bypassing standard Node NIC's Layer 3 broadcast/unicast checks. This allows for more efficient routing behavior in network scenarios where router-specific frame processing is required.
- **Enhanced Frame Reception**: The `receive_frame` method in `RouterNIC` is tailored to handle frames based on Layer 2 (Ethernet) checks, focusing on MAC address-based routing and broadcast frame acceptance.
- **Subnet-Wide Broadcasting for Services and Applications**: Implemented the ability for services and applications to conduct broadcasts across an entire IPv4 subnet within the network simulation framework.
- Introduced the `NetworkInterface` abstract class to provide a common interface for all network interfaces. Subclasses are divided into two main categories: `WiredNetworkInterface` and `WirelessNetworkInterface`, each serving as an abstract base class (ABC) for more specific interface types. Under `WiredNetworkInterface`, the subclasses `NIC` and `SwitchPort` were added. For wireless interfaces, `WirelessNIC` and `WirelessAccessPoint` are the subclasses under `WirelessNetworkInterface`.
- Added `Layer3Interface` as an abstract base class for networking functionalities at layer 3, including IP addressing and routing capabilities. This class is inherited by `NIC`, `WirelessNIC`, and `WirelessAccessPoint` to provide them with layer 3 capabilities, facilitating their role in both wired and wireless networking contexts with IP-based communication.
- Created the `ARP` and `ICMP` service classes to handle Address Resolution Protocol operations and Internet Control Message Protocol messages, respectively, with `RouterARP` and `RouterICMP` for router-specific implementations.
- Created `HostNode` as a subclass of `Node`, extending its functionality with host-specific services and applications. This class is designed to represent end-user devices like computers or servers that can initiate and respond to network communications.
- Introduced a new `IPV4Address` type in the Pydantic model for enhanced validation and auto-conversion of IPv4 addresses from strings using an `ipv4_validator`.
- Comprehensive documentation for the Node and its network interfaces, detailing the operational workflow from frame reception to application-level processing.
- Detailed descriptions of the Session Manager and Software Manager functionalities, including their roles in managing sessions, software services, and applications within the simulation.
- Documentation for the Packet Capture (PCAP) service and SysLog functionality, highlighting their importance in logging network frames and system events, respectively.
- Expanded documentation on network devices such as Routers, Switches, Computers, and Switch Nodes, explaining their specific processing logic and protocol support.
- **Firewall Node**: Introduced the `Firewall` class extending the functionality of the existing `Router` class. The `Firewall` class incorporates advanced features to scrutinize, direct, and filter traffic between various network zones, guided by predefined security rules and policies. Key functionalities include:
- Access Control Lists (ACLs) for traffic filtering based on IP addresses, protocols, and port numbers.
- Network zone segmentation for managing traffic across external, internal, and DMZ (De-Militarized Zone) networks.
- Interface configuration to establish connectivity and define network parameters for external, internal, and DMZ interfaces.
- Protocol and service management to oversee traffic and enforce security policies.
- Dynamic traffic processing and filtering to ensure network security and integrity.
-`AirSpace` class to simulate wireless communications, managing wireless interfaces and facilitating the transmission of frames within specified frequencies.
-`AirSpaceFrequency` enum for defining standard wireless frequencies, including 2.4 GHz and 5 GHz bands, to support realistic wireless network simulations.
-`WirelessRouter` class, extending the `Router` class, to incorporate wireless networking capabilities alongside traditional wired connections. This class allows the configuration of wireless access points with specific IP settings and operating frequencies.
- Documentation Updates:
- Examples include how to set up PrimAITE session via config
- Examples include how to create nodes and install software via config
- Examples include how to set up PrimAITE session via Python
- Examples include how to create nodes and install software via Python
- Added missing ``DoSBot`` documentation page
- Added diagrams where needed to make understanding some things easier
- Templated parts of the documentation to prevent unnecessary repetition and for easier maintaining of documentation
- Separated documentation pages of some items i.e. client and server software were on the same pages - which may make things confusing
- Configuration section at the bottom of the software pages specifying the configuration options available (and which ones are optional)
- Ability to add ``Firewall`` node via config
- Ability to add ``Router`` routes via config
- Ability to add ``Router``/``Firewall`` ``ACLRule`` via config
- NMNE capturing capabilities to `NetworkInterface` class for detecting and logging Malicious Network Events.
- New `nmne_config` settings in the simulation configuration to enable NMNE capturing and specify keywords such as "DELETE".
- Router-specific SessionManager Implementation: Introduced a specialized version of the SessionManager tailored for router operations. This enhancement enables the SessionManager to determine the routing path by consulting the route table.
### Changed
- Integrated the RouteTable into the Routers frame processing.
- Frames are now dropped when their TTL reaches 0
- **NIC Functionality Update**: Updated the Network Interface Card (`NIC`) functionality to support Layer 3 (L3) broadcasts.
- **Layer 3 Broadcast Handling**: Enhanced the existing `NIC` classes to correctly process and handle Layer 3 broadcasts. This update allows devices using standard NICs to effectively participate in network activities that involve L3 broadcasting.
- **Improved Frame Reception Logic**: The `receive_frame` method of the `NIC` class has been updated to include additional checks and handling for L3 broadcasts, ensuring proper frame processing in a wider range of network scenarios.
- Standardised the way network interfaces are accessed across all `Node` subclasses (`HostNode`, `Router`, `Switch`) by maintaining a comprehensive `network_interface` attribute. This attribute captures all network interfaces by their port number, streamlining the management and interaction with network interfaces across different types of nodes.
- Refactored all tests to utilise new `Node` subclasses (`Computer`, `Server`, `Router`, `Switch`) instead of creating generic `Node` instances and manually adding network interfaces. This change aligns test setups more closely with the intended use cases and hierarchies within the network simulation framework.
- Updated all tests to employ the `Network()` class for managing nodes and their connections, ensuring a consistent and structured approach to setting up network topologies in testing scenarios.
- **ACLRule Wildcard Masking**: Updated the `ACLRule` class to support IP ranges using wildcard masking. This enhancement allows for more flexible and granular control over traffic filtering, enabling the specification of broader or more specific IP address ranges in ACL rules.
- Updated `NetworkInterface` documentation to reflect the new NMNE capturing features and how to use them.
- Integration of NMNE capturing functionality within the `NICObservation` class.
- Changed blue action set to enable applying node scan, reset, start, and shutdown to every host in data manipulation scenario
- Addressed network transmission issues that previously allowed ARP requests to be incorrectly routed and repeated across different subnets. This fix ensures ARP requests are correctly managed and confined to their appropriate network segments.
- Resolved problems in `Node` and its subclasses where the default gateway configuration was not properly utilized for communications across different subnets. This correction ensures that nodes effectively use their configured default gateways for outbound communications to other network segments, thereby enhancing the network's routing functionality and reliability.
- Network Interface Port name/num being set properly for sys log and PCAP output.
* **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/{todo:fill in URL}/PrimAITE/issues).
* If you're unable to find an open issue addressing the problem, [open a new one](https://github.com/{todo:fill in URL}/PrimAITE/issues/new?assignees=&labels=bug&projects=&template=bug_report.md&title=%5BBUG%5D+-+%3Cbug+title+goes+here%3E). Be sure to follow our bug report template with the headers **Describe the bug**, **To Reproduce**, **Expected behaviour**, **Screenshots/Outputs**, **Environment**, and **Additional context**
### **Do you have a solution to fix the bug?**
* [Fork the repository](https://github.com/{todo:fill in URL}/PrimAITE/fork).
* Install the pre-commit hook with `pre-commit install`.
* Implement the bug fix.
* Update documentation where applicable.
* Update the **UNRELEASED** section of the [CHANGELOG.md](CHANGELOG.md) file
* Write a suitable test/tests.
* Commit the bug fix to the dev branch on your fork. If the bug has an open issue under [Issues](https://github.com/{todo:fill in URL}/PrimAITE/issues), reference the issue in the commit message (e.g. #1 references issue 1).
* Submit a pull request from your dev branch to the {todo:fill in URL}/PrimAITE dev branch. Again, if the bug has an open issue under [Issues](https://github.com/{todo:fill in URL}/PrimAITE/issues), reference the issue in the pull request description.
### **Did you fix whitespace, format code, or make a purely cosmetic patch?**
Changes that are cosmetic in nature and do not add anything substantial to the stability, functionality, or testability of PrimAITE will generally not be accepted.
### **Do you intend to add a new feature or change an existing one?**
* Submit a [feature request issue](https://github.com/{todo:fill in URL}/PrimAITE/issues/new?assignees=&labels=feature_request&projects=&template=feature_request.md&title=%5BREQUEST%5D+-+%3Crequest+title+goes+here%3E).
* Know how to implement the new feature or change? Follow the same steps in the bug fix section above to fork, build, document, test, commit, and submit a pull request.
### **Do you have questions about the source code?**
Ask any question about how to use PrimAITE in our discussions section.
### **Do you want to contribute to the PrimAITE documentation?**
Please follow the "Do you intend to add a new feature or change an existing one?" section above and tag your feature request issue and pull request with the documentation tag.
Copyright (c) 2023 - 2025 Defence Science and Technology Laboratory UK (https://dstl.gov.uk)
MIT License Conditions
Permission is hereby granted, free of charge, to any person obtaining a copy
These MIT License conditions confirm the provision of the following artefacts as MIT License by Defence Science and Technology
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
request to the QQ or FNC mailbox):
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
- Use Case Release Packs
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
Suppliers are required to read and confirm acceptance of the {todo:fill in URL} Foundry SyOPs (https://github.com/{todo:fill in URL}/foundry-syops) before being admitted access to material hosted on the {todo:fill in URL} Foundry GitHub site.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
The material is supplied in confidence to QQ / FNC and their subcontractors under SERAPIS, and is issued to inform only those
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
of DSTL. The material must be stored and protected appropriately. All material must be destroyed at the end of the task.
The ARCD Primary-level AI Training Environment (**PrimAITE**) provides an effective simulation capability for the purposes of training and evaluating AI in a cyber-defensive role. It incorporates the functionality required of a primary-level ARCD environment, which includes:
- The ability to model a relevant platform / system context;
- The ability to model key characteristics of a platform / system by representing connections, IP addresses, ports, traffic loading, operating systems and services;
- Operates at machine-speed to enable fast training cycles.
PrimAITE presents the following features:
- Highly configurable (via YAML files) to provide the means to model a variety of platform / system laydowns and adversarial attack scenarios;
- A Reinforcement Learning (RL) reward function based on (a) the ability to counter the specific modelled adversarial cyber-attack, and (b) the ability to ensure success;
- Provision of logging to support AI evaluation and metrics gathering;
- Realistic network traffic simulation, including address and sending packets via internet protocols like TCP, UDP, ICMP, and others
- Routers with traffic routing and firewall capabilities
- Support for multiple agents, each having their own customisable observation space, action space, and reward function definition, and either deterministic or RL-directed behaviour
## Getting Started with PrimAITE
### Pre-Requisites
In order to get **PrimAITE** installed, you will need to have the following installed:
-`python3.8+`
-`python3-pip`
-`virtualenv`
### 💫 Installation
**PrimAITE** is designed to be OS-agnostic, and thus should work on most variations/distros of Linux, Windows, and MacOS.
Currently, the PrimAITE wheel can only be installed from GitHub. This may change in the future with release to PyPi.
### Installation from source
#### 1. Navigate to the PrimAITE folder and create a new python virtual environment (venv)
To make your own changes to PrimAITE, perform the install from source (developer install)
#### 1. Clone the PrimAITE repository
``` unix
git clone git@github.com:{todo:fill in URL}/PrimAITE.git
```
#### 2. CD into the repo directory
``` unix
cd PrimAITE
```
#### 3. Create a new python virtual environment (venv)
```unix
python3 -m venv venv
```
#### 4. Activate the venv
##### Unix
```bash
source <name_of_venv>/bin/activate
sourcevenv/bin/activate
```
##### Windows
##### Windows (Powershell)
```powershell
.\<name_of_venv>\Scripts\activate
.\venv\Scripts\activate
```
#### 3. Install `primaite` into the venv along with all of it's dependencies
#### 5. Install `primaite` with the dev extra into the venv along with all of it's dependencies
```bash
python3 -m pip install -e .
python3 -m pip install -e .[dev,rl]
```
### Development Installation
To install the development dependencies, postfix the command in step 3 above with the `[dev]` extra. Example:
#### 6. Perform the PrimAITE setup:
```bash
python3 -m pip install -e .[dev]
primaite setup
```
## Building documentation
#### Note
*It is possible to install PrimAITE without Ray RLLib, StableBaselines3, or any deep learning libraries by omitting the `rl` flag in the pip install command.*
### Running PrimAITE
Use the provided jupyter notebooks as a starting point to try running PrimAITE. They are automatically copied to your PrimAITE notebook folder when you run `primaitesetup`.
#### 1. Activate the virtual environment
##### Windows (Powershell)
```powershell
.\venv\Scripts\activate
```
##### Unix
```bash
source venv/bin/activate
```
#### 2. Open jupyter notebook
```bash
python -m jupyter notebook
```
Then, click the URL provided by the jupyter command to open the jupyter application in your browser. You can also open notebooks in your IDE if supported.
## 📚 Documentation
### Pre requisites
Building the documentation requires the installation of Pandoc
##### Unix
```bash
sudo apt-get install pandoc
```
##### Other operating systems
Follow the steps in https://pandoc.org/installing.html
### Building the documentation
The PrimAITE documentation can be built with the following commands:
##### Unix
@@ -53,12 +164,12 @@ cd docs
make html
```
##### Windows
##### Windows (Powershell)
```powershell
cd docs
.\make.bat html
```
This will build the documentation as a collection of HTML files which uses the Read The Docs sphinx theme. Other build
options are available but may require additional dependencies such as LaTeX and PDF. Please refer to the Sphinx documentation
for your specific output requirements.
## Example notebooks
Check out the example notebooks to learn more about how PrimAITE works and how you can use it to train agents. They are automatically copied to your primaite installation directory when you run `primaitesetup`.
PrimAITE v3.0.0 was benchmarked automatically upon release. Learning rate metrics were captured to be referenced during system-level testing and user acceptance testing (UAT).
The benchmarking process consists of running 5 training session using the same config file. Each session trains an agent for 1000 episodes, with each episode consisting of 128 steps.
The total reward per episode from each session is captured. This is then used to calculate an caverage total reward per episode from the 5 individual sessions for smoothing. Finally, a 25-widow rolling average of the average total reward per session is calculated for further smoothing.
### 4.2 Learning Benchmark of Minor and Bugfix Releases for Major Version 3

### 4.3 Performance of Minor and Bugfix Releases for Major Version 3

PrimAITE v3.1.0 was benchmarked automatically upon release. Learning rate metrics were captured to be referenced during system-level testing and user acceptance testing (UAT).
The benchmarking process consists of running 5 training session using the same config file. Each session trains an agent for 1000 episodes, with each episode consisting of 128 steps.
The total reward per episode from each session is captured. This is then used to calculate an caverage total reward per episode from the 5 individual sessions for smoothing. Finally, a 25-widow rolling average of the average total reward per session is calculated for further smoothing.
### 4.2 Learning Benchmark of Minor and Bugfix Releases for Major Version 3

### 4.3 Performance of Minor and Bugfix Releases for Major Version 3

PrimAITE (Primary-level AI Training Environment) is a simulation environment for training AI under the ARCD programme. It incorporates the functionality required of a Primary-level environment, as specified in the Dstl ARCD Training Environment Matrix document:
Overview
^^^^^^^^
* The ability to model a relevant platform / system context;
* The ability to model key characteristics of a platform / system by representing connections, IP addresses, ports, traffic loading, operating systems, file system, services and processes;
* Operates at machine-speed to enable fast training cycles.
The ARCD Primary-level AI Training Environment (**PrimAITE**) provides an effective simulation capability for training and evaluating AI in a cyber-defensive role. It incorporates the functionality required of a primary-level ARCD environment:
PrimAITE aims to evolve into an ARCD environment that could be used as the follow-on from Reception level approaches (e.g. YAWNING TITAN), and help bridge the Sim-to-Real gap into Secondary level environments (e.g. IMAGINARY YAK).
- The ability to model a relevant system context;
- Modelling an adversarial agent that the defensive agent can be trained and evaluated against;
- The ability to model key characteristics of a system by representing hosts, servers, network devices, IP addresses, ports, operating systems, folders / files, applications, services and links;
- Modelling background (green) pattern-of-life;
- Operates at machine-speed to enable fast training cycles via Reinforcement Learning (RL).
This is similar to the approach taken by FVEY international partners (e.g. AUS CyBORG, US NSA FARLAND and CAN CyGil). These environments are referenced by the Dstl ARCD Agent Training Environments Knowledge Transfer document (TR141342).
Features
^^^^^^^^
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);
- 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;
- Assessed for compatibility with Stable-Baselines3 (SB3), Ray RLlib, and bespoke agents;
- Persona-based adversarial (Red) agent behaviour; several out-the-box personas are provided, and more can be developed to suit the needs of the task. Stochastic variations in Red agent behaviour are also included as required;
- A robust system logging tool, automatically enabled at the node level and featuring various log levels and terminal output options, enables PrimAITE users to conduct in-depth network simulations;
- A PCAP service is seamlessly integrated within the simulation, automatically capturing and logging frames for both
inbound and outbound traffic at the network interface level. This automatic functionality, combined with the ability
to separate traffic directions, significantly enhances network analysis and troubleshooting capabilities;
- Agent action logs provide a description of every action taken by each agent during the episode. This includes timestep, action, parameters, request and response, for all Blue agent activity, which is aligned with the Track 2 Common Action / Observation Space (CAOS) format. Action logs also details of all scripted / stochastic red / green agent actions;
- Environment ground truth is provided at every timestep, providing a full description of the environment’s true state;
- Alignment with CAOS provides the ability to transfer agents between CAOS compliant environments.
Architecture
^^^^^^^^^^^^
PrimAITE is a Python application and will operate on multiple Operating Systems (Windows, Linux and Mac);
a comprehensive installation and user guide is provided with each release to support its usage.
Configuration of PrimAITE is achieved via included YAML files which support full control over the network / system laydown being modelled, background pattern of life, adversarial (red agent) behaviour, and step and episode count.
A Simulation Controller layer manages the overall running of the simulation, keeping track of all low-level objects.
It is agnostic to the number of agents, their action / observation spaces, and the RL library being used.
It presents a public API providing a method for describing the current state of the simulation, a method that accepts action requests and provides responses, and a method that triggers a timestep advancement.
The Game Layer converts the simulation into a playable game for the agent(s).
It translates between simulation state and Gymnasium.Spaces to pass action / observation data between the agent(s) and the simulation. It is responsible for calculating rewards, managing Multi-Agent RL (MARL) action turns, and via a single agent interface can interact with Blue, Red and Green agents.
Agents can either generate their own scripted behaviour or accept input behaviour from an RL agent.
Finally, a Gymnasium / Ray RLlib Environment Layer forwards requests to the Game Layer as the agent sends them. This layer also manages most of the I/O, such as reading in the configuration files and saving agent logs.
..image:: ../../_static/primAITE_architecture.png
:width:500
:align:center
Training & Evaluation Capability
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PrimAITE provides a training and evaluation capability to AI agents in the context of cyber-attack, via its Gymnasium / Ray RLlib compliant interface.
Scenarios can be constructed to reflect network / system laydowns consisting of any configuration of nodes (e.g., PCs, servers etc.) and the networking equipment and links between them.
All nodes can be configured to contain applications, services, folders and files (and their status).
Traffic flows between services and applications as directed by an ‘execution definition,’ with the traffic flow on the network governed by the network equipment (switches, routers and firewalls) and the ACL rules and routing tables they employ.
Highlights of PrimAITE’s training and evaluation capability are:
- The scenario is not bound to a representation of any platform, system, or technology;
- Fully configurable (network / system laydown, green pattern-of-life, red personas, reward function, ACL rules for each device, number of episodes / steps, action / observation space) and repeatable to suit the requirements of AI agents;
- Can integrate with any Gymnasium / Ray RLlib compliant AI agent .
PrimAITE provides a number of use cases (network and red/green action configurations) by default which the user is able to extend and modify as required.
What is PrimAITE built with
--------------------------------------
---------------------------
*`OpenAI's Gym <https://gym.openai.com/>`_ is used as the basis for AI blue agent interaction with the PrimAITE environment
*`Gymnasium <https://gymnasium.farama.org/>`_ is used as the basis for AI blue agent interaction with the PrimAITE environment
*`Networkx <https://github.com/networkx/networkx>`_ is used as the underlying data structure used for the PrimAITE environment
*`Stable Baselines 3 <https://github.com/DLR-RM/stable-baselines3>`_ is used as a default source of RL algorithms (although PrimAITE is not limited to SB3 agents)
*`Ray RLlib <https://github.com/ray-project/ray>`_ is used as an additional source of RL algorithms
@@ -31,35 +98,45 @@ What is PrimAITE built with
*`Plotly <https://github.com/plotly/plotly.py>`_ is used for building high level charts
Where next?
------------
Getting Started with PrimAITE
-----------------------------
Head over to the :ref:`getting-started` page to install and setup PrimAITE!
..toctree::
:maxdepth:8
:caption:Contents:
:caption:About PrimAITE:
:hidden:
source/about
source/dependencies
source/glossary
..toctree::
:caption:Usage:
:hidden:
source/getting_started
source/about
source/simulation
source/game_layer
source/config
source/primaite_session
source/custom_agent
PrimAITE API <source/_autosummary/primaite>
PrimAITE Tests <source/_autosummary/tests>
source/dependencies
source/glossary
source/migration_1.2_-_2.0
.. TODO: Add project links once public repo has been created
PrimAITE is a simulation environment for training agents to protect a computer network from cyber attacks.
Features
********
PrimAITE provides the following features:
* A flexible network / system laydown based on the Python networkx framework
*Nodes and links (edges) host Python classes in order to present attributes and methods (and hence, a more representative model of a platform / system)
*A 'green agent' Information Exchange Requirement (IER) function allows the representation of traffic (protocols and loading) on any / all links. Application of IERs is based on the status of node operating systems and services
*A 'green agent' node Pattern-of-Life (PoL) function allows the representation of core behaviours on nodes (e.g. changing the Hardware state, Software State, Service state, or File System state)
*An Access Control List (ACL) function, mimicking the behaviour of a network firewall, is applied across the model, following standard ACL rule format (e.g. DENY/ALLOW, source IP, destination IP, protocol and port). Application of IERs adheres to any ACL restrictions
*Presents an OpenAI Gym interface to the environment, allowing integration with any OpenAI Gym compliant defensive agents
* Red agent activity based on 'red' IERs and 'red' PoL
* Defined reward function for use with RL agents (based on nodes status, and green / red IER success)
* Fully configurable (network / system laydown, IERs, node PoL, ACL, episode step period, episode max steps) and repeatable to suit the training requirements of agents. Therefore, not bound to a representation of any particular platform, system or technology
* Full capture of discrete metrics relating to agent training (full system state, agent actions taken, average reward)
An inheritance model has been adopted in order to model nodes. All nodes have the following base attributes (Class: Node):
* ID
* Name
* Type (e.g. computer, switch, RTU - enumeration)
* Priority (P1, P2, P3, P4 or P5 - enumeration)
* Hardware State (ON, OFF, RESETTING, SHUTTING_DOWN, BOOTING - enumeration)
Active Nodes also have the following attributes (Class: Active Node):
* IP Address
* Software State (GOOD, PATCHING, COMPROMISED - enumeration)
* File System State (GOOD, CORRUPT, DESTROYED, REPAIRING, RESTORING - enumeration)
Service Nodes also have the following attributes (Class: Service Node):
* List of Services (where service is composed of service name and port). There is no theoretical limit on the number of services that can be modelled. Services and protocols are currently intrinsically linked (i.e. a service is an application on a node transmitting traffic of this protocol type)
* Service state (GOOD, PATCHING, COMPROMISED, OVERWHELMED - enumeration)
Passive Nodes are currently not used (but may be employed for non IP-based components such as machinery actuators in future releases).
**Links**
Links are modelled both as network edges (networkx) and as Python classes, in order to extend their functionality. Links include the following attributes:
* ID
* Name
* Bandwidth (bits/s)
* Source node ID
* Destination node ID
* Protocol list (containing the loading of protocols currently running on the link)
When the simulation runs, IERs are applied to the links in order to model traffic loading, individually assigned to each protocol. This allows green (background) and red agent behaviour to be modelled, and defensive agents to identify suspicious traffic patterns at a protocol / traffic loading level of fidelity.
Information Exchange Requirements (IERs)
****************************************
PrimAITE adopts the concept of Information Exchange Requirements (IERs) to model both green agent (background) and red agent (adversary) behaviour. IERs are used to initiate modelling of traffic loading on the network, and have the following attributes:
* ID
* Start step (i.e. which step in the training episode should the IER start)
* End step (i.e. which step in the training episode should the IER end)
* Source node ID
* Destination node ID
* Load (bits/s)
* Protocol
* Port
* Running status (i.e. on / off)
The application of green agent IERs between a source and destination follows a number of rules. Specifically:
1. Does the current simulation time step fall between IER start and end step
2. Is the source node operational (both physically and at an O/S level), and is the service (protocol / port) associated with the IER (a) present on this node, and (b) in an operational state (i.e. not PATCHING)
3. Is the destination node operational (both physically and at an O/S level), and is the service (protocol / port) associated with the IER (a) present on this node, and (b) in an operational state (i.e. not PATCHING)
4. Are there any Access Control List rules in place that prevent the application of this IER
5. Are all switches in the (OSPF) path between source and destination operational (both physically and at an O/S level)
For red agent IERs, the application of IERs between a source and destination follows a number of subtly different rules. Specifically:
1. Does the current simulation time step fall between IER start and end step
2. Is the source node operational, and is the service (protocol / port) associated with the IER (a) present on that node and (b) already in a compromised state
3. Is the destination node operational, and is the service (protocol / port) associated with the IER present on that node
4. Are there any Access Control List rules in place that prevent the application of this IER
5. Are all switches in the (OSPF) path between source and destination operational (both physically and at an O/S level)
Assuming the rules pass, the IER is applied to all relevant links (based on use of OSPF) between source and destination.
Node Pattern-of-Life
********************
Every node can be impacted (i.e. have a status change applied to it) by either green agent pattern-of-life or red agent pattern-of-life. This is distinct from IERs, and allows for attacks (and defence) to be modelled purely within the confines of a node.
The status changes that can be made to a node are as follows:
* All Nodes:
* Hardware State:
* ON
* OFF
* RESETTING - when a status of resetting is entered, the node will automatically exit this state after a number of steps (as defined by the nodeResetDuration configuration item) after which it returns to an ON state
* BOOTING
* SHUTTING_DOWN
* Active Nodes and Service Nodes:
* Software State:
* GOOD
* PATCHING - when a status of patching is entered, the node will automatically exit this state after a number of steps (as defined by the osPatchingDuration configuration item) after which it returns to a GOOD state
* COMPROMISED
* File System State:
* GOOD
* CORRUPT (can be resolved by repair or restore)
* DESTROYED (can be resolved by restore only)
* REPAIRING - when a status of repairing is entered, the node will automatically exit this state after a number of steps (as defined by the fileSystemRepairingLimit configuration item) after which it returns to a GOOD state
* RESTORING - when a status of repairing is entered, the node will automatically exit this state after a number of steps (as defined by the fileSystemRestoringLimit configuration item) after which it returns to a GOOD state
* Service Nodes only:
* Service State (for any associated service):
* GOOD
* PATCHING - when a status of patching is entered, the service will automatically exit this state after a number of steps (as defined by the servicePatchingDuration configuration item) after which it returns to a GOOD state
* COMPROMISED
* OVERWHELMED
Red agent pattern-of-life has an additional feature not found in the green pattern-of-life. This is the ability to influence the state of the attributes of a node via a number of different conditions:
* DIRECT:
The pattern-of-life described by the configuration file item will be applied regardless of any other conditions in the network. This is particularly useful for direct red agent entry into the network.
* IER:
The pattern-of-life described by the configuration file item will be applied to the service on the node, only if there is an IER of the same protocol / service type incoming at the specified timestep.
* SERVICE:
The pattern-of-life described by the configuration file item will be applied to the node based on the state of a service. The service can either be on the same node, or a different node within the network.
Access Control List modelling
*****************************
An Access Control List (ACL) is modelled to provide the means to manage traffic flows in the system. This will allow defensive agents the means to turn on / off rules, or potentially create new rules, to counter an attack.
The ACL follows a standard network firewall format. For example:
..list-table:: ACL example
:widths:25 25 25 25 25
:header-rows:1
* - Permission
- Source IP
- Dest IP
- Protocol
- Port
* - DENY
- 192.168.1.2
- 192.168.1.3
- HTTPS
- 443
* - ALLOW
- 192.168.1.4
- ANY
- SMTP
- 25
* - DENY
- ANY
- 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.
Observation Spaces
******************
The observation space provides the blue agent with information about the current status of nodes and links.
PrimAITE builds on top of Gym Spaces to create an observation space that is easily configurable for users. It's made up of components which are managed by the :py:class:`primaite.environment.observations.ObservationsHandler`. Each training scenario can define its own observation space, and the user can choose which information to inlude, and how it should be formatted.
NodeLinkTable component
-----------------------
For example, the :py:class:`primaite.environment.observations.NodeLinkTable` component represents the status of nodes and links as a ``gym.spaces.Box`` with an example format shown below:
An example observation space is provided below:
..list-table:: Observation Space example
:widths:25 25 25 25 25 25 25
:header-rows:1
* -
- ID
- Hardware State
- Software State
- File System State
- Service / Protocol A
- Service / Protocol B
* - Node A
- 1
- 1
- 1
- 1
- 1
- 1
* - Node B
- 2
- 1
- 3
- 1
- 1
- 1
* - Node C
- 3
- 2
- 1
- 1
- 3
- 2
* - Link 1
- 5
- 0
- 0
- 0
- 0
- 10000
* - Link 2
- 6
- 0
- 0
- 0
- 0
- 10000
* - Link 3
- 7
- 0
- 0
- 0
- 5000
- 0
For the nodes, the following values are represented:
.. code-block::
[
ID
Hardware State (1=ON, 2=OFF, 3=RESETTING, 4=SHUTTING_DOWN, 5=BOOTING)
Operating System State (0=none, 1=GOOD, 2=PATCHING, 3=COMPROMISED)
File System State (0=none, 1=GOOD, 2=CORRUPT, 3=DESTROYED, 4=REPAIRING, 5=RESTORING)
Service1/Protocol1 state (0=none, 1=GOOD, 2=PATCHING, 3=COMPROMISED)
Service2/Protocol2 state (0=none, 1=GOOD, 2=PATCHING, 3=COMPROMISED)
]
(Note that each service available in the network is provided as a column, although not all nodes may utilise all services)
For the links, the following statuses are represented:
..code-block::
[
ID
Hardware State (0=not applicable)
Operating System State (0=not applicable)
File System State (0=not applicable)
Service1/Protocol1 state (Traffic load from this protocol on this link)
Service2/Protocol2 state (Traffic load from this protocol on this link)
]
NodeStatus component
----------------------
This is a MultiDiscrete observation space that can be though of as a one-dimensional vector of discrete states.
The example above would have the following structure:
In a network with three nodes and two services, the full observation space would have 15 elements. It can be written with ``gym`` notation to indicate the number of discrete options for each of the elements of the observation space. For example:
NodeStatus observation component provides information only about nodes. Links are not considered.
LinkTrafficLevels
-----------------
This component is a MultiDiscrete space showing the traffic flow levels on the links in the network, after applying a threshold to convert it from a continuous to a discrete value.
There are two configurable parameters:
*``quantisation_levels`` determines how many discrete bins to use for converting the continuous traffic value to discrete (default is 5).
*``combine_service_traffic`` determines whether to separately output traffic use for each network protocol or whether to combine them into an overall value for the link. (default is ``True``)
For example, with default parameters and a network with three links, the structure of this component would be:
..code-block::
[
link1_status
link2_status
link3_status
]
Each ``link_status`` is a number from 0-4 representing the network load in relation to bandwidth.
..code-block::
0 = No traffic (0%)
1 = low traffic (1%-33%)
2 = medium traffic (33%-66%)
3 = high traffic (66%-99%)
4 = max traffic/ overwhelmed (100%)
Using ``gym`` notation, the shape of the obs space is: ``gym.spaces.MultiDiscrete([5,5,5])``.
Action Spaces
**************
The action space available to the blue agent comes in two types:
1. Node-based
2. Access Control List
3. Any (Agent can take both node-based and ACL-based actions)
The choice of action space used during a training session is determined in the config_[name].yaml file.
**Node-Based**
The agent is able to influence the status of nodes by switching them off, resetting, or patching operating systems and services. In this instance, the action space is an OpenAI Gym spaces.Discrete type, as follows:
* Dictionary item {... ,1: [x1, x2, x3,x4] ...}
The placeholders inside the list under the key '1' mean the following:
* [0, num nodes] - Node ID (0 = nothing, node ID)
* [0, 4] - What property it's acting on (0 = nothing, 1 = state, 2 = SoftwareState, 3 = service state, 4 = file system state)
* [0, 3] - Action on property (0 = nothing, 1 = on / scan, 2 = off / repair, 3 = reset / patch / restore)
* [0, num services] - Resolves to service ID (0 = nothing, resolves to service)
**Access Control List**
The blue agent is able to influence the configuration of the Access Control List rule set (which implements a system-wide firewall). In this instance, the action space is an OpenAI spaces.Discrete type, as follows:
* [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)
* [0, num ports] - Port (0 = any, then 1 -> x resolving to port)
**ANY**
The agent is able to carry out both **Node-Based** and **Access Control List** operations.
This means the dictionary will contain key-value pairs in the format of BOTH Node-Based and Access Control List as seen above.
Rewards
*******
A reward value is presented back to the blue agent on the conclusion of every step. The reward value is calculated via two methods which combine to give the total value:
1. Node and service status
2. IER status
**Node and service status**
On every step, the status of each node is compared against both a reference environment (simulating the situation if the red and blue agents had not impacted the environment)
and the before and after state of the environment. If the comparison against the reference environment shows no difference, then the score provided is "AllOK". If there is a
difference with respect to the reference environment, the before and after states are compared, and a score determined. See :ref:`config` for details of reward values.
**IER status**
On every step, the full IER set is examined to determine whether green and red agent IERs are being permitted to run. Any red agent IERs running incur a penalty; any green agent
IERs not permitted to run also incur a penalty. See :ref:`config` for details of reward values.
Future Enhancements
*******************
The PrimAITE project has an ambition to include the following enhancements in future releases:
* Integration with a suitable standardised framework to allow multi-agent integration
* Integration with external threat emulation tools, either using off-line data, or integrating at runtime
* A flexible system for defining network layouts and host configurations
*Highly configurable network hosts, including definition of software, file system, and network interfaces,
*Realistic network traffic simulation, including address and sending packets via internet protocols like TCP, UDP, ICMP, etc.
*Routers with traffic routing and firewall capabilities
*Simulation of customisable deterministic agents
*Support for multiple agents, each having their own customisable observation space, action space, and reward function definition.
Structure
*********
PrimAITE consists of a simulator and a 'game' layer that allows agents to interact with the simulator. The simulator is built in a modular way where each component such as network hosts, links, networking devices, softwares, etc. are implemented as instances of a base class, meaning they all support the same interface. This allows for standardised configuration using either the Python API or YAML files.
The game layer is built on top of the simulator and it consumes the simulation action/state interface to allow agents to interact with the simulator. The game layer is also responsible for defining the reward function and observation space for the agents.
..
Architecture - Nodes and Links
******************************
**Nodes**
An inheritance model has been adopted in order to model nodes. All nodes have the following base attributes (Class: Node):
* ID
* Name
* Type (e.g. computer, switch, RTU - enumeration)
* Priority (P1, P2, P3, P4 or P5 - enumeration)
* Hardware State (ON, OFF, RESETTING, SHUTTING_DOWN, BOOTING - enumeration)
Active Nodes also have the following attributes (Class: Active Node):
* IP Address
* Software State (GOOD, FIXING, COMPROMISED - enumeration)
* File System State (GOOD, CORRUPT, DESTROYED, REPAIRING, RESTORING - enumeration)
Service Nodes also have the following attributes (Class: Service Node):
* List of Services (where service is composed of service name and port). There is no theoretical limit on the number of services that can be modelled. Services and protocols are currently intrinsically linked (i.e. a service is an application on a node transmitting traffic of this protocol type)
* Service state (GOOD, FIXING, COMPROMISED, OVERWHELMED - enumeration)
Passive Nodes are currently not used (but may be employed for non IP-based components such as machinery actuators in future releases).
**Links**
Links are modelled both as network edges (networkx) and as Python classes, in order to extend their functionality. Links include the following attributes:
* ID
* Name
* Bandwidth (bits/s)
* Source node ID
* Destination node ID
* Protocol list (containing the loading of protocols currently running on the link)
When the simulation runs, IERs are applied to the links in order to model traffic loading, individually assigned to each protocol. This allows green (background) and red agent behaviour to be modelled, and defensive agents to identify suspicious traffic patterns at a protocol / traffic loading level of fidelity.
Information Exchange Requirements (IERs)
****************************************
PrimAITE adopts the concept of Information Exchange Requirements (IERs) to model both green agent (background) and red agent (adversary) behaviour. IERs are used to initiate modelling of traffic loading on the network, and have the following attributes:
* ID
* Start step (i.e. which step in the training episode should the IER start)
* End step (i.e. which step in the training episode should the IER end)
* Source node ID
* Destination node ID
* Load (bits/s)
* Protocol
* Port
* Running status (i.e. on / off)
The application of green agent IERs between a source and destination follows a number of rules. Specifically:
1. Does the current simulation time step fall between IER start and end step
2. Is the source node operational (both physically and at an O/S level), and is the service (protocol / port) associated with the IER (a) present on this node, and (b) in an operational state (i.e. not FIXING)
3. Is the destination node operational (both physically and at an O/S level), and is the service (protocol / port) associated with the IER (a) present on this node, and (b) in an operational state (i.e. not FIXING)
4. Are there any Access Control List rules in place that prevent the application of this IER
5. Are all switches in the (OSPF) path between source and destination operational (both physically and at an O/S level)
For red agent IERs, the application of IERs between a source and destination follows a number of subtly different rules. Specifically:
1. Does the current simulation time step fall between IER start and end step
2. Is the source node operational, and is the service (protocol / port) associated with the IER (a) present on that node and (b) already in a compromised state
3. Is the destination node operational, and is the service (protocol / port) associated with the IER present on that node
4. Are there any Access Control List rules in place that prevent the application of this IER
5. Are all switches in the (OSPF) path between source and destination operational (both physically and at an O/S level)
Assuming the rules pass, the IER is applied to all relevant links (based on use of OSPF) between source and destination.
Node Pattern-of-Life
********************
Every node can be impacted (i.e. have a status change applied to it) by either green agent pattern-of-life or red agent pattern-of-life. This is distinct from IERs, and allows for attacks (and defence) to be modelled purely within the confines of a node.
The status changes that can be made to a node are as follows:
* All Nodes:
* Hardware State:
* ON
* OFF
* RESETTING - when a status of resetting is entered, the node will automatically exit this state after a number of steps (as defined by the nodeResetDuration configuration item) after which it returns to an ON state
* BOOTING
* SHUTTING_DOWN
* Active Nodes and Service Nodes:
* Software State:
* GOOD
* FIXING - when a status of FIXING is entered, the node will automatically exit this state after a number of steps (as defined by the osFIXINGDuration configuration item) after which it returns to a GOOD state
* COMPROMISED
* File System State:
* GOOD
* CORRUPT (can be resolved by repair or restore)
* DESTROYED (can be resolved by restore only)
* REPAIRING - when a status of repairing is entered, the node will automatically exit this state after a number of steps (as defined by the fileSystemRepairingLimit configuration item) after which it returns to a GOOD state
* RESTORING - when a status of repairing is entered, the node will automatically exit this state after a number of steps (as defined by the fileSystemRestoringLimit configuration item) after which it returns to a GOOD state
* Service Nodes only:
* Service State (for any associated service):
* GOOD
* FIXING - when a status of FIXING is entered, the service will automatically exit this state after a number of steps (as defined by the serviceFIXINGDuration configuration item) after which it returns to a GOOD state
* COMPROMISED
* OVERWHELMED
Red agent pattern-of-life has an additional feature not found in the green pattern-of-life. This is the ability to influence the state of the attributes of a node via a number of different conditions:
* DIRECT:
The pattern-of-life described by the configuration file item will be applied regardless of any other conditions in the network. This is particularly useful for direct red agent entry into the network.
* IER:
The pattern-of-life described by the configuration file item will be applied to the service on the node, only if there is an IER of the same protocol / service type incoming at the specified timestep.
* SERVICE:
The pattern-of-life described by the configuration file item will be applied to the node based on the state of a service. The service can either be on the same node, or a different node within the network.
Access Control List modelling
*****************************
An Access Control List (ACL) is modelled to provide the means to manage traffic flows in the system. This will allow defensive agents the means to turn on / off rules, or potentially create new rules, to counter an attack.
The ACL follows a standard network firewall format. For example:
.. list-table:: ACL example
:widths: 25 25 25 25 25
:header-rows: 1
* - Permission
- Source IP
- Dest IP
- Protocol
- Port
* - DENY
- 192.168.1.2
- 192.168.1.3
- HTTPS
- 443
* - ALLOW
- 192.168.1.4
- ANY
- SMTP
- 25
* - DENY
- ANY
- 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.
Observation Spaces
******************
The observation space provides the blue agent with information about the current status of nodes and links.
PrimAITE builds on top of Gymnasium Spaces to create an observation space that is easily configurable for users. It's made up of components which are managed by the :py:class:`primaite.environment.observations.ObservationsHandler`. Each training scenario can define its own observation space, and the user can choose which information to inlude, and how it should be formatted.
NodeLinkTable component
-----------------------
For example, the :py:class:`primaite.environment.observations.NodeLinkTable` component represents the status of nodes and links as a ``gym.spaces.Box`` with an example format shown below:
An example observation space is provided below:
.. list-table:: Observation Space example
:widths: 25 25 25 25 25 25 25
:header-rows: 1
* -
- ID
- Hardware State
- Software State
- File System State
- Service / Protocol A
- Service / Protocol B
* - Node A
- 1
- 1
- 1
- 1
- 1
- 1
* - Node B
- 2
- 1
- 3
- 1
- 1
- 1
* - Node C
- 3
- 2
- 1
- 1
- 3
- 2
* - Link 1
- 5
- 0
- 0
- 0
- 0
- 10000
* - Link 2
- 6
- 0
- 0
- 0
- 0
- 10000
* - Link 3
- 7
- 0
- 0
- 0
- 5000
- 0
For the nodes, the following values are represented:
.. code-block::
[
ID
Hardware State (1=ON, 2=OFF, 3=RESETTING, 4=SHUTTING_DOWN, 5=BOOTING)
Operating System State (0=none, 1=GOOD, 2=PATCHING, 3=COMPROMISED)
File System State (0=none, 1=GOOD, 2=CORRUPT, 3=DESTROYED, 4=REPAIRING, 5=RESTORING)
Service1/Protocol1 state (0=none, 1=GOOD, 2=FIXING, 3=COMPROMISED)
Service2/Protocol2 state (0=none, 1=GOOD, 2=FIXING, 3=COMPROMISED)
]
(Note that each service available in the network is provided as a column, although not all nodes may utilise all services)
For the links, the following statuses are represented:
.. code-block::
[
ID
Hardware State (0=not applicable)
Operating System State (0=not applicable)
File System State (0=not applicable)
Service1/Protocol1 state (Traffic load from this protocol on this link)
Service2/Protocol2 state (Traffic load from this protocol on this link)
]
NodeStatus component
----------------------
This is a MultiDiscrete observation space that can be though of as a one-dimensional vector of discrete states.
The example above would have the following structure:
In a network with three nodes and two services, the full observation space would have 15 elements. It can be written with ``gym`` notation to indicate the number of discrete options for each of the elements of the observation space. For example:
NodeStatus observation component provides information only about nodes. Links are not considered.
LinkTrafficLevels
-----------------
This component is a MultiDiscrete space showing the traffic flow levels on the links in the network, after applying a threshold to convert it from a continuous to a discrete value.
There are two configurable parameters:
* ``quantisation_levels`` determines how many discrete bins to use for converting the continuous traffic value to discrete (default is 5).
* ``combine_service_traffic`` determines whether to separately output traffic use for each network protocol or whether to combine them into an overall value for the link. (default is ``True``)
For example, with default parameters and a network with three links, the structure of this component would be:
.. code-block::
[
link1_status
link2_status
link3_status
]
Each ``link_status`` is a number from 0-4 representing the network load in relation to bandwidth.
.. code-block::
0 = No traffic (0%)
1 = low traffic (1%-33%)
2 = medium traffic (33%-66%)
3 = high traffic (66%-99%)
4 = max traffic/ overwhelmed (100%)
Using ``gym`` notation, the shape of the obs space is: ``gym.spaces.MultiDiscrete([5,5,5])``.
Action Spaces
**************
The action space available to the blue agent comes in two types:
1. Node-based
2. Access Control List
3. Any (Agent can take both node-based and ACL-based actions)
The choice of action space used during a training session is determined in the config_[name].yaml file.
**Node-Based**
The agent is able to influence the status of nodes by switching them off, resetting, or FIXING operating systems and services. In this instance, the action space is a Gymnasium spaces.Discrete type, as follows:
* Dictionary item {... ,1: [x1, x2, x3,x4] ...}
The placeholders inside the list under the key '1' mean the following:
* [0, num nodes] - Node ID (0 = nothing, node ID)
* [0, 4] - What property it's acting on (0 = nothing, 1 = state, 2 = SoftwareState, 3 = service state, 4 = file system state)
* [0, 3] - Action on property (0 = nothing, 1 = on / scan, 2 = off / repair, 3 = reset / patch / restore)
* [0, num services] - Resolves to service ID (0 = nothing, resolves to service)
**Access Control List**
The blue agent is able to influence the configuration of the Access Control List rule set (which implements a system-wide firewall). In this instance, the action space is an Gymnasium spaces.Discrete type, as follows:
* [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)
* [0, num ports] - Port (0 = any, then 1 -> x resolving to port)
**ANY**
The agent is able to carry out both **Node-Based** and **Access Control List** operations.
This means the dictionary will contain key-value pairs in the format of BOTH Node-Based and Access Control List as seen above.
Rewards
*******
A reward value is presented back to the blue agent on the conclusion of every step. The reward value is calculated via two methods which combine to give the total value:
1. Node and service status
2. IER status
**Node and servicestatus**
On every step, the status of each node is compared against both a reference environment (simulating the situation if the red and blue agents had not impacted the environment)
and the before and after state of the environment. If the comparison against the reference environment shows no difference, then the score provided is "AllOK". If there is a
difference with respect to the reference environment, the before and after states are compared, and a score determined. See :ref:`config` for details of reward values.
**IER status**
On every step, the full IER set is examined to determine whether green and red agent IERs are being permitted to run. Any red agent IERs running incur a penalty; any green agent
IERs not permitted to run also incur a penalty. See :ref:`config` for details of reward values.
Future Enhancements
*******************
The PrimAITE project has an ambition to include the following enhancements in future releases:
* Integration with a suitable standardised framework to allow multi-agent integration
* Integration with external threat emulation tools, either using off-line data, or integrating at runtime
PrimAITE uses YAML configuration files to define everything needed to create the training environment for RL agents, including the network, the scripted agents, and the RL agent's action space, observation space, and reward function.
PrimAITE uses two configuration files for its operation:
Example Configuration Hierarchy
###############################
The top level configuration items in a configuration file is as follows
***The Training Config**
..code-block::yaml
Used to define the top-level settings of the PrimAITE environment, the reward values, and the session that is to be run.
io_settings:
...
game:
...
agents:
...
simulation:
...
***The Lay Down Config**
These are expanded upon in the Configurable items section below
Used to define the low-level settings of a session, including the network laydown, green / red agent information exchange requirements (IERSs) and Access Control Rules.
Configurable items
##################
Training Config:
*******************
..toctree::
:maxdepth:1
The Training Config file consists of the following attributes:
configuration/io_settings.rst
configuration/game.rst
configuration/agents.rst
configuration/simulation.rst
**Generic Config Values**
Varying The Configuration Each Episode
######################################
***agent_framework** [enum]
This identifies the agent framework to be used to instantiate the agent algorithm. Select from one of the following:
* NONE - Where a user developed agent is to be used
* SB3 - Stable Baselines3
* RLLIB - Ray RLlib.
***agent_identifier**
This identifies the agent to use for the session. Select from one of the following:
* A2C - Advantage Actor Critic
* PPO - Proximal Policy Optimization
* HARDCODED - A custom built deterministic agent
* RANDOM - A Stochastic random agent
***random_red_agent** [bool]
Determines if the session should be run with a random red agent
***action_type** [enum]
Determines whether a NODE, ACL, or ANY (combined NODE & ACL) action space format is adopted for the session
***OBSERVATION_SPACE** [dict]
Allows for user to configure observation space by combining one or more observation components. List of available
components is in :py:mod:`primaite.environment.observations`.
The observation space config item should have a ``components`` key which is a list of components. Each component
config must have a ``name`` key, and can optionally have an ``options`` key. The ``options`` are passed to the
component while it is being initialised.
This example illustrates the correct format for the observation space config item
..code-block::yaml
observation_space:
components:
- name:NODE_LINK_TABLE
- name:NODE_STATUSES
- name:LINK_TRAFFIC_LEVELS
- name:ACCESS_CONTROL_LIST
options:
combine_service_traffic :False
quantisation_levels:99
Currently available components are:
*:py:mod:`NODE_LINK_TABLE<primaite.environment.observations.NodeLinkTable>` this does not accept any additional options
*:py:mod:`NODE_STATUSES<primaite.environment.observations.NodeStatuses>`, this does not accept any additional options
*:py:mod:`ACCESS_CONTROL_LIST<primaite.environment.observations.AccessControlList>`, this does not accept additional options
*:py:mod:`LINK_TRAFFIC_LEVELS<primaite.environment.observations.LinkTrafficLevels>`, this accepts the following options:
*``combine_service_traffic`` - whether to consider bandwidth use separately for each network protocol or combine them into a single bandwidth reading (boolean)
*``quantisation_levels`` - how many discrete bandwidth usage levels to use for encoding. This can be an integer equal to or greater than 3.
The other configurable item is ``flatten`` which is false by default. When set to true, the observation space is flattened (turned into a 1-D vector). You should use this if your RL agent does not natively support observation space types like ``gym.Spaces.Tuple``.
***num_train_episodes** [int]
This defines the number of episodes that the agent will train for.
***num_train_steps** [int]
Determines the number of steps to run in each episode of the training session.
***num_eval_episodes** [int]
This defines the number of episodes that the agent will be evaluated over.
***num_eval_steps** [int]
Determines the number of steps to run in each episode of the evaluation session.
***time_delay** [int]
The time delay (in milliseconds) to take between each step when running a GENERIC agent session
***session_type** [text]
Type of session to be run (TRAINING, EVALUATION, or BOTH)
***load_agent** [bool]
Determine whether to load an agent from file
***agent_load_file** [text]
File path and file name of agent if you're loading one in
***observation_space_high_value** [int]
The high value to use for values in the observation space. This is set to 1000000000 by default, and should not need changing in most cases
***implicit_acl_rule** [str]
Determines which Explicit rule the ACL list has - two options are: DENY or ALLOW.
***max_number_acl_rules** [int]
Sets a limit on how many ACL rules there can be in the ACL list throughout the training session.
**Reward-Based Config Values**
Rewards are calculated based on the difference between the current state and reference state (the 'should be' state) of the environment.
***Generic [all_ok]** [float]
The score to give when the current situation (for a given component) is no different from that expected in the baseline (i.e. as though no blue or red agent actions had been undertaken)
***Node Hardware State [off_should_be_on]** [float]
The score to give when the node should be on, but is off
***Node Hardware State [off_should_be_resetting]** [float]
The score to give when the node should be resetting, but is off
***Node Hardware State [on_should_be_off]** [float]
The score to give when the node should be off, but is on
***Node Hardware State [on_should_be_resetting]** [float]
The score to give when the node should be resetting, but is on
***Node Hardware State [resetting_should_be_on]** [float]
The score to give when the node should be on, but is resetting
***Node Hardware State [resetting_should_be_off]** [float]
The score to give when the node should be off, but is resetting
***Node Hardware State [resetting]** [float]
The score to give when the node is resetting
***Node Operating System or Service State [good_should_be_patching]** [float]
The score to give when the state should be patching, but is good
***Node Operating System or Service State [good_should_be_compromised]** [float]
The score to give when the state should be compromised, but is good
***Node Operating System or Service State [good_should_be_overwhelmed]** [float]
The score to give when the state should be overwhelmed, but is good
***Node Operating System or Service State [patching_should_be_good]** [float]
The score to give when the state should be good, but is patching
***Node Operating System or Service State [patching_should_be_compromised]** [float]
The score to give when the state should be compromised, but is patching
***Node Operating System or Service State [patching_should_be_overwhelmed]** [float]
The score to give when the state should be overwhelmed, but is patching
***Node Operating System or Service State [patching]** [float]
The score to give when the state is patching
***Node Operating System or Service State [compromised_should_be_good]** [float]
The score to give when the state should be good, but is compromised
***Node Operating System or Service State [compromised_should_be_patching]** [float]
The score to give when the state should be patching, but is compromised
***Node Operating System or Service State [compromised_should_be_overwhelmed]** [float]
The score to give when the state should be overwhelmed, but is compromised
***Node Operating System or Service State [compromised]** [float]
The score to give when the state is compromised
***Node Operating System or Service State [overwhelmed_should_be_good]** [float]
The score to give when the state should be good, but is overwhelmed
***Node Operating System or Service State [overwhelmed_should_be_patching]** [float]
The score to give when the state should be patching, but is overwhelmed
***Node Operating System or Service State [overwhelmed_should_be_compromised]** [float]
The score to give when the state should be compromised, but is overwhelmed
***Node Operating System or Service State [overwhelmed]** [float]
The score to give when the state is overwhelmed
***Node File System State [good_should_be_repairing]** [float]
The score to give when the state should be repairing, but is good
***Node File System State [good_should_be_restoring]** [float]
The score to give when the state should be restoring, but is good
***Node File System State [good_should_be_corrupt]** [float]
The score to give when the state should be corrupt, but is good
***Node File System State [good_should_be_destroyed]** [float]
The score to give when the state should be destroyed, but is good
***Node File System State [repairing_should_be_good]** [float]
The score to give when the state should be good, but is repairing
***Node File System State [repairing_should_be_restoring]** [float]
The score to give when the state should be restoring, but is repairing
***Node File System State [repairing_should_be_corrupt]** [float]
The score to give when the state should be corrupt, but is repairing
***Node File System State [repairing_should_be_destroyed]** [float]
The score to give when the state should be destroyed, but is repairing
***Node File System State [repairing]** [float]
The score to give when the state is repairing
***Node File System State [restoring_should_be_good]** [float]
The score to give when the state should be good, but is restoring
***Node File System State [restoring_should_be_repairing]** [float]
The score to give when the state should be repairing, but is restoring
***Node File System State [restoring_should_be_corrupt]** [float]
The score to give when the state should be corrupt, but is restoring
***Node File System State [restoring_should_be_destroyed]** [float]
The score to give when the state should be destroyed, but is restoring
***Node File System State [restoring]** [float]
The score to give when the state is restoring
***Node File System State [corrupt_should_be_good]** [float]
The score to give when the state should be good, but is corrupt
***Node File System State [corrupt_should_be_repairing]** [float]
The score to give when the state should be repairing, but is corrupt
***Node File System State [corrupt_should_be_restoring]** [float]
The score to give when the state should be restoring, but is corrupt
***Node File System State [corrupt_should_be_destroyed]** [float]
The score to give when the state should be destroyed, but is corrupt
***Node File System State [corrupt]** [float]
The score to give when the state is corrupt
***Node File System State [destroyed_should_be_good]** [float]
The score to give when the state should be good, but is destroyed
***Node File System State [destroyed_should_be_repairing]** [float]
The score to give when the state should be repairing, but is destroyed
***Node File System State [destroyed_should_be_restoring]** [float]
The score to give when the state should be restoring, but is destroyed
***Node File System State [destroyed_should_be_corrupt]** [float]
The score to give when the state should be corrupt, but is destroyed
***Node File System State [destroyed]** [float]
The score to give when the state is destroyed
***Node File System State [scanning]** [float]
The score to give when the state is scanning
***IER Status [red_ier_running]** [float]
The score to give when a red agent IER is permitted to run
***IER Status [green_ier_blocked]** [float]
The score to give when a green agent IER is prevented from running
**Patching / Reset Durations**
***os_patching_duration** [int]
The number of steps to take when patching an Operating System
***node_reset_duration** [int]
The number of steps to take when resetting a node's hardware state
***service_patching_duration** [int]
The number of steps to take when patching a service
***file_system_repairing_limit** [int]:
The number of steps to take when repairing the file system
***file_system_restoring_limit** [int]
The number of steps to take when restoring the file system
***file_system_scanning_limit** [int]
The number of steps to take when scanning the file system
***deterministic** [bool]
Set to true if the agent evaluation should be deterministic. Default is ``False``
***seed** [int]
Seed used in the randomisation in agent training. Default is ``None``
The Lay Down Config
*******************
The lay down config file consists of the following attributes:
***itemType: STEPS** [int]
***item_type: PORTS** [int]
Provides a list of ports modelled in this session
***item_type: SERVICES** [freetext]
Provides a list of services modelled in this session
***item_type: NODE**
Defines a node included in the system laydown being simulated. It should consist of the following attributes:
* **id** [int]: Unique ID for this YAML item
***name** [freetext]: Human-readable name of the component
***node_class** [enum]: Relates to the base type of the node. Can be SERVICE, ACTIVE or PASSIVE. PASSIVE nodes do not have an operating system or services. ACTIVE nodes have an operating system, but no services. SERVICE nodes have both an operating system and one or more services
***node_type** [enum]: Relates to the component type. Can be one of CCTV, SWITCH, COMPUTER, LINK, MONITOR, PRINTER, LOP, RTU, ACTUATOR or SERVER
***priority** [enum]: Provides a priority for each node. Can be one of P1, P2, P3, P4 or P5 (which P1 being the highest)
***hardware_state** [enum]: The initial hardware state of the node. Can be one of ON, OFF or RESETTING
***ip_address** [IP address]: The IP address of the component in format xxx.xxx.xxx.xxx
***software_state** [enum]: The intial state of the node operating system. Can be GOOD, PATCHING or COMPROMISED
***file_system_state** [enum]: The initial state of the node file system. Can be GOOD, CORRUPT, DESTROYED, REPAIRING or RESTORING
***services**: For each service associated with the node:
***name** [freetext]: Free-text name of the service, but must match one of the services defined for the system in the services list
***port** [int]: Integer value of the port related to this service, but must match one of the ports defined for the system in the ports list
***state** [enum]: The initial state of the service. Can be one of GOOD, PATCHING, COMPROMISED or OVERWHELMED
***item_type: LINK**
Defines a link included in the system laydown being simulated. It should consist of the following attributes:
* **id** [int]: Unique ID for this YAML item
***name** [freetext]: Human-readable name of the component
***bandwidth** [int]: The bandwidth (in bits/s) of the link
***source** [int]: The ID of the source node
***destination** [int]: The ID of the destination node
***item_type: GREEN_IER**
Defines a green agent Information Exchange Requirement (IER). It should consist of:
* **id** [int]: Unique ID for this YAML item
***start_step** [int]: The start step (in the episode) for this IER to begin
***end_step** [int]: The end step (in the episode) for this IER to finish
***load** [int]: The load (in bits/s) for this IER to apply to links
***protocol** [freetext]: The protocol to apply to the links. This must match a value in the services list
***port** [int]: The port that the protocol is running on. This must match a value in the ports list
***source** [int]: The ID of the source node
***destination** [int]: The ID of the destination node
***mission_criticality** [enum]: The mission criticality of this IER (with 5 being highest, 1 lowest)
***item_type: RED_IER**
Defines a red agent Information Exchange Requirement (IER). It should consist of:
* **id** [int]: Unique ID for this YAML item
***start_step** [int]: The start step (in the episode) for this IER to begin
***end_step** [int]: The end step (in the episode) for this IER to finish
***load** [int]: The load (in bits/s) for this IER to apply to links
***protocol** [freetext]: The protocol to apply to the links. This must match a value in the services list
***port** [int]: The port that the protocol is running on. This must match a value in the ports list
***source** [int]: The ID of the source node
***destination** [int]: The ID of the destination node
***mission_criticality** [enum]: Not currently used. Default to 0
***item_type: GREEN_POL**
Defines a green agent pattern-of-life instruction. It should consist of:
* **id** [int]: Unique ID for this YAML item
***start_step** [int]: The start step (in the episode) for this PoL to begin
***end_step** [int]: Not currently used. Default to same as start step
***nodeId** [int]: The ID of the node to apply the PoL to
***type** [enum]: The type of PoL to apply. Can be one of OPERATING, OS or SERVICE
***protocol** [freetext]: The protocol to be affected if SERVICE type is chosen. Must match a value in the services list
***state** [enuum]: The state to apply to the node (which represents the PoL change). Can be one of ON, OFF or RESETTING (for node state) or GOOD, PATCHING or COMPROMISED (for Software State) or GOOD, PATCHING, COMPROMISED or OVERWHELMED (for service state)
***item_type: RED_POL**
Defines a red agent pattern-of-life instruction. It should consist of:
* **id** [int]: Unique ID for this YAML item
***start_step** [int]: The start step (in the episode) for this PoL to begin
***end_step** [int]: Not currently used. Default to same as start step
***targetNodeId** [int]: The ID of the node to apply the PoL to
***initiator** [enum]: What initiates the PoL. Can be DIRECT, IER or SERVICE
***type** [enum]: The type of PoL to apply. Can be one of OPERATING, OS or SERVICE
***protocol** [freetext]: The protocol to be affected if SERVICE type is chosen. Must match a value in the services list
***state** [enum]: The state to apply to the node (which represents the PoL change). Can be one of ON, OFF or RESETTING (for node state) or GOOD, PATCHING or COMPROMISED (for Software State) or GOOD, PATCHING, COMPROMISED or OVERWHELMED (for service state) or GOOD, CORRUPT, DESTROYED, REPAIRING or RESTORING (for file system state)
***sourceNodeId** [int] The ID of the source node containing the service to check (used for SERVICE initiator)
***sourceNodeService** [freetext]: The service on the source node to check (used for SERVICE initiator). Must match a value in the services list for this node
***sourceNodeServiceState** [enum]: The state of the source node service to check (used for SERVICE initiator). Can be one of GOOD, PATCHING, COMPROMISED or OVERWHELMED
***item_type: ACL_RULE**
Defines an initial Access Control List (ACL) rule. It should consist of:
* **id** [int]: Unique ID for this YAML item
***permission** [enum]: Defines either an allow or deny rule. Value must be either DENY or ALLOW
***source** [IP address]: Defines the source IP address for the rule in xxx.xxx.xxx.xxx format
***destination** [IP address]: Defines the destination IP address for the rule in xxx.xxx.xxx.xxx format
***protocol** [freetext]: Defines the protocol for the rule. Must match a value in the services list
***port** [int]: Defines the port for the rule. Must match a value in the ports list
***position** [int]: Defines where to place the ACL rule in the list. Lower index or (higher up in the list) means they are checked first. Index starts at 0 (Python indexes).
PrimAITE allows for the configuration to be varied each episode. This is done by specifying a configuration folder instead of a single file. A full explanation is provided in the notebook `Using-Episode-Schedules.ipynb`. Please find the notebook in the user notebooks directory.
Agents can be scripted (deterministic and stochastic), or controlled by a reinforcement learning algorithm. Not to be confused with an RL agent, the term agent here is used to refer to an entity that sends requests to the simulated network. In this part of the config, each agent's action space, observation space, and reward function can be defined. All three are defined in a modular way.
``agents`` hierarchy
--------------------
..code-block::yaml
agents:
- ref:red_agent_example
...
- ref:blue_agent_example
...
- 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
agent_settings:
start_settings:
start_step:5
frequency:4
variance:3
flatten_obs:False
``ref``
-------
The reference to be used for the given agent.
``team``
--------
Specifies if the agent is malicious (``RED``), benign (``GREEN``), or defensive (``BLUE``). Currently this value is not used for anything other than for human readability in the configuration file.
``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.
Available agent types:
-``ProbabilisticAgent``
-``ProxyAgent``
-``RedDatabaseCorruptingAgent``
``observation_space``
---------------------
Defines the observation space of the agent.
``type``
^^^^^^^^
selects which python class from the :py:mod:`primaite.game.agent.observation` module is used for the overall observation structure.
``options``
^^^^^^^^^^^
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.
*``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.
For more information see :py:mod:`primaite.game.agent.observations`
``action_space``
----------------
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``
^^^^^^^^^^^^^^
Restricts the possible combinations of action type / action parameter values to reduce the overall size of the action space. By default, every possible combination of actions and parameters will be assigned an integer for the agent's ``MultiDiscrete`` action space. Instead, the ``action_map`` allows you to list the actions corresponding to each integer in the ``MultiDiscrete`` space.
This is Optional.
``options``
^^^^^^^^^^^
Options that apply to all action components. These are optional.
*``nodes``: list the nodes that the agent can act on, the order of this list defines the mapping between nodes and ``node_id`` integers.
*``max_folders_per_node``, ``max_files_per_folder``, ``max_services_per_node``, ``max_nics_per_node``, ``max_acl_rules`` all are used to define the size of the action space.
For more information see :py:mod:`primaite.game.agent.actions`
``reward_function``
-------------------
Similar to action space, this is defined as a list of components from the :py:mod:`primaite.game.agent.rewards` module.
``reward_components``
^^^^^^^^^^^^^^^^^^^^^
A list of reward types from :py:mod:`primaite.game.agent.rewards.RewardFunction.rew_class_identifiers`
e.g.
..code-block::yaml
reward_components:
- type:DUMMY
- type:DATABASE_FILE_INTEGRITY
``agent_settings``
------------------
Settings passed to the agent during initialisation. Determines how the agent will behave during training.
e.g.
..code-block::yaml
agent_settings:
start_settings:
start_step:25
frequency:20
variance:5
``start_step``
^^^^^^^^^^^^^^
Optional. Default value is ``5``.
The timestep where the agent begins performing actions.
``frequency``
^^^^^^^^^^^^^
Optional. Default value is ``5``.
The number of timesteps the agent will wait before performing another action.
``variance``
^^^^^^^^^^^^
Optional. Default value is ``0``.
The amount of timesteps that the frequency can randomly change.
``flatten_obs``
---------------
If ``True``, gymnasium flattening will be performed on the observation space before sending to the agent. Set this to ``True`` if your agent does not support nested observation spaces.
This section defines high-level settings that apply across the game, currently it's used to help shape the action and observation spaces by restricting which ports and internet protocols should be considered. Here, users can also set the maximum number of steps in an episode.
``game`` hierarchy
------------------
..code-block::yaml
game:
max_episode_length:256
ports:
- ARP
- DNS
- HTTP
- POSTGRES_SERVER
protocols:
- ICMP
- TCP
- UDP
thresholds:
nmne:
high:10
medium:5
low:0
``max_episode_length``
----------------------
Optional. Default value is ``256``.
The maximum number of episodes a Reinforcement Learning agent(s) can be trained for.
``ports``
---------
A list of ports that the Reinforcement Learning agent(s) are able to see in the observation space.
See :ref:`List of Ports <List of Ports>` for a list of ports.
``protocols``
-------------
A list of protocols that the Reinforcement Learning agent(s) are able to see in the observation space.
See :ref:`List of IPProtocols <List of IPProtocols>` for a list of protocols.
``thresholds``
--------------
These are used to determine the thresholds of high, medium and low categories for counted observation occurrences.
This section configures how PrimAITE saves data during simulation and training.
``io_settings`` hierarchy
-------------------------
..code-block::yaml
io_settings:
# save_logs: True
save_agent_actions:True
save_step_metadata:False
save_pcap_logs:False
save_sys_logs:False
write_sys_log_to_terminal:False
sys_log_level:WARNING
``save_logs``
-------------
*currently unused*.
``save_agent_actions``
----------------------
Optional. Default value is ``True``.
If ``True``, this will create a JSON file each episode detailing every agent's action in each step of that episode, formatted according to the CAOS format. This includes scripted, RL, and red agents.
``save_step_metadata``
----------------------
Optional. Default value is ``False``.
If ``True``, The RL agent(s) actions, environment states and other data will be saved at every single step.
``save_pcap_logs``
------------------
Optional. Default value is ``False``.
If ``True``, then the pcap files which contain all network traffic during the simulation will be saved.
``save_sys_logs``
-----------------
Optional. Default value is ``False``.
If ``True``, then the log files which contain all node actions during the simulation will be saved.
``write_sys_log_to_terminal``
-----------------------------
Optional. Default value is ``False``.
If ``True``, PrimAITE will print sys log to the terminal.
``sys_log_level``
-------------
Optional. Default value is ``WARNING``.
The level of logging that should be visible in the sys logs or the logs output to the terminal.
``save_sys_logs`` or ``write_sys_log_to_terminal`` has to be set to ``True`` for this setting to be used.
Available options are:
-``DEBUG``: Debug level items and the items below
-``INFO``: Info level items and the items below
-``WARNING``: Warning level items and the items below
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.
At the top level of the network are ``nodes`` and ``links``.
e.g.
..code-block::yaml
simulation:
network:
nodes:
...
links:
...
``nodes``
---------
This is where the list of nodes are defined. Some items will differ according to the node type, however, there will be common items such as a node's reference (which is used by the agent), the node's ``type`` and ``hostname``
To see the configuration for these nodes, refer to the following:
..toctree::
:maxdepth:1
:glob:
simulation/nodes/computer
simulation/nodes/firewall
simulation/nodes/router
simulation/nodes/server
simulation/nodes/switch
simulation/nodes/wireless_router
simulation/nodes/network_examples
``links``
---------
This is where the links between the nodes are formed.
e.g.
In order to recreate the network below, we will need to create 2 links:
- a link from computer_1 to the switch
- a link from computer_2 to the switch
..image:: ../../_static/switched_p2p_network.png
:width:500
:align:center
this results in:
..code-block::yaml
links:
- endpoint_a_hostname:computer_1
endpoint_a_port:1# port 1 on computer_1
endpoint_b_hostname:switch
endpoint_b_port:1# port 1 on switch
bandwidth:100
- endpoint_a_hostname:computer_2
endpoint_a_port:1# port 1 on computer_2
endpoint_b_hostname:switch
endpoint_b_port:2# port 2 on switch
bandwidth:100
``ref``
^^^^^^^
The human readable name for the link. Not used in code, however is useful for a human to understand what the link is for.
``endpoint_a_hostname``
^^^^^^^^^^^^^^^^^^^^^^^
The ``hostname`` of the node which must be connected.
``endpoint_a_port``
^^^^^^^^^^^^^^^^^^^
The port on ``endpoint_a_hostname`` which is to be connected to ``endpoint_b_port``.
This accepts an integer value e.g. if port 1 is to be connected, the configuration should be ``endpoint_a_port: 1``
``endpoint_b_hostname``
^^^^^^^^^^^^^^^^^^^^^^^
The ``hostname`` of the node which must be connected.
``endpoint_b_port``
^^^^^^^^^^^^^^^^^^^
The port on ``endpoint_b_hostname`` which is to be connected to ``endpoint_a_port``.
This accepts an integer value e.g. if port 1 is to be connected, the configuration should be ``endpoint_b_port: 1``
``bandwidth``
This is an integer value specifying the allowed bandwidth across the connection. Units are in Mbps.
The IP address that the |NODE| will use as the default gateway. Typically, this is the IP address of the closest router that the |NODE| is connected to.
A list of routes which tells the |NODE| where to forward the packet to depending on the target IP address.
e.g.
..code-block::yaml
nodes:
- ref:node
...
routes:
- address:192.168.0.10
subnet_mask:255.255.255.0
next_hop_ip_address:192.168.1.1
metric:0
``address``
"""""""""""
The target IP address for the route. If the packet destination IP address matches this, the |NODE| will route the packet according to the ``next_hop_ip_address``.
This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``.
``subnet_mask``
"""""""""""""""
Optional. Default value is ``255.255.255.0``.
The subnet mask setting for the route.
``next_hop_ip_address``
"""""""""""""""""""""""
The IP address of the next hop IP address that the packet will follow if the address matches the packet's destination IP address.
This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``.
``metric``
""""""""""
Optional. Default value is ``0``. This value accepts floats.
The cost or distance of a route. The higher the value, the more cost or distance is attributed to the route.
A basic representation of a network firewall within the simulation.
The firewall is similar to how :ref:`Router <router_configuration>` works, with the difference being how firewall has specific ACL rules for inbound and outbound traffic as well as firewall being limited to 3 ports.
See :py:mod:`primaite.simulator.network.hardware.nodes.network.firewall.Firewall`
example firewall
----------------
..code-block::yaml
simulation:
network:
nodes:
- ref:firewall
hostname:firewall
type:firewall
start_up_duration:0
shut_down_duration:0
ports:
external_port:# port 1
ip_address:192.168.20.1
subnet_mask:255.255.255.0
internal_port:# port 2
ip_address:192.168.1.2
subnet_mask:255.255.255.0
dmz_port:# port 3
ip_address:192.168.10.1
subnet_mask:255.255.255.0
acl:
internal_inbound_acl:
...
internal_outbound_acl:
...
dmz_inbound_acl:
...
dmz_outbound_acl:
...
external_inbound_acl:
...
external_outbound_acl:
...
routes:
...
..include:: common/common_node_attributes.rst
..include:: common/node_type_list.rst
``ports``
---------
The firewall node only has 3 ports. These specifically are:
-``external_port`` (port 1)
-``internal_port`` (port 2)
-``dmz_port`` (port 3) (can be optional)
The ports should be defined with an ip address and subnet mask e.g.
..code-block::yaml
nodes:
- ref:firewall
...
ports:
external_port:# port 1
ip_address:192.168.20.1
subnet_mask:255.255.255.0
internal_port:# port 2
ip_address:192.168.1.2
subnet_mask:255.255.255.0
dmz_port:# port 3
ip_address:192.168.10.1
subnet_mask:255.255.255.0
``ip_address``
""""""""""""""
The IP address for the given port. This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``.
``subnet_mask``
"""""""""""""""
Optional. Default value is ``255.255.255.0``.
The subnet mask setting for the port.
``acl``
-------
There are 6 ACLs that can be defined for a firewall
-``internal_inbound_acl`` for traffic going towards the internal network
-``internal_outbound_acl`` for traffic coming from the internal network
-``dmz_inbound_acl`` for traffic going towards the dmz network
-``dmz_outbound_acl`` for traffic coming from the dmz network
-``external_inbound_acl`` for traffic coming from the external network
-``external_outbound_acl`` for traffic going towards the external network
..image:: ../../../../_static/firewall_acl.png
:width:500
:align:center
By default, ``external_inbound_acl`` and ``external_outbound_acl`` will permit any traffic through.
``internal_inbound_acl``, ``internal_outbound_acl``, ``dmz_inbound_acl`` and ``dmz_outbound_acl`` will deny any traffic by default, so must be configured to allow defined ``src_port`` and ``dst_port`` or ``protocol``.
See :py:mod:`primaite.simulator.network.hardware.nodes.network.router.AccessControlList`
See :ref:`List of Ports <List of Ports>` for a list of ports.
``internal_inbound_acl``
""""""""""""""""""""""""
ACL rules for packets that have a destination IP address in what is considered the internal network.
example:
..code-block::yaml
nodes:
- ref:firewall
...
acl:
internal_inbound_acl:
21:# position 21 on ACL list
action:PERMIT # allow packets that
src_port:POSTGRES_SERVER # are emitted from the POSTGRES_SERVER port
dst_port:POSTGRES_SERVER # are going towards an POSTGRES_SERVER port
22:# position 22 on ACL list
action:PERMIT # allow packets that
src_port:ARP # are emitted from the ARP port
dst_port:ARP # are going towards an ARP port
23:# position 23 on ACL list
action:PERMIT # allow packets that
protocol:ICMP # are ICMP
``internal_outbound_acl``
"""""""""""""""""""""""""
ACL rules for packets that have a source IP address in what is considered the internal network and is going towards the DMZ network or the external network.
example:
..code-block::yaml
nodes:
- ref:firewall
...
acl:
internal_outbound_acl:
21:# position 21 on ACL list
action:PERMIT # allow packets that
src_port:POSTGRES_SERVER # are emitted from the POSTGRES_SERVER port
dst_port:POSTGRES_SERVER # are going towards an POSTGRES_SERVER port
22:# position 22 on ACL list
action:PERMIT # allow packets that
src_port:ARP # are emitted from the ARP port
dst_port:ARP # are going towards an ARP port
23:# position 23 on ACL list
action:PERMIT # allow packets that
protocol:ICMP # are ICMP
``dmz_inbound_acl``
"""""""""""""""""""
ACL rules for packets that have a destination IP address in what is considered the DMZ network.
example:
..code-block::yaml
nodes:
- ref:firewall
...
acl:
dmz_inbound_acl:
19:# position 19 on ACL list
action:PERMIT # allow packets that
src_port:POSTGRES_SERVER # are emitted from the POSTGRES_SERVER port
dst_port:POSTGRES_SERVER # are going towards an POSTGRES_SERVER port
20:# position 20 on ACL list
action:PERMIT # allow packets that
src_port:HTTP # are emitted from the HTTP port
dst_port:HTTP # are going towards an HTTP port
21:# position 21 on ACL list
action:PERMIT # allow packets that
src_port:HTTPS # are emitted from the HTTPS port
dst_port:HTTPS # are going towards an HTTPS port
22:# position 22 on ACL list
action:PERMIT # allow packets that
src_port:ARP # are emitted from the ARP port
dst_port:ARP # are going towards an ARP port
23:# position 23 on ACL list
action:PERMIT # allow packets that
protocol:ICMP # are ICMP
``dmz_outbound_acl``
""""""""""""""""""""
ACL rules for packets that have a source IP address in what is considered the DMZ network and is going towards the internal network or the external network.
example:
..code-block::yaml
nodes:
- ref:firewall
...
acl:
dmz_outbound_acl:
19:# position 19 on ACL list
action:PERMIT # allow packets that
src_port:POSTGRES_SERVER # are emitted from the POSTGRES_SERVER port
dst_port:POSTGRES_SERVER # are going towards an POSTGRES_SERVER port
20:# position 20 on ACL list
action:PERMIT # allow packets that
src_port:HTTP # are emitted from the HTTP port
dst_port:HTTP # are going towards an HTTP port
21:# position 21 on ACL list
action:PERMIT # allow packets that
src_port:HTTPS # are emitted from the HTTPS port
dst_port:HTTPS # are going towards an HTTPS port
22:# position 22 on ACL list
action:PERMIT # allow packets that
src_port:ARP # are emitted from the ARP port
dst_port:ARP # are going towards an ARP port
23:# position 23 on ACL list
action:PERMIT # allow packets that
protocol:ICMP # are ICMP
``external_inbound_acl``
""""""""""""""""""""""""
Optional. By default, this will allow any traffic through.
ACL rules for packets that have a destination IP address in what is considered the external network.
example:
..code-block::yaml
nodes:
- ref:firewall
...
acl:
external_inbound_acl:
21:# position 19 on ACL list
action:DENY # deny packets that
src_port:POSTGRES_SERVER # are emitted from the POSTGRES_SERVER port
dst_port:POSTGRES_SERVER # are going towards an POSTGRES_SERVER port
22:# position 22 on ACL list
action:PERMIT # allow packets that
src_port:ARP # are emitted from the ARP port
dst_port:ARP # are going towards an ARP port
23:# position 23 on ACL list
action:PERMIT # allow packets that
protocol:ICMP # are ICMP
``external_outbound_acl``
"""""""""""""""""""""""""
Optional. By default, this will allow any traffic through.
ACL rules for packets that have a source IP address in what is considered the external network and is going towards the DMZ network or the internal network.
A basic representation of a network router within the simulation.
See :py:mod:`primaite.simulator.network.hardware.nodes.network.router.Router`
example router
--------------
..code-block::yaml
simulation:
network:
nodes:
- ref:router_1
hostname:router_1
type:router
num_ports:5
ports:
...
acl:
...
..include:: common/common_node_attributes.rst
..include:: common/node_type_list.rst
``num_ports``
-------------
Optional. Default value is ``5``.
The number of ports the router will have.
``ports``
---------
Sets up the router's ports with an IP address and a subnet mask.
Example of setting ports for a router with 2 ports:
..code-block::yaml
nodes:
- ref:router_1
...
ports:
1:
ip_address:192.168.1.1
subnet_mask:255.255.255.0
2:
ip_address:192.168.10.1
subnet_mask:255.255.255.0
``ip_address``
""""""""""""""
The IP address for the given port. This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``.
``subnet_mask``
"""""""""""""""
Optional. Default value is ``255.255.255.0``.
The subnet mask setting for the port.
``acl``
-------
Sets up the ACL rules for the router.
e.g.
..code-block::yaml
nodes:
- ref:router_1
...
acl:
1:
action:PERMIT
src_port:ARP
dst_port:ARP
2:
action:PERMIT
protocol:ICMP
See :py:mod:`primaite.simulator.network.hardware.nodes.network.router.AccessControlList`
See :ref:`List of Ports <List of Ports>` for a list of ports.
``action``
""""""""""
Available options are
-``PERMIT`` : Allows the specified ``protocol`` or ``src_port`` and ``dst_port`` pairs
-``DENY`` : Blocks the specified ``protocol`` or ``src_port`` and ``dst_port`` pairs
``src_port``
""""""""""""
Is used alongside ``dst_port``. Specifies the port where a packet originates. Used by the ACL Rule to determine if a packet with a specific source port is allowed to pass through the network node.
``dst_port``
""""""""""""
Is used alongside ``src_port``. Specifies the port where a packet is destined to arrive. Used by the ACL Rule to determine if a packet with a specific destination port is allowed to pass through the network node.
``protocol``
""""""""""""
Specifies which protocols are allowed by the ACL Rule to pass through the network node.
See :ref:`List of IPProtocols <List of IPProtocols>` for a list of protocols.
If you are planning to implement custom RL agents into PrimAITE, you must use the project as a repository. If you install PrimAITE as a python package from wheel, custom agents are not supported.
PrimAITE has integration with Ray RLLib and StableBaselines3 agents. All agents interface with PrimAITE through an :py:class:`primaite.agents.agent.AgentSessionABC<Agent Session>` which provides Input/Output of agent savefiles, as well as capturing and plotting performance metrics during training and evaluation. If you wish to integrate a custom blue agent, it is recommended to create a subclass of the :py:class:`primaite.agents.agent.AgentSessionABC` and implement the ``__init__()``, ``_setup()``, ``_save_checkpoint()``, ``learn()``, ``evaluate()``, ``_get_latest_checkpoint``, ``load()``, and ``save()`` methods.
Below is a barebones example of a custom agent implementation:
# saves checkpoint if the episode count is not 0 and save_checkpoint flag was set to true
ifepisode_countandsave_checkpoint:
...
# your code to save checkpoint goes here.
# The path should start with self.checkpoints_path and include the episode number.
deflearn(self):
...
# call your agent's learning function here.
super().learn()# this will finalise learning and output session metadata
self.save()
defevaluate(self):
...
# call your agent's evaluation function here.
self._env.close()
super().evaluate()
def_get_latest_checkpoint(self):
...
# Load an agent from file.
@classmethod
defload(cls,path):
...
# Create a CustomAgent object which loads model weights from file.
defsave(self):
...
# Call your agent's function that saves it to a file
You will also need to modify :py:class:`primaite.primaite_session.PrimaiteSession<PrimaiteSession>` and :py:mod:`primaite.common.enums` to capture your new agent identifiers.
..code-block:: python
:emphasize-lines:17, 18
# src/primaite/common/enums.py
class AgentIdentifier(Enum):
"""The Red Agent algo/class."""
A2C = 1
"Advantage Actor Critic"
PPO = 2
"Proximal Policy Optimization"
HARDCODED = 3
"The Hardcoded agents"
DO_NOTHING = 4
"The DoNothing agents"
RANDOM = 5
"The RandomAgent"
DUMMY = 6
"The DummyAgent"
CUSTOM_AGENT = 7
"Your custom agent"
..code-block:: python
:emphasize-lines:3, 11, 12
# src/primaite_session.py
from primaite.agents.my_custom_agent import CustomAgent
# ...
def setup(self):
"""Performs the session setup."""
if self._training_config.agent_framework == AgentFramework.CUSTOM:
For an example of how to customise red agent behaviour in the Data Manipulation scenario, please refer to the notebook ``Data-Manipulation-Customising-Red-Agent.ipynb``.
RL environments are the objects that directly interface with RL libraries such as Stable-Baselines3 and Ray RLLib. The PrimAITE simulation is exposed via three different environment APIs:
* Gymnasium API - this is the standard interface that works with many RL libraries like SB3, Ray, Tianshou, etc. ``PrimaiteGymEnv`` adheres to the `Official Gymnasium documentation <https://gymnasium.farama.org/api/env/>`_.
* Ray Single agent API - For training a single Ray RLLib agent
* Ray MARL API - For training multi-agent systems with Ray RLLib. ``PrimaiteRayMARLEnv`` adheres to the `Official Ray documentation <https://docs.ray.io/en/latest/rllib/package_ref/env/multi_agent_env.html>`_.
There are Jupyter notebooks which demonstrate integration with each of these three environments. They are located in ``~/primaite/<VERSION>/notebooks/example_notebooks``.
There are a few example notebooks included which help with the understanding of PrimAITE's capabilities.
The PrimAITE documentation includes a pre executed example of notebooks. See :ref:`Executed Notebooks`.
In order to run the notebooks interactively, :ref:`install PrimAITE <getting-started>` and follow these steps:
Running Jupyter Notebooks
-------------------------
1. Navigate to the PrimAITE directory
..code-block:: bash
:caption:Unix
cd ~/primaite/{VERSION}
..code-block:: powershell
:caption:Windows (Powershell)
cd ~\primaite\{VERSION}
2. Run jupyter notebook (the python environment to which you installed PrimAITE must be active)
..code-block:: bash
:caption:Unix
jupyter notebook
..code-block:: powershell
:caption:Windows (Powershell)
jupyter notebook
3. Opening the jupyter webpage (optional)
The default web browser may automatically open the webpage. However, if that is not the case, click the link shown in your command prompt output. It should look like this: ``http://localhost:8888/?token=0123456798abc0123456789abc``
4. Navigate to the list of notebooks
The example notebooks are located in ``notebooks/example_notebooks/``. The file system shown in the jupyter webpage is relative to the location in which the ``jupyter notebook`` command was used.
Running Jupyter Notebooks via VSCode
------------------------------------
It is also possible to view the Jupyter notebooks within VSCode.
The best place to start is by opening a notebook file (.ipynb) in VSCode. If using VSCode to view a notebook for the first time, follow the steps below.
Installing extensions
"""""""""""""""""""""
VSCode may need some extensions to be installed if not already done.
To do this, press the "Select Kernel" button on the top right.
This should open a dialog which has the option to install python and jupyter extensions.
The Primaite codebase consists of two main modules:
*``simulator``: The simulation logic including the network topology, the network state, and behaviour of various hardware and software classes.
*``game``: The agent-training infrastructure which helps reinforcement learning agents interface with the simulation. This includes the observation, action, and rewards, for RL agents, but also scripted deterministic agents. The game layer orchestrates all the interactions between modules.
The simulator and game layer communicate using the PrimAITE State API and the PrimAITE Request API.
The game layer is responsible for managing agents and getting them to interface with the simulator correctly. It consists of several components:
Agents
======
All agents inherit from the :py:class:`primaite.game.agent.interface.AbstractAgent` class, which mandates that they have an ObservationManager, ActionManager, and RewardManager. The agent behaviour depends on the type of agent, but there are two main types:
* RL agents action during each step is decided by an appropriate RL algorithm. The agent within PrimAITE just acts to format and forward actions decided by an RL policy.
* Deterministic agents perform all of their decision making within the PrimAITE game layer. They typically have a scripted policy which always performs the same action or a rule-based policy which performs actions based on the current state of the simulation. They can have a stochastic element, and their seed is settable.
Observations
============
An agent's observations are managed by the ``ObservationManager`` class. It generates observations based on the current simulation state dictionary. It also provides the observation space during initial setup. The data is formatted so it's compatible with ``Gymnasium.spaces``. Observation spaces are composed of one or more components which are defined by the ``AbstractObservation`` base class.
Actions
=======
An agent's actions are managed by the ``ActionManager``. It converts actions selected by agents (which are typically integers chosen from a ``gymnasium.spaces.Discrete`` space) into simulation-friendly requests. It also provides the action space during initial setup. Action spaces are composed of one or more components which are defined by the ``AbstractAction`` base class.
Rewards
=======
An agent's reward function is managed by the ``RewardManager``. It calculates rewards based on the simulation state (in a way similar to observations). Rewards can be defined as a weighted sum of small reward components. For example, an agents reward can be based on the uptime of a database service plus the loss rate of packets between clients and a web server.
Reward Components
-----------------
Currently implemented are reward components tailored to the data manipulation scenario. View the full API and description of how they work here: :py:module:`primaite.game.agent.reward`.
Reward Sharing
--------------
An agent's reward can be based on rewards of other agents. This is particularly useful for modelling a situation where the blue agent's job is to protect the ability of green agents to perform their pattern-of-life. This can be configured in the YAML file this way:
```yaml
green_agent_1: # this agent sometimes tries to access the webpage, and sometimes the database
# actions, observations, and agent settings go here
reward_function:
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
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
weight: 0.05
options:
node_hostname: client_2
blue_agent:
# actions, observations, and agent settings go here
reward_function:
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
weight: 0.40
options:
node_hostname: database_server
folder_name: database
file_name: database.db
# The green's reward is added onto the blue's reward.
- type: SHARED_REWARD
weight: 1.0
options:
agent_name: client_2_green_user
```
When defining agent reward sharing, users must be careful to avoid circular references, as that would lead to an infinite calculation loop. PrimAITE will prevent circular dependencies and provide a helpful error message if they are detected in the yaml.
In order to get **PrimAITE** installed, you will need to have a python version between 3.8 and 3.10 installed. If you don't already have it, this is how to install it:
In order to get **PrimAITE** installed, you will need Python, venv, and pip. If you don't already have them, this is how to install it:
A defensive agent that protects the network from Red Agent attacks to minimise disruption to green agents and protect data.
Information Exchange Requirement (IER)
Simulates network traffic by sending data from one network node to another via links for a specified amount of time. IERs can be part of green agent behaviour or red agent behaviour. PrimAITE can be configured to apply a penalty for green agents' IERs being blocked and a reward for red agents' IERs being blocked.
Pattern-of-Life (PoL)
PoLs allow agents to change the current hardware, OS, file system, or service statuses of nodes during the course of an episode. For example, a green agent may restart a server node to represent scheduled maintainance. A red agent's Pattern-of-Life can be used to attack nodes by changing their states to CORRUPTED or COMPROMISED.
Reward
The reward is a single number used by the blue agent to understand whether it's performing well or poorly. RL agents change their behaviour in an attempt to increase the expected reward each episode. The reward is generated based on the current states of the environment / :term:`reference environment` and is impacted positively by things like green IERS running successfully and negatively by things like nodes being compromised.
The reward is a single number used by the blue agent to understand whether it's performing well or poorly. RL agents change their behaviour in an attempt to increase the expected reward each episode. The reward is generated based on the current states of the environment and is impacted positively by things like green PoL running successfully and negatively by things like nodes being compromised.
Observation
An observation is a representation of the current state of the environment that is given to the learning agent so it can decide on which action to perform. If the environment is 'fully observable', the observation contains information about every possible aspect of the environment. More commonly, the environment is 'partially observable' which means the learning agent has to make decisions without knowing every detail of the current environment state.
@@ -65,17 +62,11 @@ Glossary
Episode
When an episode starts, the network simulation is reset to an initial state. The agents take actions on each step of the episode until it reaches a terminal state, which usually happens after a predetermined number of steps. After the terminal state is reached, a new episode starts and the RL agent has another opportunity to protect the network.
Reference environment
While the network simulation is unfolding, a parallel simulation takes place which is identical to the main one except that blue and red agent actions are not applied. This reference environment essentially shows what would be happening to the network if there had been no cyberattack or defense. The reference environment is used to calculate rewards.
Transaction
PrimAITE records the decisions of the learning agent by saving its observation, action, and reward at every time step. During each session, this data is saved to disk to allow for full inspection.
Laydown
The laydown is a file which defines the training scenario. It contains the network topology, firewall rules, services, protocols, and details about green and red agent behaviours.
Gym
PrimAITE uses the Gym reinforcement learning framework API to create a training environment and interface with RL agents. Gym defines a common way of creating observations, actions, and rewards.
Gymnasium
PrimAITE uses the Gymnasium reinforcement learning framework API to create a training environment and interface with RL agents. Gymnasium defines a common way of creating observations, actions, and rewards.
User app home
PrimAITE supports upgrading software version while retaining user data. The user data directory is where configs, notebooks, and results are stored, this location is `~/primaite<version>` on linux/darwin and `C:\Users\<username>\primaite\<version>` on Windows.
PrimAITE supports upgrading software version while retaining user data. The user data directory is where configs, notebooks, and results are stored, this location is `~/primaite<version>/` on linux/darwin and `C:\\Users\\<username>\\primaite<version>` on Windows.
Like before, you can install primaite from the repository by running ``pip install -e .``. But, there is now an additional setup step which does several things, like setting up user directories, copy default configs and notebooks, etc. Once you have installed PrimAITE to your virtual environment, run this command to finalise setup.
..code-block::bash
primaite setup
**2. Running a training session**
In version 1.2 of PrimAITE, the main entry point for training or evaluating agents was the ``src/primaite/main.py`` file. v2.0.0 introduced managed 'sessions' which are responsible for reading configuration files, performing training, and writing outputs.
``main.py`` file still runs a training session but it now uses the new `PrimaiteSession`, and it now requires you to provide the path to your config files.
In version 1.2, training configs and laydown configs were all stored in the project repository under ``src/primaite/config``. Version 2.0.0 introduced user data directories, and now when you install and setup PrimAITE, config files are stored in your user data location. On Linux/OSX, this is stored in ``~/primaite/2.0.0/config``. On Windows, this is stored in ``C:\Users\<your username>\primaite\configs``. Upon first setup, the configs folder is populated with some default yaml files. It is recommended that you store all your custom configuration files here.
**4. Contents of configs**
Some things that were previously part of the laydown config are now part of the traning config.
* Actions
If you have custom configs which use these, you will need to adapt them by moving the configuration from the laydown config to the training config.
Also, there are new configurable items in the training config:
* Observations
* Agent framework
* Agent
* Deep learning framework
* random red agents
* seed
* deterministic
* hard coded agent view
Each of these items have default values which are designed so that PrimAITE has the same behaviour as it did in 1.2.0, so you do not have to specify them.
ACL Rules in laydown configs have a new required parameter: ``position``. The lower the position, the higher up in the ACL table the rule will placed. If you have custom laydowns, you will need to go through them and add a position to each ACL_RULE.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.