diff --git a/docs/source/configuration/simulation.rst b/docs/source/configuration/simulation.rst index f24cc41d..89c1669b 100644 --- a/docs/source/configuration/simulation.rst +++ b/docs/source/configuration/simulation.rst @@ -29,12 +29,9 @@ To see the configuration for these nodes, refer to the following: .. toctree:: :maxdepth: 1 + :glob: - simulation/nodes/computer.rst - simulation/nodes/firewall.rst - simulation/nodes/router.rst - simulation/nodes/server.rst - simulation/nodes/switch.rst + simulation/nodes/* ``links`` --------- diff --git a/docs/source/simulation_components/network/network.rst b/docs/source/simulation_components/network/network.rst index 533a15f2..36e8ee48 100644 --- a/docs/source/simulation_components/network/network.rst +++ b/docs/source/simulation_components/network/network.rst @@ -30,11 +30,11 @@ we'll use the following Network that has a client, server, two switches, and a r .. code-block:: python from primaite.simulator.network.container import Network - from primaite.simulator.network.hardware.base import NIC - from primaite.simulator.network.hardware.nodes.computer import Computer - from primaite.simulator.network.hardware.nodes.router import Router, ACLAction - from primaite.simulator.network.hardware.nodes.server import Server - from primaite.simulator.network.hardware.nodes.switch import Switch + from primaite.simulator.network.hardware.base import NetworkInterface + from primaite.simulator.network.hardware.nodes.host.computer import Computer + from primaite.simulator.network.hardware.nodes.network.router import Router, ACLAction + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.network.hardware.nodes.network.switch import Switch from primaite.simulator.network.transmission.network_layer import IPProtocol from primaite.simulator.network.transmission.transport_layer import Port diff --git a/docs/source/simulation_components/system/applications/data_manipulation_bot.rst b/docs/source/simulation_components/system/applications/data_manipulation_bot.rst index 8c326b56..209cdcbd 100644 --- a/docs/source/simulation_components/system/applications/data_manipulation_bot.rst +++ b/docs/source/simulation_components/system/applications/data_manipulation_bot.rst @@ -2,14 +2,15 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _DataManipulationBot: DataManipulationBot -=================== +################### -The ``DataManipulationBot`` class provides functionality to connect to a ``DatabaseService`` and execute malicious SQL statements. +The ``DataManipulationBot`` class provides functionality to connect to a :ref:`DatabaseService` and execute malicious SQL statements. Overview --------- +======== The bot is intended to simulate a malicious actor carrying out attacks like: @@ -28,7 +29,7 @@ The bot performs attacks in the following stages to simulate the real pattern of Each of these stages has a random, configurable probability of succeeding (by default 10%). The bot can also be configured to repeat the attack once complete. Usage ------ +===== - Create an instance and call ``configure`` to set: - Target database server IP @@ -41,16 +42,35 @@ The bot handles connecting, executing the statement, and disconnecting. In a simulation, the bot can be controlled by using ``DataManipulationAgent`` which calls ``run`` on the bot at configured timesteps. -Example -------- +Implementation +============== + +The bot extends :ref:`DatabaseClient` and leverages its connectivity. + +- Uses the Application base class for lifecycle management. +- Credentials, target IP and other options set via ``configure``. +- ``run`` handles connecting, executing statement, and disconnecting. +- SQL payload executed via ``query`` method. +- Results in malicious SQL being executed on remote database server. + + +Examples +======== + +Python +"""""" .. code-block:: python + from primaite.simulator.network.hardware.nodes.host.computer import Computer + from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState + from primaite.simulator.system.applications.red_applications.data_manipulation_bot import DataManipulationBot + client_1 = Computer( hostname="client_1", ip_address="192.168.10.21", subnet_mask="255.255.255.0", - default_gateway="192.168.10.1" + default_gateway="192.168.10.1", operating_state=NodeOperatingState.ON # initialise the computer in an ON state ) network.connect(endpoint_b=client_1.network_interface[1], endpoint_a=switch_2.network_interface[1]) @@ -62,13 +82,13 @@ Example This would connect to the database service at 192.168.1.14, authenticate, and execute the SQL statement to drop the 'users' table. Example with ``DataManipulationAgent`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +"""""""""""""""""""""""""""""""""""""" If not using the data manipulation bot manually, it needs to be used with a data manipulation agent. Below is an example section of configuration file for setting up a simulation with data manipulation bot and agent. .. code-block:: yaml - game_config: + game: # ... agents: - ref: data_manipulation_red_bot @@ -129,13 +149,51 @@ If not using the data manipulation bot manually, it needs to be used with a data payload: "DELETE" server_ip: 192.168.1.14 -Implementation --------------- +Configuration +============= -The bot extends ``DatabaseClient`` and leverages its connectivity. +.. include:: ../common/common_configuration.rst -- Uses the Application base class for lifecycle management. -- Credentials, target IP and other options set via ``configure``. -- ``run`` handles connecting, executing statement, and disconnecting. -- SQL payload executed via ``query`` method. -- Results in malicious SQL being executed on remote database server. +.. |SOFTWARE_NAME| replace:: DataManipulationBot +.. |SOFTWARE_NAME_BACKTICK| replace:: ``DataManipulationBot`` + +``server_ip`` +""""""""""""" + +IP address of the :ref:`DatabaseService` which the ``DataManipulationBot`` will try to attack. + +This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. + +``server_password`` +""""""""""""""""""" + +Optional. Default value is ``None``. + +The password that the ``DataManipulationBot`` will use to access the :ref:`DatabaseService`. + +``payload`` +""""""""""" + +Optional. Default value is ``DELETE``. + +The payload that the ``DataManipulationBot`` will send to the :ref:`DatabaseService`. + +See :ref:`Database Payload List` + +``port_scan_p_of_success`` +"""""""""""""""""""""""""" + +Optional. Default value is ``0.1``. + +The chance of the ``DataManipulationBot`` to succeed with a port scan (and therefore continue the attack). + +This must be a float value between ``0`` and ``1``. + +``data_manipulation_p_of_success`` +"""""""""""""""""""""""""""""""""" + +Optional. Default value is ``0.1``. + +The chance of the ``DataManipulationBot`` to succeed with a data manipulation attack. + +This must be a float value between ``0`` and ``1``. diff --git a/docs/source/simulation_components/system/applications/database_client.rst b/docs/source/simulation_components/system/applications/database_client.rst index 47690cb6..61d955f2 100644 --- a/docs/source/simulation_components/system/applications/database_client.rst +++ b/docs/source/simulation_components/system/applications/database_client.rst @@ -2,37 +2,111 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _DatabaseClient: DatabaseClient -=============== +############## -The DatabaseClient provides a client interface for connecting to the ``DatabaseService``. +The ``DatabaseClient`` provides a client interface for connecting to the :ref:`DatabaseService`. Key features -^^^^^^^^^^^^ +============ -- Connects to the ``DatabaseService`` via the ``SoftwareManager``. +- Connects to the :ref:`DatabaseService` via the ``SoftwareManager``. - Handles connecting and disconnecting. - Executes SQL queries and retrieves result sets. Usage -^^^^^ +===== - Initialise with server IP address and optional password. -- Connect to the ``DatabaseService`` with ``connect``. +- Connect to the :ref:`DatabaseService` with ``connect``. - Retrieve results in a dictionary. - Disconnect when finished. To create database backups: -- Configure the backup server on the ``DatabaseService`` by providing the Backup server ``IPv4Address`` with ``configure_backup`` +- Configure the backup server on the :ref:`DatabaseService` by providing the Backup server ``IPv4Address`` with ``configure_backup`` - Create a backup using ``backup_database``. This fails if the backup server is not configured. - Restore a backup using ``restore_backup``. By default, this uses the database created via ``backup_database``. Implementation -^^^^^^^^^^^^^^ +============== - Leverages ``SoftwareManager`` for sending payloads over the network. - Connect and disconnect methods manage sessions. - Payloads serialised as dictionaries for transmission. - Extends base Application class. + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from ipaddress import IPv4Address + + from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState + from primaite.simulator.network.hardware.nodes.host.computer import Computer + from primaite.simulator.system.applications.database_client import DatabaseClient + + client = Computer( + hostname="client", + ip_address="192.168.10.21", + subnet_mask="255.255.255.0", + default_gateway="192.168.10.1", + operating_state=NodeOperatingState.ON # initialise the computer in an ON state + ) + + # install DatabaseClient + client.software_manager.install(DatabaseClient) + + database_client: DatabaseClient = client.software_manager.software.get("DatabaseClient") + + # Configure the DatabaseClient + database_client.configure(server_ip_address=IPv4Address("192.168.0.1")) # address of the DatabaseService + database_client.run() + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_computer + hostname: example_computer + type: computer + ... + applications: + - ref: database_client + type: DatabaseClient + options: + db_server_ip: 192.168.0.1 + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: DatabaseClient +.. |SOFTWARE_NAME_BACKTICK| replace:: ``DatabaseClient`` + + +``db_server_ip`` +"""""""""""""""" + +IP address of the :ref:`DatabaseService` that the ``DatabaseClient`` will connect to + +This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. + +``server_password`` +""""""""""""""""""" + +Optional. Default value is ``None``. + +The password that the ``DatabaseClient`` will use to access the :ref:`DatabaseService`. diff --git a/docs/source/simulation_components/system/applications/dos_bot.rst b/docs/source/simulation_components/system/applications/dos_bot.rst index 6aa849a7..fcf3f207 100644 --- a/docs/source/simulation_components/system/applications/dos_bot.rst +++ b/docs/source/simulation_components/system/applications/dos_bot.rst @@ -2,7 +2,157 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK -DoSBot ------- +.. _DoSBot: -test +DoSBot +###### + +The ``DoSBot`` is an implementation of a Denial of Service attack within the PrimAITE simulation. This specifically simulates a `Slow Loris attack `. + +Key features +============ + +- Connects to the :ref:`DatabaseService` via the ``SoftwareManager``. +- Makes many connections to the :ref:`DatabaseService` which ends up using up the available connections. + +Usage +===== + +- Configure with target IP address and optional password. +- use ``run`` to run the application_loop of DoSBot to begin attacks +- DoSBot runs through different actions at each timestep + +Implementation +============== + +- Leverages :ref:`DatabaseClient` to create connections with :ref`DatabaseServer`. +- Extends base Application class. + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from ipaddress import IPv4Address + + from primaite.simulator.network.hardware.nodes.host.computer import Computer + from primaite.simulator.system.applications.red_applications.dos_bot import DoSBot + + # Create Computer + computer = Computer( + hostname="computer", + ip_address="192.168.1.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + computer.power_on() + + # Install DoSBot on computer + computer.software_manager.install(DoSBot) + dos_bot: DoSBot = computer.software_manager.software.get("DoSBot") + + # Configure the DoSBot + dos_bot.configure( + target_ip_address=IPv4Address("192.168.0.10"), + payload="SPOOF DATA", + repeat=False, + port_scan_p_of_success=0.8, + dos_intensity=1.0, + max_sessions=1000 + ) + + # run DoSBot + dos_bot.run() + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_computer + hostname: example_computer + type: computer + ... + applications: + - ref: dos_bot + type: DoSBot + options: + target_ip_address: 192.168.0.10 + payload: SPOOF DATA + repeat: False + port_scan_p_of_success: 0.8 + dos_intensity: 1.0 + max_sessions: 1000 + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: DoSBot +.. |SOFTWARE_NAME_BACKTICK| replace:: ``DoSBot`` + +``target_ip_address`` +""""""""""""""""""""" + +IP address of the :ref:`DatabaseService` which the ``DataManipulationBot`` will try to attack. + +This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. + +``target_port`` +""""""""""""""" + +Optional. Default value is ``5432``. + +Port of the target service. + +See :ref:`List of IPProtocols ` for a list of protocols. + +``payload`` +""""""""""" + +Optional. Default value is ``None``. + +The payload that the ``DoSBot`` sends as part of its attack. + +``repeat`` +"""""""""" + +Optional. Default value is ``False``. + +If ``True`` the ``DoSBot`` will maintain its attack. + +``port_scan_p_of_success`` +"""""""""""""""""""""""""" + +Optional. Default value is ``0.1``. + +The chance of the ``DoSBot`` to succeed with a port scan (and therefore continue the attack). + +This must be a float value between ``0`` and ``1``. + +``dos_intensity`` +""""""""""""""""" + +Optional. Default value is ``1.0``. + +The intensity of the Denial of Service attack. This is multiplied by the number of ``max_sessions``. + +This must be a float value between ``0`` and ``1``. + +``max_sessions`` +"""""""""""""""" + +Optional. Default value is ``1000``. + +The maximum number of sessions the ``DoSBot`` is able to make. + +This must be an integer value above equal to or greater than ``0``. diff --git a/docs/source/simulation_components/system/applications/web_browser.rst b/docs/source/simulation_components/system/applications/web_browser.rst index ee4e8b94..c46089ba 100644 --- a/docs/source/simulation_components/system/applications/web_browser.rst +++ b/docs/source/simulation_components/system/applications/web_browser.rst @@ -2,16 +2,17 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _WebBrowser: WebBrowser -========== +########## -The ``WebBrowser`` provides a client interface for connecting to the ``WebServer``. +The ``WebBrowser`` provides a client interface for connecting to the :ref:`WebServer`. Key features -^^^^^^^^^^^^ +============ -- Connects to the ``WebServer`` via the ``SoftwareManager``. +- Connects to the :ref:`WebServer` via the ``SoftwareManager``. - Simulates HTTP requests and HTTP packet transfer across a network - Allows the emulation of HTTP requests between client and server: - Automatically uses ``DNSClient`` to resolve domain names @@ -19,66 +20,92 @@ Key features - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the ``WebBrowser``. - Service runs on HTTP port 80 by default. (TODO: HTTPS) - Execute sending an HTTP GET request with ``get_webpage`` Implementation -^^^^^^^^^^^^^^ +============== - Leverages ``SoftwareManager`` for sending payloads over the network. - Provides easy interface for making HTTP requests between an HTTP client and server. - Extends base Service class. -Example Usage -------------- +Examples +======== -Dependencies -^^^^^^^^^^^^ +Python +"""""" + +The ``WebBrowser`` utilises :ref:`DNSClient` and :ref:`DNSServer` to resolve a URL. + +The :ref:`DNSClient` must be configured to use the :ref:`DNSServer`. The :ref:`DNSServer` should be configured to have the ``WebBrowser`` ``target_url`` within its ``domain_mapping``. .. code-block:: python - from primaite.simulator.network.container import Network - from primaite.simulator.network.hardware.nodes.computer import Computer - from primaite.simulator.network.hardware.nodes.server import Server + from primaite.simulator.network.hardware.nodes.host.computer import Computer from primaite.simulator.system.applications.web_browser import WebBrowser - from primaite.simulator.system.services.web_server.web_server_service import WebServer -Example peer to peer network -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + # Create Computer + computer = Computer( + hostname="computer", + ip_address="192.168.1.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + computer.power_on() -.. code-block:: python + # Install WebBrowser on computer + computer.software_manager.install(WebBrowser) + web_browser: WebBrowser = computer.software_manager.software.get("WebBrowser") + web_browser.run() - net = Network() + # configure the WebBrowser + web_browser.target_url = "arcd.com" - pc1 = Computer(hostname="pc1", ip_address="192.168.1.50", subnet_mask="255.255.255.0") - srv = Server(hostname="srv", ip_address="192.168.1.10", subnet_mask="255.255.255.0") - pc1.power_on() - srv.power_on() - net.connect(pc1.network_interface[1], srv.network_interface[1]) + # once DNS server is configured with the correct domain mapping + # this should work + web_browser.get_webpage() -Install the Web Server -^^^^^^^^^^^^^^^^^^^^^^ +Via Configuration +""""""""""""""""" -.. code-block:: python +.. code-block:: yaml - # web browser is automatically installed in computer nodes - # IRL this is usually included with an OS - client: WebBrowser = pc1.software_manager.software['WebBrowser'] + simulation: + network: + nodes: + - ref: example_computer + hostname: example_computer + type: computer + ... + applications: + - ref: web_browser + type: WebBrowser + options: + target_url: http://arcd.com/ - # install web server - srv.software_manager.install(WebServer) - webserv: WebServer = srv.software_manager.software['WebServer'] +Configuration +============= -Open the web page -^^^^^^^^^^^^^^^^^ +.. include:: ../common/common_configuration.rst -Using a domain name to connect to a website requires setting up DNS Servers. For this example, it is possible to use the IP address directly +.. |SOFTWARE_NAME| replace:: WebBrowser +.. |SOFTWARE_NAME_BACKTICK| replace:: ``WebBrowser`` -.. code-block:: python +``target_url`` +"""""""""""""" - # check that the get request succeeded - print(client.get_webpage("http://192.168.1.10")) # should be True +The URL that the ``WebBrowser`` will request when ``get_webpage`` is called without parameters. + +The URL can be in any format so long as the domain is within it e.g. + +The domain ``arcd.com`` can be matched by + +- http://arcd.com/ +- http://arcd.com/users/ +- arcd.com diff --git a/docs/source/simulation_components/system/common/common_configuration.rst b/docs/source/simulation_components/system/common/common_configuration.rst new file mode 100644 index 00000000..86991655 --- /dev/null +++ b/docs/source/simulation_components/system/common/common_configuration.rst @@ -0,0 +1,14 @@ +``ref`` +======= + +Human readable name used as reference for the |SOFTWARE_NAME_BACKTICK|. Not used in code. + +``type`` +======== + +The type of software that should be added. To add |SOFTWARE_NAME| this must be |SOFTWARE_NAME_BACKTICK|. + +``options`` +=========== + +The configuration options are the attributes that fall under the options for an application. diff --git a/docs/source/simulation_components/system/list_of_applications.rst b/docs/source/simulation_components/system/list_of_applications.rst index 9aac23de..0ba0c45c 100644 --- a/docs/source/simulation_components/system/list_of_applications.rst +++ b/docs/source/simulation_components/system/list_of_applications.rst @@ -1,11 +1,11 @@ .. toctree:: :maxdepth: 1 + :glob: - applications/data_manipulation_bot.rst - applications/database_client.rst - applications/dos_bot.rst - applications/web_browser.rst + applications/* More info :py:mod:`primaite.game.game.APPLICATION_TYPES_MAPPING` .. include:: list_of_system_applications.rst + +.. |SOFTWARE_TYPE| replace:: application diff --git a/docs/source/simulation_components/system/list_of_services.rst b/docs/source/simulation_components/system/list_of_services.rst index 07bc25ee..e24b26dc 100644 --- a/docs/source/simulation_components/system/list_of_services.rst +++ b/docs/source/simulation_components/system/list_of_services.rst @@ -1,15 +1,11 @@ .. toctree:: :maxdepth: 1 + :glob: - services/database_service.rst - services/dns_client.rst - services/dns_server.rst - services/ftp_client.rst - services/ftp_server.rst - services/ntp_client.rst - services/ntp_server.rst - services/web_server.rst + services/* More info :py:mod:`primaite.game.game.SERVICE_TYPES_MAPPING` .. include:: list_of_system_services.rst + +.. |SOFTWARE_TYPE| replace:: service diff --git a/docs/source/simulation_components/system/list_of_system_applications.rst b/docs/source/simulation_components/system/list_of_system_applications.rst index ca5a7457..fae0f5d4 100644 --- a/docs/source/simulation_components/system/list_of_system_applications.rst +++ b/docs/source/simulation_components/system/list_of_system_applications.rst @@ -11,9 +11,6 @@ The application may not be configured as needed, in which case, see the relevant The list of applications that are considered system software are: -.. toctree:: - :maxdepth: 1 - - applications/web_browser.rst +- ``WebBrowser`` More info :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.SYSTEM_SOFTWARE` diff --git a/docs/source/simulation_components/system/list_of_system_services.rst b/docs/source/simulation_components/system/list_of_system_services.rst index 657faa52..4ff6f245 100644 --- a/docs/source/simulation_components/system/list_of_system_services.rst +++ b/docs/source/simulation_components/system/list_of_system_services.rst @@ -11,11 +11,8 @@ The service may not be configured as needed, in which case, see the relevant ser The list of services that are considered system software are: -.. toctree:: - :maxdepth: 1 - - services/dns_client.rst - services/ftp_client.rst - services/ntp_client.rst +- ``DNSClient`` +- ``FTPClient`` +- ``NTPClient`` More info :py:mod:`primaite.simulator.network.hardware.nodes.host.host_node.SYSTEM_SOFTWARE` diff --git a/docs/source/simulation_components/system/services/database_service.rst b/docs/source/simulation_components/system/services/database_service.rst index a4591d15..30d6b3ba 100644 --- a/docs/source/simulation_components/system/services/database_service.rst +++ b/docs/source/simulation_components/system/services/database_service.rst @@ -2,13 +2,15 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _DatabaseService: + DatabaseService -=============== +############### The ``DatabaseService`` provides a SQL database server simulation by extending the base Service class. Key capabilities -^^^^^^^^^^^^^^^^ +================ - Creates a database file in the ``Node`` 's ``FileSystem`` upon creation. - Handles connecting clients by maintaining a dictionary of connections mapped to session IDs. @@ -18,16 +20,90 @@ Key capabilities - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the database service. - Clients connect, execute queries, and disconnect. - Service runs on TCP port 5432 by default. Implementation -^^^^^^^^^^^^^^ +============== - Creates the database file within the node's file system. - Manages client connections in a dictionary by session ID. - Processes SQL queries. - Returns results and status codes in a standard dictionary format. - Extends Service class for integration with ``SoftwareManager``. + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from ipaddress import IPv4Address + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.database.database_service import DatabaseService + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install DatabaseService on server + server.software_manager.install(DatabaseService) + db_service: DatabaseService = server.software_manager.software.get("DatabaseService") + db_service.start() + + # configure DatabaseService + db_service.configure_backup(IPv4Address("192.168.0.10")) + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: database_service + type: DatabaseService + options: + backup_server_ip: 192.168.0.10 + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: DatabaseService +.. |SOFTWARE_NAME_BACKTICK| replace:: ``DatabaseService`` + +``backup_server_ip`` +"""""""""""""""""""" + +Optional. Default value is ``None``. + +The IP Address of the backup server that the ``DatabaseService`` will use to create backups of the database. + +This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. + +``password`` +"""""""""""" + +Optional. Default value is ``None``. + +The password that needs to be provided by connecting clients in order to create a successful connection. diff --git a/docs/source/simulation_components/system/services/dns_client.rst b/docs/source/simulation_components/system/services/dns_client.rst index f961ece3..91461590 100644 --- a/docs/source/simulation_components/system/services/dns_client.rst +++ b/docs/source/simulation_components/system/services/dns_client.rst @@ -2,20 +2,22 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK -DNSClient -========= +.. _DNSClient: -The DNSClient provides a client interface for connecting to the ``DNSServer``. +DNSClient +######### + +The DNSClient provides a client interface for connecting to the :ref:`DNSServer`. Key features -^^^^^^^^^^^^ +============ -- Connects to the ``DNSServer`` via the ``SoftwareManager``. +- Connects to the :ref:`DNSServer` via the ``SoftwareManager``. - Executes DNS lookup requests and keeps a cache of known domain name IP addresses. - Handles connection to DNSServer and querying for domain name IP addresses. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the database service. - Service runs on TCP port 53 by default. (TODO: TCP for now, should be UDP in future) @@ -23,8 +25,75 @@ Usage - ``DNSClient`` will automatically add the IP Address of the domain into its cache Implementation -^^^^^^^^^^^^^^ +============== - Leverages ``SoftwareManager`` for sending payloads over the network. - Provides easy interface for Nodes to find IP addresses via domain names. - Extends base Service class. + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from ipaddress import IPv4Address + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.dns.dns_client import DNSClient + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install DNSClient on server + server.software_manager.install(DNSClient) + dns_client: DNSClient = server.software_manager.software.get("DNSClient") + dns_client.start() + + # configure DatabaseService + dns_client.dns_server = IPv4Address("192.168.0.10") + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: dns_client + type: DNSClient + options: + dns_server: 192.168.0.10 + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: DNSClient +.. |SOFTWARE_NAME_BACKTICK| replace:: ``DNSClient`` + +``dns_server`` +"""""""""""""" + +Optional. Default value is ``None``. + +The IP Address of the :ref:`DNSServer`. + +This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. diff --git a/docs/source/simulation_components/system/services/dns_server.rst b/docs/source/simulation_components/system/services/dns_server.rst index ef463d9a..89ce7fc1 100644 --- a/docs/source/simulation_components/system/services/dns_server.rst +++ b/docs/source/simulation_components/system/services/dns_server.rst @@ -2,12 +2,15 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _DNSServer: + DNSServer -========= +######### + Also known as a DNS Resolver, the ``DNSServer`` provides a DNS Server simulation by extending the base Service class. Key capabilities -^^^^^^^^^^^^^^^^ +================ - Simulates DNS requests and DNSPacket transfer across a network - Registers domain names and the IP Address linked to the domain name @@ -15,12 +18,81 @@ Key capabilities - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the database service. - Service runs on TCP port 53 by default. (TODO: TCP for now, should be UDP in future) Implementation -^^^^^^^^^^^^^^ +============== - DNS request and responses use a ``DNSPacket`` object - Extends Service class for integration with ``SoftwareManager``. + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from ipaddress import IPv4Address + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.dns.dns_server import DNSServer + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install DNSServer on server + server.software_manager.install(DNSServer) + dns_server: DNSServer = server.software_manager.software.get("DNSServer") + dns_server.start() + + # configure DatabaseService + dns_server.dns_register("arcd.com", IPv4Address("192.168.10.10")) + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: dns_server + type: DNSServer + options: + domain_mapping: + arcd.com: 192.168.0.10 + another-example.com: 192.168.10.10 + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: DNSServer +.. |SOFTWARE_NAME_BACKTICK| replace:: ``DNSServer`` + +domain_mapping +"""""""""""""" + +Domain mapping takes the domain and IP Addresses as a key-value pairs i.e. + +If the domain is "arcd.com" and the IP Address attributed to the domain is 192.168.0.10, then the value should be ``arcd.com: 192.168.0.10`` + +The key must be a string and the IP Address must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. diff --git a/docs/source/simulation_components/system/services/ftp_client.rst b/docs/source/simulation_components/system/services/ftp_client.rst index 77111938..82b85770 100644 --- a/docs/source/simulation_components/system/services/ftp_client.rst +++ b/docs/source/simulation_components/system/services/ftp_client.rst @@ -2,16 +2,17 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _FTPClient: FTPClient -========= +######### -The ``FTPClient`` provides a client interface for connecting to the ``FTPServer``. +The ``FTPClient`` provides a client interface for connecting to the :ref:`FTPServer`. Key features -^^^^^^^^^^^^ +============ -- Connects to the ``FTPServer`` via the ``SoftwareManager``. +- Connects to the :ref:`FTPServer` via the ``SoftwareManager``. - Simulates FTP requests and FTPPacket transfer across a network - Allows the emulation of FTP commands between an FTP client and server: - PORT: specifies the port that server should connect to on the client (currently only uses ``Port.FTP``) @@ -21,7 +22,7 @@ Key features - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the FTP client service. - Service runs on FTP (command) port 21 by default. (TODO: look at in depth implementation of FTP PORT command) @@ -29,81 +30,61 @@ Usage - Execute retrieving a file from the FTP server with ``request_file`` Implementation -^^^^^^^^^^^^^^ +============== - Leverages ``SoftwareManager`` for sending payloads over the network. - Provides easy interface for Nodes to transfer files between each other. - Extends base Service class. +Examples +======== -Example Usage -------------- - -Dependencies -^^^^^^^^^^^^ +Python +"""""" .. code-block:: python - from ipaddress import IPv4Address - - from primaite.simulator.network.container import Network - from primaite.simulator.network.hardware.nodes.computer import Computer - from primaite.simulator.network.hardware.nodes.server import Server - from primaite.simulator.system.services.ftp.ftp_server import FTPServer + from primaite.simulator.network.hardware.nodes.host.server import Server from primaite.simulator.system.services.ftp.ftp_client import FTPClient - from primaite.simulator.network.hardware.node_operating_state import NodeOperatingState -Example peer to peer network -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: python - - net = Network() - - pc1 = Computer( - hostname="pc1", - ip_address="120.10.10.10", + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", subnet_mask="255.255.255.0", - operating_state=NodeOperatingState.ON # initialise the computer in an ON state + default_gateway="192.168.1.1Ó", + start_up_duration=0, ) - srv = Server( - hostname="srv", - ip_address="120.10.10.20", - subnet_mask="255.255.255.0", - operating_state=NodeOperatingState.ON # initialise the server in an ON state - ) - net.connect(pc1.network_interface[1], srv.network_interface[1]) + server.power_on() -Install the FTP Server -^^^^^^^^^^^^^^^^^^^^^^ + # Install FTPClient on server + server.software_manager.install(FTPClient) + ftp_client: FTPClient = server.software_manager.software.get("FTPClient") + ftp_client.start() -FTP Client should be pre installed on nodes -.. code-block:: python +Via Configuration +""""""""""""""""" - srv.software_manager.install(FTPServer) - ftpserv: FTPServer = srv.software_manager.software['FTPServer'] +.. code-block:: yaml -Setting up the FTP Server -^^^^^^^^^^^^^^^^^^^^^^^^^ + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: ftp_client + type: FTPClient -Set up the FTP Server with a file that the client will need to retrieve +Configuration +============= -.. code-block:: python +.. include:: ../common/common_configuration.rst - srv.file_system.create_file('my_file.png') +.. |SOFTWARE_NAME| replace:: FTPClient +.. |SOFTWARE_NAME_BACKTICK| replace:: ``FTPClient`` -Check that file was retrieved -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: python - - client.request_file( - src_folder_name='root', - src_file_name='my_file.png', - dest_folder_name='root', - dest_file_name='test.png', - dest_ip_address=IPv4Address("120.10.10.20") - ) - - print(client.get_file(folder_name="root", file_name="test.png")) +**FTPClient has no configuration options** diff --git a/docs/source/simulation_components/system/services/ftp_server.rst b/docs/source/simulation_components/system/services/ftp_server.rst index 81f51e6b..d807a14f 100644 --- a/docs/source/simulation_components/system/services/ftp_server.rst +++ b/docs/source/simulation_components/system/services/ftp_server.rst @@ -2,12 +2,15 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _FTPServer: + FTPServer -========= +######### + Provides a FTP Client-Server simulation by extending the base Service class. Key capabilities -^^^^^^^^^^^^^^^^ +================ - Simulates FTP requests and FTPPacket transfer across a network - Allows the emulation of FTP commands between an FTP client and server: @@ -16,12 +19,75 @@ Key capabilities - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== + - Install on a Node via the ``SoftwareManager`` to start the FTP server service. - Service runs on FTP (command) port 21 by default. (TODO: look at in depth implementation of FTP PORT command) Implementation -^^^^^^^^^^^^^^ +============== - FTP request and responses use a ``FTPPacket`` object - Extends Service class for integration with ``SoftwareManager``. + + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.ftp.ftp_server import FTPServer + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install FTPServer on server + server.software_manager.install(FTPServer) + ftp_server: FTPServer = server.software_manager.software.get("FTPServer") + ftp_server.start() + + ftp_server.server_password = "test" + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: ftp_server + type: FTPServer + options: + server_password: test + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: FTPServer +.. |SOFTWARE_NAME_BACKTICK| replace:: ``FTPServer`` + +``server_password`` +""""""""""""""""""" + +Optional. Default value is ``None``. + +The password that needs to be provided by a connecting :ref:`FTPClient` in order to create a successful connection. diff --git a/docs/source/simulation_components/system/services/ntp_client.rst b/docs/source/simulation_components/system/services/ntp_client.rst index 27cd27e4..aaba3261 100644 --- a/docs/source/simulation_components/system/services/ntp_client.rst +++ b/docs/source/simulation_components/system/services/ntp_client.rst @@ -2,25 +2,94 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _NTPClient: + NTPClient -========= +######### The NTPClient provides a client interface for connecting to the ``NTPServer``. Key features -^^^^^^^^^^^^ +============ - Connects to the ``NTPServer`` via the ``SoftwareManager``. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the database service. - Service runs on UDP port 123 by default. Implementation -^^^^^^^^^^^^^^ +============== - Leverages ``SoftwareManager`` for sending payloads over the network. - Provides easy interface for Nodes to find IP addresses via domain names. - Extends base Service class. + + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from ipaddress import IPv4Address + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.ntp.ntp_client import NTPClient + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install NTPClient on server + server.software_manager.install(NTPClient) + ntp_client: NTPClient = server.software_manager.software.get("NTPClient") + ntp_client.start() + + ntp_client.configure(ntp_server_ip_address=IPv4Address("192.168.0.10")) + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: ntp_client + type: NTPClient + options: + ntp_server_ip: 192.168.0.10 + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: NTPClient +.. |SOFTWARE_NAME_BACKTICK| replace:: ``NTPClient`` + +``ntp_server_ip`` +""""""""""""""""" + +Optional. Default value is ``None``. + +The IP address of an NTP Server which provides a time that the ``NTPClient`` can synchronise to. + +This must be a valid octet i.e. in the range of ``0.0.0.0`` and ``255.255.255.255``. diff --git a/docs/source/simulation_components/system/services/ntp_server.rst b/docs/source/simulation_components/system/services/ntp_server.rst index 066ad5ac..0025b428 100644 --- a/docs/source/simulation_components/system/services/ntp_server.rst +++ b/docs/source/simulation_components/system/services/ntp_server.rst @@ -2,27 +2,85 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _NTPServer: + NTPServer -========= +######### + The ``NTPServer`` provides a NTP Server simulation by extending the base Service class. NTP Client ----------- +========== + The ``NTPClient`` provides a NTP Client simulation by extending the base Service class. Key capabilities -^^^^^^^^^^^^^^^^ +================ - Simulates NTP requests and NTPPacket transfer across a network - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== - Install on a Node via the ``SoftwareManager`` to start the database service. - Service runs on UDP port 123 by default. Implementation -^^^^^^^^^^^^^^ +============== - NTP request and responses use a ``NTPPacket`` object - Extends Service class for integration with ``SoftwareManager``. + + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.ntp.ntp_server import NTPServer + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install NTPServer on server + server.software_manager.install(NTPServer) + ntp_server: NTPServer = server.software_manager.software.get("NTPServer") + ntp_server.start() + + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: ntp_server + type: NTPServer + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: NTPServer +.. |SOFTWARE_NAME_BACKTICK| replace:: ``NTPServer`` + +**NTPServer has no configuration options** diff --git a/docs/source/simulation_components/system/services/web_server.rst b/docs/source/simulation_components/system/services/web_server.rst index ae3f32e6..62b1d090 100644 --- a/docs/source/simulation_components/system/services/web_server.rst +++ b/docs/source/simulation_components/system/services/web_server.rst @@ -2,12 +2,15 @@ © Crown-owned copyright 2023, Defence Science and Technology Laboratory UK +.. _WebServer: + WebServer -========= +######### + Provides a Web Server simulation by extending the base Service class. Key capabilities -^^^^^^^^^^^^^^^^ +================ - Simulates a web server with the capability to also request data from a database - Allows the emulation of HTTP requests between client (e.g. a web browser) and server @@ -15,13 +18,69 @@ Key capabilities - Leverages the Service base class for install/uninstall, status tracking, etc. Usage -^^^^^ +===== + - Install on a Node via the ``SoftwareManager`` to start the `WebServer`. - Service runs on HTTP port 80 by default. (TODO: HTTPS) +- A :ref:`DatabaseClient` must be installed and configured on the same node as the ``WebServer`` if it is intended to send a users request i.e. + in the case that the :ref:`WebBrowser` sends a request with users in its request path, the ``WebServer`` will utilise the ``DatabaseClient`` to send a request to the ``DatabaseService`` Implementation -^^^^^^^^^^^^^^ +============== - HTTP request uses a ``HttpRequestPacket`` object - HTTP response uses a ``HttpResponsePacket`` object - Extends Service class for integration with ``SoftwareManager``. + + +Examples +======== + +Python +"""""" + +.. code-block:: python + + from primaite.simulator.network.hardware.nodes.host.server import Server + from primaite.simulator.system.services.web_server.web_server import WebServer + + # Create Server + server = Server( + hostname="server", + ip_address="192.168.2.2", + subnet_mask="255.255.255.0", + default_gateway="192.168.1.1", + start_up_duration=0, + ) + server.power_on() + + # Install WebServer on server + server.software_manager.install(WebServer) + web_server: WebServer = server.software_manager.software.get("WebServer") + web_server.start() + +Via Configuration +""""""""""""""""" + +.. code-block:: yaml + + simulation: + network: + nodes: + - ref: example_server + hostname: example_server + type: server + ... + services: + - ref: web_server + type: WebServer + +Configuration +============= + +.. include:: ../common/common_configuration.rst + +.. |SOFTWARE_NAME| replace:: WebServer +.. |SOFTWARE_NAME_BACKTICK| replace:: ``WebServer`` + +**WebServer has no configuration options** diff --git a/src/primaite/game/game.py b/src/primaite/game/game.py index 8e78f636..ef54893e 100644 --- a/src/primaite/game/game.py +++ b/src/primaite/game/game.py @@ -296,6 +296,7 @@ class PrimaiteGame: if service_type == "DatabaseService": if "options" in service_cfg: opt = service_cfg["options"] + new_service.password = opt.get("backup_server_ip", None) new_service.configure_backup(backup_server=IPv4Address(opt.get("backup_server_ip"))) if service_type == "FTPServer": if "options" in service_cfg: @@ -327,7 +328,7 @@ class PrimaiteGame: new_application.configure( server_ip_address=IPv4Address(opt.get("server_ip")), server_password=opt.get("server_password"), - payload=opt.get("payload"), + payload=opt.get("payload", "DELETE"), port_scan_p_of_success=float(opt.get("port_scan_p_of_success", "0.1")), data_manipulation_p_of_success=float(opt.get("data_manipulation_p_of_success", "0.1")), ) diff --git a/src/primaite/simulator/system/services/database/database_service.py b/src/primaite/simulator/system/services/database/database_service.py index 0b9554d5..c0390b4f 100644 --- a/src/primaite/simulator/system/services/database/database_service.py +++ b/src/primaite/simulator/system/services/database/database_service.py @@ -23,6 +23,7 @@ class DatabaseService(Service): """ password: Optional[str] = None + """Password that needs to be provided by clients if they want to connect to the DatabaseService.""" backup_server_ip: IPv4Address = None """IP address of the backup server.""" @@ -194,6 +195,8 @@ class DatabaseService(Service): """ Executes the given SQL query and returns the result. + .. _Database Payload List: + Possible queries: - SELECT : returns the data - DELETE : deletes the data