Skip to content

Commit

Permalink
Merge pull request #305 from kubernetes-simulator/doc-create-scenario
Browse files Browse the repository at this point in the history
doc: create scenario
  • Loading branch information
s-irvine authored Oct 22, 2020
2 parents 052b083 + 3fc329a commit fc4def8
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ Refer to the [Launch scenario flow documentation](./docs/launch.md)

Refer to the [Tasks YAML file Format documentation](./docs/tasks-yaml-format.md)

### Create a new scenario

Refer to the [Create Scenario documentation](./docs/create-scenario.md)

### The kubesim script

<code>kubesim</code> is a small script written in BASH for getting users up and running with simulator as fast as possible. It pulls the latest version of the simulator container and sets up some options for running the image. It can be installed with the following steps:
Expand Down
41 changes: 29 additions & 12 deletions docs/create-scenario.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
# Creating a Simulator Scenario

The following is a guide on contributing scenarios in terms of what they should contain from a technical and functional standpoint.
Scenarios are a self-contained set of one or more tasks that together comprise a user journey through a Kubernetes issue. Scenarios tell the story of a breached cluster, vulnerability or misconfiguration and guide the user through compromise, escalation of privilege and eventually fixing the cluster. An example of a scenario is the `network-hedgehog-defence` scenario, which explores a compromised database and includes two tasks; access the database across another namespace and add a Kubernetes resource to prevent this.

The objective of this page is to document all the steps needed to create a new scenario for the open-source Kubernetes Simulator.

## Before you start

Ensure that your scenario does not already exist in [the list of scenarios](../simulation-scripts/scenario/). You can read all the challenge texts and hints in each scenario's directory. Familiarise yourself with the structure.
Determine the type of challenge you want to create and make sure it's not already covered by an existing scenario. A good challenge should have at least a compromise step and a mitigation or fixing step. Ensure that your scenario does not already exist in [the list of scenarios](../simulation-scripts/scenario/). You can read all the challenge texts and hints in each scenario's directory. Familiarise yourself with the structure.

Think about how difficult your scenario will be. Guidelines can be found [here.](./difficulty.md)

## Creating scenarios

### How to add a scenario

In simulation-scripts > scenario create the following structure of folder

![Scenario Structure](./scenario-structure.png)
1. Create a directory in simulation-scripts/scenario/ for your scenario. This directory should be the name of your scenario and follow the naming convention of the rest of the scenarios of <challenge-topic>-<military-tactic>. You can choose a military tactic at random.

- _scenario name_: Substitute "scenario-name" with the name of your scenario.
- _apply folder_: Any yaml you put in the "apply" folder will get applied at scenario launch. This could be misconfigured RBAC, deployment, secret or any other kubernetes resource.
- _challenge.txt_: Anything you put in "challenge.txt" will get displayed on entering the scenario as the challenge text to the user. Put any context and information on tasks you want in here. You should format it with the overall challenge, and then bullet point the tasks you want available to the user. The _challenge.txt_ can be templated by using any of the environment variables available to the attack container, for example `$MASTER_IP_ADDRESSES`. Also, `##IP` can be prefixed to a Deployment, Pod or DaemonSet name to insert the pod IPs for their associated pods. For example, `##IPfrontend` would be substituted with pod IPs for all pods with names containing 'frontend'. `##NAME` will insert the full pod names and `##HIP` will insert the host IPs of the pods.
- _tasks.yaml_: "tasks.yaml" is where you store the hints for your tasks - for example an attack and a mitigation task. Hints in this file are displayed in order on prompt from the user as part of the exercise.
- _other scripts_: At the root of the scenario directory you can also add optional scripts which will run on either workers or masters when you launch the scenario. These, could, for example edit or create files on the host or change user permissions. See your options for scripts [here](./scenario.md)
2. Populate your scenario directory as per [the scenario folder structure](#scenario-folder-structure)
In simulation-scripts > scenario create the following structure of folder

When you are done writing your scenario, you must put it in the [scenario yaml ](../simulation-scripts/scenarios.yaml). The scenarios in here will be launchable from the launch container on running the simulator.
3. Put the scenario spec in the [scenario yaml ](../simulation-scripts/scenarios.yaml) and add it to the [README](../README.md). The scenarios in the scenario yaml here will be launchable from the launch container on running the simulator.

### What a good scenario contains

Expand All @@ -41,4 +38,24 @@ _Core Components_

Additionally there should be a structured story to your scenario. Most of the scenarios include an attack task from for example a pod/container or external server and a mitigation task to fix the misconfiguration. Don't forget to provide all necessary information to the user in the challenge.txt file - if the user needs to attack a port on the node, they will need to be aware of the node IP from the start.

## Testing
### Scenario Folder structure

![Scenario Structure](./scenario-structure.png)

Scenarios live in the `simulator/simulation-scripts/scenario/` directory. Minimally they must contain:

- _scenario name_: Substitute "scenario-name" with the name of your scenario.
- _apply/scenario.yaml_: This file specifies all Kubernetes resources such as namespaces, deployments and services which are part of the scenario. This Yaml will be deployed when the scenario is started. [Example scenario.yaml](https://github.com/kubernetes-simulator/simulator/blob/master/simulation-scripts/scenario/network-hedgehog-defence/apply/scenario.yaml).
- _challenge.txt_: This file contains metadata for the scenario that you want to make available to the user, such as scenario description, starting point, difficulty level and the descriptions of the tasks. This will get displayed on entering the scenario as the challenge text to the user. The _challenge.txt_ can be templated by using any of the environment variables available to the attack container, for example `$MASTER_IP_ADDRESSES`. Also, `##IP` can be prefixed to a Deployment, Pod or DaemonSet name to insert the pod IPs for their associated pods. For example, `##IPfrontend` would be substituted with pod IPs for all pods with names containing 'frontend'. `##NAME` will insert the full pod names and `##HIP` will insert the host IPs of the pods. Example [challenge.txt](https://github.com/kubernetes-simulator/simulator/blob/master/simulation-scripts/scenario/network-hedgehog-defence/challenge.txt).
- _tasks.yaml_: This file contains the task and hint specs for all tasks in the scenario. It also determines where you start - e.g. in a pod on the cluster, on a node or even outside the cluster. [Example tasks.yaml](https://github.com/kubernetes-simulator/simulator/blob/master/simulation-scripts/scenario/network-hedgehog-defence/tasks.yaml). To see the required structure and options of the tasks.yaml, see the guide [here](https://github.com/kubernetes-simulator/simulator/blob/master/docs/tasks-yaml-format.md).

Additionally the `simulator/simulation-scripts/scenario/` directory can include a number of supporting bash scripts which can we executed on the master and worker nodes. These files help with particular setups on the nodes such as installing tooling, creating files or setting up users. The scripts are executed on startup and must have the following names:

- _worker-any.sh_: runs on a randomly chosen worker node
- _worker-1.sh_: runs on worker node 1
- _worker-2.sh_: runs on worker node 2
- _workers-every.sh_: runs on worker nodes 1 & 2
- _nodes-every.sh_: runs on master and worker nodes 1 and 2
- _master.sh_: runs on master

Any other names will cause an error. See this example [master.sh](https://github.com/kubernetes-simulator/simulator/blob/master/simulation-scripts/scenario/etcd-inverted-wedge/master.sh).
4 changes: 2 additions & 2 deletions docs/tasks-yaml-format.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ tasks:

* Each task is identified by its name which **must** be a number enclosed in quotes.
* The `sortOrder` is used to sort the tasks for more advanced functions. For now each task name matches with its `sortOrder`
* The `hints` stanza contains two fields for the hints themselves and the penalty for viewing a hint:
* The `hints` stanza contains two fields; for the hints themselves and the penalty for viewing a hint:
* Text is a string value displayed to the user when the use `next_hint`
* Penalty is the value subtracted from the users score when they use `next_hint`

Expand Down Expand Up @@ -92,7 +92,7 @@ The pod starting point can also use two optional fields:
* `containerName` to choose a specific container in a pod to start in. This is required for multi-container pods.
* `podHost` to choose a pod on a specific host. Options are one of `master-0`, `node-0` or `node-1`. It is recommended to use this option with a `DaemonSet` as it can be guaranteed that a pod exists on your chosen host.

A starting point using these options is below:
A starting point using these options below:

```YAML
startingPoint:
Expand Down

0 comments on commit fc4def8

Please sign in to comment.