How to Install and Use Gremlin with Docker

Introduction

The gremlin/gremlin Docker image is hosted on Docker Hub. The image contains both the gremlin and gremlind (daemon) binaries which allow multiple usages of gremlin with the same image.

File System Requirements

To run the gremlin daemon (gremlind) in a Docker container or use gremlin to attack other Docker containers, there are two directories that must be mounted on the host’s file system.

docker run -d \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    -v /var/lib/gremlin:/var/lib/gremlin \
    -v /var/log/gremlin:/var/log/gremlin \
    gremlin/gremlin daemon

NOTE: If you are using Docker’s user namespace remapping feature, you will need to enable Gremlin to assume the user namespace of the host. See “User Namespace Isolation”.

Basic Usage

When it comes to running attacks in a Docker environment, there are two basic usages. Both usages can be done in daemon-mode with gremlind, or directly with the gremlin cli:

  1. Attack the host machine from within a gremlin container
  2. Attack any application container from within a gremlin container

By supplying daemon as your first argument, the container will launch the daemon process.

# run a gremlin container in daemon mode
docker run -d \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    -e GREMLIN_IDENTIFIER="${GREMLIN_IDENTIFIER}" \
    -e GREMLIN_CONFIG_SERVICE="${GREMLIN_CONFIG_SERVICE}" \
    -e GREMLIN_CONFIG_REGION="${GREMLIN_CONFIG_REGION}" \
    -e GREMLIN_CONFIG_ZONE="${GREMLIN_CONFIG_ZONE}" \
    -v /var/lib/gremlin:/var/lib/gremlin \
    -v /var/log/gremlin:/var/log/gremlin \
    gremlin/gremlin daemon

Otherwise, any other arguments will be interpreted by the gremlin CLI

# run a cpu attack in a gremlin container
docker run -it \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    gremlin/gremlin attack cpu

Detailed Usage

Gremlin’s usage of some Linux capabilities is documented in our security section. However, it’s worth showing how those capabilities can be granted to the daemon when running in Docker. Additionally, some gremlins like shutdown and the network gremlins require some additional resources.

The example below is the full command you should issue when launching a daemon that can attack its own host, as well as other containers.

# run a gremlin container in daemon mode
docker run -d \
    --net=host \
    --pid=host \
    --cap-add=NET_ADMIN \
    --cap-add=SYS_BOOT \
    --cap-add=SYS_TIME \
    --cap-add=KILL \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    -e GREMLIN_IDENTIFIER="${GREMLIN_IDENTIFIER}" \
    -e GREMLIN_CONFIG_SERVICE="${GREMLIN_CONFIG_SERVICE}" \
    -v /var/run/docker.sock:/var/run/docker.sock \
    -v /var/log/gremlin:/var/log/gremlin \
    -v /var/lib/gremlin:/var/lib/gremlin \
    gremlin/gremlin daemon

Let’s unpack this command:

--net=host:

This tells Docker that you want to run the container on the same network as your host. This gives the gremlin daemon access to the network devices on the host and allows you to run attacks on them.

--pid=host:

This maps the hosts processes into the containers process namespace, and is only needed if you intend to run process killer attacks against the host.

--cap-add=[ NET_ADMIN | SYS_BOOT | SYS_TIME | KILL ]:

These options grant the respective capabilities to the Docker container. Without them, your attacks will likely run into permissions issues.

-v /var/run/docker.sock:/var/run/docker.sock:

This option mounts the host’s Docker socket to the container running the gremlin daemon. This allows the gremlin daemon to find and attack other Docker containers

-v /proc/sysrq-trigger:/sysrq

This special mount is only needed if you intend to run shutdown attacks on the host.

Attacking the Host

Even with the gremlin running in a Docker container, gremlin can attack the host given the right capabilities and namespaces.

The network gremlins can attack the host’s network traffic by attaching to the host’s network namespace via --net=host.

# run a latency attack against the host from a Docker container
docker run -it \
    --cap-add=NET_ADMIN \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    gremlin/gremlin attack latency -h google.com -m 100

The time travel gremlin can attack the host’s system time

# run a time_travel attack against the host from a Docker container
docker run -it --net=host \
    --cap-add=NET_ADMIN \
    --cap-add=SYS_TIME \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    gremlin/gremlin attack time_travel --ntp --offset 3600

The process killer gremlin can terminate the host’s processes, provided you give it access to the host process namespace with --pid=host and a permissive apparmor profile such as --security-opt apparmor=unconfined.

# run a process_killer attack against the host from a Docker container
docker run -it \
    --cap-add=KILL \
    --pid=host \
    --security-opt apparmor=unconfined \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    gremlin/gremlin attack process_killer -l 1 -i 1 -p top

The shutdown gremlin can attack the host’s system, provided you give it access to the linux shutdown trigger with a volume mount option of -v /proc/sysrq-trigger:/sysrq.

# run a shutdown attack against the host from a Docker container
docker run -it \
    --cap-add=SYS_BOOT \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    -v /proc/sysrq-trigger:/sysrq \
    gremlin/gremlin attack shutdown

Attacking Containers

Like the attack argument, gremlin has an attack-container argument that can be used to attack containers by their CONTAINER ID or NAME.

This example shows how a host can attack one of its containers.

# run a blackhole attack, dropping all of the f291a040a6aa's egress traffic to google.com
gremlin attack-container f291a040a6aa blackhole -h google.com

Gremlin does not have to be installed on the host in order to attack a container on the host. This example shows how a gremlin container can attack an application container.

Notice that /var/run/docker.sock is mounted. This is needed so that gremlin can find and attack the application container.

# run a blackhole attack, dropping all of the f291a040a6aa's egress traffic to google.com
# because gremlin is running in a container, give it access to the Docker socket
docker run -it \
    --cap-add=NET_ADMIN \
    -e GREMLIN_ORG_ID="${GREMLIN_ORG_ID}" \
    -e GREMLIN_ORG_SECRET="${GREMLIN_ORG_SECRET}" \
    -v /var/run/docker.sock:/var/run/docker.sock \
    gremlin/gremlin attack-container f291a040a6aa blackhole -h google.com

Technologies on Docker

Docker Compose

The gremlin daemon can be deployed like any other service with docker-compose.

version: '2'
services:
  gremlin:
    image: gremlin/gremlin
    command: daemon
    # optionally add gremlin to the host network to attack the host
    network_mode: host
    # add the capabilities you need to run your attacks
    cap_add:
      - NET_ADMIN
      - SYS_BOOT
      - SYS_TIME
      - KILL
    # configure gremlin with org and identity information
    environment:
      - GREMLIN_ORG_ID
      - GREMLIN_ORG_SECRET
      - GREMLIN_IDENTIFIER
      # optionally configure your daemon with a service identifier
      - GREMLIN_CONFIG_SERVICE
      # optionally configure your daemon with a custom region and zone
      # note: if running on AWS, these values can be discovered if the
      # daemon runs in `network_mode: host`
      - GREMLIN_CONFIG_REGION
      - GREMLIN_CONFIG_ZONE
    # To attack other Docker containers:
    # Mount the Docker socket and the gremlin state directory
    volumes:
      - /var/lib/gremlin:/var/lib/gremlin
      - /var/run/docker.sock:/var/run/docker.sock