Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
c9a5383
Add support for custom certificate (partially)
shreyamalviya Jun 2, 2021
c1463b4
Implement `has_sufficient_permissions` function for checking certific…
shreyamalviya Jun 3, 2021
6f1154f
Add log message for which certificate is being used
shreyamalviya Jun 3, 2021
a2bd59c
Move `has_sufficient_permissions` to a separate file in utils/
shreyamalviya Jun 3, 2021
88ae762
Expand cert and key path in IslandConfigOptions
shreyamalviya Jun 4, 2021
d740173
Post-rebase fixes
shreyamalviya Jun 4, 2021
53a1264
Extract file checking activities
shreyamalviya Jun 7, 2021
4ad49d1
Rename "required" permissions to "expected" permissions
shreyamalviya Jun 7, 2021
5ba8eff
Use octal representation for permissions
shreyamalviya Jun 7, 2021
8c1e76f
docs: Reword docker supported operating systems
mssalvatore Jun 7, 2021
16ed2e5
docs: Add steps for user-provided certificate for docker container
mssalvatore Jun 7, 2021
6c04124
docs: Add `--volume` workaround to docker troubleshooting
mssalvatore Jun 7, 2021
82c3273
docs: Fix minor capitalization issue in docker setup
mssalvatore Jun 7, 2021
227039f
Add `_expand_path()` to wrap `os.path.expandvars()\' and `os.path.exp…
shreyamalviya Jun 7, 2021
2b73ec7
Move monkey_island/cc/setup/certificate/certificate_setup.py to monke…
shreyamalviya Jun 7, 2021
42a9a79
Modify server_config.json ssl cert fields
shreyamalviya Jun 7, 2021
4f601ca
Pass file paths to setup_certificate() instead of IslandConfigOptions
shreyamalviya Jun 7, 2021
a420403
docs: Add a skeleton setup page for Linux AppImage package
mssalvatore Jun 7, 2021
871fce1
docs: Add setup instructions for linux AppImage package
mssalvatore Jun 7, 2021
eb04420
docs: Small change to docker setup to keep consistent with linux.md
mssalvatore Jun 7, 2021
ea0d6f0
island: Add a generalized testing function to test_island_config_options
mssalvatore Jun 7, 2021
f2a2efc
island: Remove redundant "test_island_config_options" from tests
mssalvatore Jun 7, 2021
4231f31
island: Add tests for ssl_certificate_file
mssalvatore Jun 7, 2021
f0a109a
island: Add tests for ssl_certificate_key_file
mssalvatore Jun 7, 2021
e4866b1
island: Change _expand_path() from a static to regular function
mssalvatore Jun 7, 2021
0519153
island: Move _expand_path() to file_utils.py so it can be reused
mssalvatore Jun 7, 2021
8744011
island: move set_home_env() to conftest.py so it can be reused
mssalvatore Jun 7, 2021
bf0fe10
island: Add unit tests for expand_path()
mssalvatore Jun 7, 2021
4e1b4fb
island: Replace calls to os.{expandpath,expandusers} with expand_path()
mssalvatore Jun 7, 2021
36314f0
island: Use certificate provided in config, not environment variables
mssalvatore Jun 7, 2021
a45848c
island: Move file_has_expected_permissions() to file_utils.py
mssalvatore Jun 7, 2021
c19dc9d
island: Add config validation to IslandConfigOptions
mssalvatore Jun 7, 2021
78af0d8
island: Move IslandConfigOptions validation to separate module
mssalvatore Jun 7, 2021
b80dd59
tests: move create_empty_file() to conftest.py
mssalvatore Jun 7, 2021
63fb396
island: Add unit tests for island_config_options_validator
mssalvatore Jun 7, 2021
4b119ab
island: Skip some island_config_options_validator tests on Windows
mssalvatore Jun 8, 2021
9086d93
docs: Make chmod command less specific in docker setup
mssalvatore Jun 8, 2021
7fe3dce
Merge pull request #1210 from guardicore/docs-docker-signed-certs
mssalvatore Jun 8, 2021
526019a
docs: Make chmod command less specific in linux setup
mssalvatore Jun 8, 2021
93e18a5
Merge pull request #1212 from guardicore/docs-appimage-signed-certs
mssalvatore Jun 8, 2021
3841dd7
island: Set tighter permissions on certs in create_certificate.sh
mssalvatore Jun 8, 2021
10e7b19
Fix consts.py (mix up during rebase)
shreyamalviya Jun 9, 2021
011ab2a
Modify `has_expected_permissions()` to check files on Windows
shreyamalviya Jun 9, 2021
f1d85db
Change default cert permissions in bat script for creating default cert
shreyamalviya Jun 9, 2021
438a63b
Fix Windows file permission checking
shreyamalviya Jun 9, 2021
fcd758e
Fix Windows file permissions checking
shreyamalviya Jun 9, 2021
cd2f627
Add tests for Windows file permissions checking
shreyamalviya Jun 9, 2021
dc8e2b0
Fix/ignore flake8 and fix isort warnings
shreyamalviya Jun 9, 2021
945e1ad
island: Split has_expected_permissions() into os-specific functions
mssalvatore Jun 9, 2021
84b0664
Modify comment in monkey_island/cc/server_utils/file_utils.py
shreyamalviya Jun 9, 2021
424aceb
Use constants instead of permission masks
shreyamalviya Jun 9, 2021
91aad66
Modify log message when checking file permissions
shreyamalviya Jun 9, 2021
8a321f0
Add Windows tests for island_config_options_validator.py
shreyamalviya Jun 9, 2021
91a7c42
Format test_island_config_options_validator.py with black
shreyamalviya Jun 9, 2021
5aaa844
Add missing constant in config_setup.py
shreyamalviya Jun 9, 2021
7fe10af
island: Pass int, not str to has_expected_permissions()
mssalvatore Jun 9, 2021
cf5b137
island: Consolidate duplicate code in test_island_config_options_vali…
mssalvatore Jun 9, 2021
67d4f18
tests: Refactor create_empty_file() -> create_empty_tmp_file()
mssalvatore Jun 9, 2021
9131f86
island: remove misleading comment
mssalvatore Jun 9, 2021
6aa7649
island: Use config file in ~/.monkey_island if it exists
mssalvatore Jun 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
159 changes: 136 additions & 23 deletions docs/content/setup/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,125 @@ weight: 4
tags: ["setup", "docker", "linux", "windows"]
---

## Deployment

### Linux

To extract the `tar.gz` file, run `tar -xvzf monkey-island-docker.tar.gz`.

Once you've extracted the container from the tar.gz file, run the following commands:

```sh
sudo docker load -i dk.monkeyisland.1.10.0.tar
sudo docker pull mongo:4.2
sudo mkdir -p /var/monkey-mongo/data/db
sudo docker run --name monkey-mongo --network=host -v /var/monkey-mongo/data/db:/data/db -d mongo:4.2
sudo docker run --name monkey-island --network=host -d guardicore/monkey-island:1.10.0
```
## Supported operating systems

Wait until the Island is done setting up and it will be available on https://localhost:5000
The Infection Monkey Docker container works on Linux only. It is not compatible with Docker for Windows or Docker for Mac.

### Windows and Mac OS X
## Deployment

Not supported yet, since docker doesn't support `--network=host` parameter on these OS's.
### 1. Load the docker images
1. Pull the MongoDB v4.2 Docker image:

```bash
sudo docker pull mongo:4.2
```

1. Extract the Monkey Island Docker tarball:

```bash
tar -xvzf monkey-island-docker.tar.gz
```

1. Load the Monkey Island Docker image:

```bash
sudo docker load -i dk.monkeyisland.1.10.0.tar
```

### 2. Start MongoDB

1. Start a MongoDB Docker container:

```bash
sudo docker run \
--name monkey-mongo \
--network=host \
--volume db:/data/db \
--detach mongo:4.2
```

### 3a. Start Monkey Island with default certificate

By default, Infection Monkey comes with a [self-signed SSL certificate](https://aboutssl.org/what-is-self-sign-certificate/). In
enterprise or other security-sensitive environments, it is recommended that the
user [provide Infection Monkey with a
certificate](#3b-start-monkey-island-with-user-provided-certificate) that has
been signed by a private certificate authority.

1. Run the Monkey Island server
```bash
sudo docker run \
--name monkey-island \
--network=host \
guardicore/monkey-island:1.10.0
```

### 3b. Start Monkey Island with user-provided certificate

1. Create a directory named `monkey_island_data`. This will serve as the
location where Infection Monkey stores its configuration and runtime
artifacts.

```bash
mkdir ./monkey_island_data
```

1. Run Monkey Island with the `--setup-only` flag to populate the `./monkey_island_data` directory with a default `server_config.json` file.

```bash
sudo docker run \
--rm \
--name monkey-island \
--network=host \
--user $(id -u ${USER}):$(id -g ${USER}) \
--volume "$(realpath ./monkey_island_data)":/monkey_island_data \
guardicore/monkey-island:1.10.0 --setup-only
```

1. (Optional but recommended) Move your `.crt` and `.key` files to `./monkey_island_data`.

1. Make sure that your `.crt` and `.key` files are read-only and readable only by you.

```bash
chmod 400 <PATH_TO_KEY_FILE>
chmod 400 <PATH_TO_CRT_FILE>
```

1. Edit `./monkey_island_data/server_config.json` to configure Monkey Island
to use your certificate. Your config should look something like this:

```json {linenos=inline,hl_lines=["11-14"]}
{
"data_dir": "/monkey_island_data",
"log_level": "DEBUG",
"environment": {
"server_config": "password",
"deployment": "docker"
},
"mongodb": {
"start_mongodb": false
},
"ssl_certificate": {
"ssl_certificate_file": "<PATH_TO_CRT_FILE>",
"ssl_certificate_key_file": "<PATH_TO_KEY_FILE>",
}
}
```

1. Start the Monkey Island server:

```bash
sudo docker run \
--name monkey-island \
--network=host \
--user $(id -u ${USER}):$(id -g ${USER}) \
--volume "$(realpath ./monkey_island_data)":/monkey_island_data \
guardicore/monkey-island:1.10.0
```

### 4. Accessing Monkey Island

After the Monkey Island docker container starts, you can access Monkey Island by pointing your browser at `https://localhost:5000`.

## Upgrading

Expand All @@ -43,12 +141,27 @@ using the *Export config* button and then import it to the new Monkey Island.
## Troubleshooting

### The Monkey Island container crashes due to a 'UnicodeDecodeError'
`UnicodeDecodeError: 'utf-8' codec can't decode byte 0xee in position 0: invalid continuation byte`

You may encounter this error because of the existence of different MongoDB keys in the `monkey-island` and `monkey-mongo` containers.
You will encounter a `UnicodeDecodeError` if the `monkey-island` container is
using a different secret key to encrypt sensitive data than was initially used
to store data in the `monkey-mongo` container.

```
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xee in position 0: invalid continuation byte
```

Starting a new container from the `guardicore/monkey-island:1.10.0` image generates a new secret key for storing sensitive information in MongoDB. If you have an old database instance running (from a previous run of Monkey), the key in the `monkey-mongo` container is different than the newly generated key in the `monkey-island` container. Since encrypted data (obtained from the previous run) is stored in MongoDB with the old key, decryption fails and you get this error.
Starting a new container from the `guardicore/monkey-island:1.10.0` image
generates a new secret key for storing sensitive information in MongoDB. If you
have an old database instance running (from a previous instance of Infection
Monkey), the data stored in the `monkey-mongo` container has been encrypted
with a key that is different from the one that Monkey Island is currently
using. When MongoDB attempts to decrypt its data with the new key, decryption
fails and you get this error.

You can fix this in two ways:
You can fix this in one of three ways:
1. Instead of starting a new container for the Monkey Island, you can run `docker container start -a monkey-island` to restart the existing container, which will contain the correct key material.
2. Kill and remove the existing MongoDB container, and start a new one. This will remove the old database entirely. Then, start the new Monkey Island container.
1. Kill and remove the existing MongoDB container, and start a new one. This will remove the old database entirely. Then, start the new Monkey Island container.
1. When you start the Monkey Island container, use `--volume
monkey_island_data:/monkey_island_data`. This will store all of Monkey
Island's runtime artifacts (including the encryption key file) in a docker
volume that can be reused by subsequent Monkey Island containers.
81 changes: 81 additions & 0 deletions docs/content/setup/linux.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
---
title: "Linux"
date: 2020-05-26T20:57:28+03:00
draft: false
pre: '<i class="fab fa-linux"></i> '
weight: 4
tags: ["setup", "AppImage", "linux"]
---

## Supported operating systems

## Deployment

1. Make the AppImage package executable:
```bash
chmod u+x Infection_Monkey_v1.11.0.AppImage
```
1. Start Monkey Island by running the Infection Monkey AppImage package:
```bash
./Infection_Monkey_v1.11.0.AppImage
```
1. Access the Monkey Island web UI by pointing your browser at
`https://localhost:5000`.

### Start Monkey Island with user-provided certificate

By default, Infection Monkey comes with a [self-signed SSL
certificate](https://aboutssl.org/what-is-self-sign-certificate/). In
enterprise or other security-sensitive environments, it is recommended that the
user provide Infection Monkey with a certificate that has been signed by a
private certificate authority.

1. Run the Infection Monkey AppImage package with the `--setup-only` flag to
populate the `$HOME/.monkey_island` directory with a default
`server_config.json` file.

```bash
./Infection_Monkey_v1.11.0.AppImage --setup-only
```

1. (Optional but recommended) Move your `.crt` and `.key` files to
`$HOME/.monkey_island`.

1. Make sure that your `.crt` and `.key` files are read-only and readable only
by you.

```bash
chmod 400 <PATH_TO_KEY_FILE>
chmod 400 <PATH_TO_CRT_FILE>
```

1. Edit `$HOME/.monkey_island/server_config.json` to configure Monkey Island
to use your certificate. Your config should look something like this:

```json {linenos=inline,hl_lines=["11-14"]}
{
"data_dir": "~/.monkey_island",
"log_level": "DEBUG",
"environment": {
"server_config": "password",
"deployment": "linux"
},
"mongodb": {
"start_mongodb": true
},
"ssl_certificate": {
"ssl_certificate_file": "<PATH_TO_CRT_FILE>",
"ssl_certificate_key_file": "<PATH_TO_KEY_FILE>",
}
}
```

1. Start Monkey Island by running the Infection Monkey AppImage package:
```bash
./Infection_Monkey_v1.11.0.AppImage
```

1. Access the Monkey Island web UI by pointing your browser at
`https://localhost:5000`.

## Upgrading
4 changes: 4 additions & 0 deletions monkey/common/utils/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,7 @@ class FindingWithoutDetailsError(Exception):

class DomainControllerNameFetchError(FailedExploitationError):
""" Raise on failed attempt to extract domain controller's name """


class InsecurePermissionsError(Exception):
""" Raise when a file does not have permissions that are secure enough """
31 changes: 23 additions & 8 deletions monkey/monkey_island/cc/server_setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json
import logging
import os
import sys
from pathlib import Path
from threading import Thread
Expand All @@ -22,12 +21,12 @@
from monkey_island.cc.arg_parser import parse_cli_args # noqa: E402
from monkey_island.cc.resources.monkey_download import MonkeyDownload # noqa: E402
from monkey_island.cc.server_utils.bootloader_server import BootloaderHttpServer # noqa: E402
from monkey_island.cc.server_utils.consts import MONKEY_ISLAND_ABS_PATH # noqa: E402
from monkey_island.cc.server_utils.encryptor import initialize_encryptor # noqa: E402
from monkey_island.cc.server_utils.island_logger import reset_logger, setup_logging # noqa: E402
from monkey_island.cc.services.initialize import initialize_services # noqa: E402
from monkey_island.cc.services.reporting.exporter_init import populate_exporter_list # noqa: E402
from monkey_island.cc.services.utils.network_utils import local_ip_addresses # noqa: E402
from monkey_island.cc.setup import island_config_options_validator # noqa: E402
from monkey_island.cc.setup.island_config_options import IslandConfigOptions # noqa: E402
from monkey_island.cc.setup.mongo.database_initializer import init_collections # noqa: E402
from monkey_island.cc.setup.mongo.mongo_setup import ( # noqa: E402
Expand All @@ -44,6 +43,8 @@ def run_monkey_island():
island_args = parse_cli_args()
config_options, server_config_path = _setup_data_dir(island_args)

_exit_on_invalid_config_options(config_options)

_configure_logging(config_options)
_initialize_globals(config_options, server_config_path)

Expand All @@ -67,6 +68,14 @@ def _setup_data_dir(island_args: IslandCmdArgs) -> Tuple[IslandConfigOptions, st
exit(1)


def _exit_on_invalid_config_options(config_options: IslandConfigOptions):
try:
island_config_options_validator.raise_on_invalid_options(config_options)
except Exception as ex:
print(f"Configuration error: {ex}")
exit(1)


def _configure_logging(config_options):
reset_logger()
setup_logging(config_options.data_dir, config_options.log_level)
Expand All @@ -83,9 +92,6 @@ def _start_island_server(should_setup_only, config_options: IslandConfigOptions)
populate_exporter_list()
app = init_app(MONGO_URL)

crt_path = str(Path(MONKEY_ISLAND_ABS_PATH, "cc", "server.crt"))
key_path = str(Path(MONKEY_ISLAND_ABS_PATH, "cc", "server.key"))

init_collections()

if should_setup_only:
Expand All @@ -94,14 +100,23 @@ def _start_island_server(should_setup_only, config_options: IslandConfigOptions)

bootloader_server_thread = _start_bootloader_server()

logger.info(
f"Using certificate path: {config_options.crt_path}, and key path: "
"{config_options.key_path}."
)

if env_singleton.env.is_debug():
app.run(host="0.0.0.0", debug=True, ssl_context=(crt_path, key_path))
app.run(
host="0.0.0.0",
debug=True,
ssl_context=(config_options.crt_path, config_options.key_path),
)
else:
http_server = WSGIServer(
("0.0.0.0", env_singleton.env.get_island_port()),
app,
certfile=os.environ.get("SERVER_CRT", crt_path),
keyfile=os.environ.get("SERVER_KEY", key_path),
certfile=config_options.crt_path,
keyfile=config_options.key_path,
)
_log_init_info()
http_server.serve_forever()
Expand Down
20 changes: 13 additions & 7 deletions monkey/monkey_island/cc/server_utils/consts.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from pathlib import Path

from monkey_island.cc.environment.utils import is_windows_os
from monkey_island.cc.server_utils import file_utils

__author__ = "itay.mizeretz"

Expand All @@ -25,7 +26,7 @@ def _get_monkey_island_abs_path() -> str:

MONKEY_ISLAND_ABS_PATH = _get_monkey_island_abs_path()

DEFAULT_DATA_DIR = os.path.expandvars(get_default_data_dir())
DEFAULT_DATA_DIR = file_utils.expand_path(get_default_data_dir())

DEFAULT_MONKEY_TTL_EXPIRY_DURATION_IN_SECONDS = 60 * 5

Expand All @@ -36,13 +37,18 @@ def _get_monkey_island_abs_path() -> str:
_MONGO_EXECUTABLE_PATH_WIN if is_windows_os() else _MONGO_EXECUTABLE_PATH_LINUX
)

DEFAULT_SERVER_CONFIG_PATH = os.path.expandvars(
os.path.join(DEFAULT_DATA_DIR, SERVER_CONFIG_FILENAME)
)

DEFAULT_DEVELOP_SERVER_CONFIG_PATH = os.path.join(
MONKEY_ISLAND_ABS_PATH, "cc", f"{SERVER_CONFIG_FILENAME}.develop"
DEFAULT_SERVER_CONFIG_PATH = file_utils.expand_path(
os.path.join(MONKEY_ISLAND_ABS_PATH, "cc", SERVER_CONFIG_FILENAME)
)

DEFAULT_LOG_LEVEL = "INFO"

DEFAULT_START_MONGO_DB = True

DEFAULT_CRT_PATH = str(Path(MONKEY_ISLAND_ABS_PATH, "cc", "server.crt"))
DEFAULT_KEY_PATH = str(Path(MONKEY_ISLAND_ABS_PATH, "cc", "server.key"))

DEFAULT_CERTIFICATE_PATHS = {
"ssl_certificate_file": DEFAULT_CRT_PATH,
"ssl_certificate_key_file": DEFAULT_KEY_PATH,
}
Loading