OpenCTI Installation with Portainer

- Advertisement -

This post is about OpenCTI Installation with Portainer.

OpenCTI is an open source platform allowing organizations to manage their cyber threat intelligence knowledge and observables. It has been created in order to structure, store, organize and visualize technical and non-technical information about cyber threats.

The data is structured using a knowledge schema based on the STIX2 standards. It has been designed as a modern web application including a GraphQL API and an UX oriented frontend. Also, OpenCTI can be integrated with other tools and applications such as MISP, TheHive, MITRE ATT&CK etc.


The goal is to create a comprehensive tool allowing users to integrate technical information (such as TTPs and observables) and non-technical information (such as suggested attribution, victimology, sector of activity and localization), while linking each piece of information to its primary source (a report, a MISP event, etc.) and providing features such as links between each piece of information, first and last seen dates, levels of confidence and description fields. The tool is able to use the MITRE ATT&CK framework (through a dedicated connector) to help structure the data. The user can also chose to implement its own datasets.

Once data has been integrated within OpenCTI by the analysts, new relations may be inferred from existing ones to facilitate the understanding and the representation of this information. This allow the user to extract and leverage meaningful knowledge from the raw data.

OpenCTI not only allows imports but also exports of data under different formats (CSV, STIX2 bundles, etc.). Connectors are currently under development to accelerate interactions between the tool and other platforms.

OpenCTI Installation

For the installation of OpenCTI, I am using 2 x Ubuntu 18.04.4 virtual machines with 8Gb RAM and 20Gb disk assigned to each of them. They will need connectivity to each other and the internet, and can ping by hostname. Nothing else is special about them as such. Just a base OS that has been fully patched to begin with. I have named my machines opencti-1 and opencti-2. In hindsight, I probably should have named them as docker. Not a show stopper though as ill just be using them for OpenCTI and associated images.

Install Docker

Note: Both virtual machines will require Docker to be installed.

While you can install OpenCTI manually, save yourself the hassle and use the provided docker-compose file. To install Docker run the following commands. 

Update the repositories

sudo apt-get update
- Advertisement -
sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
curl -fsSL | sudo apt-key add -

Check the fingerprint of the key

sudo apt-key fingerprint 0EBFCD88

Add the stable repository

sudo add-apt-repository \
   "deb [arch=amd64] \
   $(lsb_release -cs) \

Install Docker and Docker Compose

sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli docker-compose
sudo docker version

Manage docker as a non root user

Having to sudo every docker command is annoying so lets create a docker group and add your user into it. You will need to logoff and on again for the group to re-evaluate.

sudo usermod -aG docker $USER

Create Docker Swarm

While you don’t technically need Docker Swarm to install OpenCTI, this is how im going to be installing it as I want to incorporate more Docker containers for other features in the future.

From the first node (AKA: Manager node) run the following command:

docker swarm init --advertise-addr <MANAGER-IP>

The output displays a command on what you run on the other node to join this swarm. Run that command on the second node. It will join this node as a worker node.

docker swarm join --token <LONG-TOKEN-ID> <IP-ADDRESS-OF-MANAGER:PORT>

Install Portainer

While you might enjoy managing containers manually, and its probably something you want to get your hands dirty with, using Portainer will make your life much easier. The installation of Portainer is a matter of downloading a docker-compose file and deploying a stack. We will then use Portainer to add the OpenCTI stack.

This only needs to be performed on one node.

mkdir -p /opt/portainer && cd /opt/portainer
curl -L -o portainer-agent-stack.yml

Before you stand up Portainer, we need to change the client port as it will conflict with OpenCTI. You can make this change by editing the portainer-agent-stack.yml file. Locate the ports section and change them from port 8000 / 9000 to port 18000 / 19000 respectively. The configuration should look like this afterwards.

      - "19000:9000"
      - "18000:8000"

With the ports changed, we can now stand up Portainer using the following command:

docker stack deploy --compose-file=portainer-agent-stack.yml portainer

You can then login to Portainer by using the ip:19000 and setting your initial password

The GUI provides a comprehensive overview of your Docker stack environment.

Install OpenCTI

Now we have Portainer installed, we can create the OpenCTI stack. This will be done within the Portainer interface.

Obtain docker-compose.yml

Download or copy the contents of While you could stand up your own git repository for this and point portainer at it, I am just going to keep this as a standalone system and I plan on making further changes to the docker-compose file in a later post.

Within Portainer, Select Stacks from the left hand pane, and Add stack. Give the stack a name, and use the web editor to paste in docker-compose.yml file that was downloaded.

Before we deploy the stack we need to create a number of environment variables. If you look at the docker-compose.yml file, you will notice a heap of ${VARIABLE} entries. We can add these as Environment variables.

OpenCTI provides a sample .env file which can be used and modified. Goes without saying that you should be creating your own strong passwords. Each line item needs to be manually added into the environment variables section. There are 13 variables in total.

The environment variables are used so that credentials are not hard coded and stored within the docker-compose.yml file.

You will need to create a new UUID for the OPENCTI_ADMIN_TOKEN variable. A UUID can be generated using or uuidgen from a linux command line

Deploy the OpenCTI stack

With the docker-compose file added into the web editor and the environment variables filled, press the Deploy the stack button and wait.

From deploying the stack to OpenCTI being available took quite a while. Probably best to have a break while you wait for the stack to be ready.

All going well, you should be able to hit any IP of your docker swarm on port 8080 and get an OpenCTI logon page.

OpenCTI certainly looks like a very exciting and interesting platform to store and manage Cyber Threat Intelligence for your organisation. I hope to add in a reverse proxy docker solution and extend the functionality of OpenCTI using the various available connectors.


Please enter your comment!
Please enter your name here

Latest articles

Join us on Facebook