Setting Up OpenCTI: A Beginner's Guide

Introduction

When I first set out to stand up OpenCTI in my home lab, I figured getting it configured and adding connectors would be plug-and-play. I was wrong — but the process taught me a lot about container management, environment variables, and the subtle ways OpenCTI expects things to be structured. If you're working on a home lab or just starting out with OpenCTI, this guide should help you skip some of the stumbling blocks I hit along the way.

This post is for folks like me — those trying to learn threat intelligence tooling by doing. We'll walk through my environment, the setup process, where things went wrong, and how I eventually got the VirusTotal and AlienVault OTX connectors fully functional.

Environment Overview

Here’s what I’m working with in the lab:

  • Hypervisor: Proxmox VE

  • Host Hardware: Dell PowerEdge R640

  • OpenCTI Version: 6.7.3

  • Deployment Method: Official opencti-docker GitHub repo

  • OpenCTI URL: Internal LAN IP — http://10.0.0.61:8080

  • Connectors Deployed:

    • File import/export (STIX, TXT, CSV)

    • Document import

    • VirusTotal (finally working after some troubleshooting)

    • AlienVault OTX (successfully integrated and pulling threat intel)

I installed OpenCTI using Docker Compose, with everything — Elasticsearch, MinIO, RabbitMQ, Redis, Neo4j — running in containers. All configuration was managed through the .env file and docker-compose.yml. I’m also using Docker Desktop on my daily driver to check container logs and test configs when needed.

Networking-wise, this lab is isolated but reachable from my main workstation. I’m not exposing OpenCTI outside of my internal network.

Troubleshooting the VirusTotal Connector

I initially added the VirusTotal connector thinking it would be a simple case of copy, paste, and deploy. That wasn’t the case.

The biggest hurdle? Setting the correct CONNECTOR_TYPE. At first, I set it to EXTERNAL_ENRICHMENT because that seemed to make sense. Turns out, INTERNAL_ENRICHMENT is the only accepted value.

- CONNECTOR_TYPE=INTERNAL_ENRICHMENT

The container kept throwing logs like:

'EXTERNAL_ENRICHMENT' is not a valid ConnectorType

Once I corrected the connector type, it spun up cleanly. From there, I confirmed that the container was running using:

docker compose ps | grep virustotal

And checked logs with:

docker logs opencti-docker-connector-virustotal-1 --tail=50

This gave me confidence the integration was live, even if I didn’t have observables yet.

Testing and Integration

At this point, I had the VirusTotal connector working — but I didn’t have any data to enrich. I hadn’t integrated OpenCTI with a SIEM or log source, and I wasn’t feeding it indicators from anywhere else.

So I pivoted. If I wasn’t going to push observables in, I needed something to pull them in. That’s when I set up the AlienVault OTX connector.

Adding the AlienVault connector was straightforward. I grabbed my OTX API key, added the configuration block from the official OpenCTI GitHub repo into my docker-compose.yml, and set some sane defaults:

  • Collection interval: every 30 minutes

  • Confidence scores for different observable types

  • Auto-create indicators

After a docker compose up -d --profile connectors, it came alive.

First Signs of Life

I checked the Observables and Dashboards tab in the UI... and data was there. It felt like flipping a switch. Suddenly I had:

  • 350+ indicators

  • Reports attributed to known actors like RastaFarEye and Chinese state actors

  • Active malware listings like PikaBot and BitRAT

  • Geographic targeting visuals

Populating OpenCTI with Observables from AlienVault OTX

Once the AlienVault connector was running, the payoff was nearly instant. I opened the Observables tab and finally saw real data streaming in — hashes, indicators, and labels tied to ransomware families like Phobos and actors linked to AlienVault pulses.

Here’s what that looks like:



Each observable was attributed to a report, tagged with context-rich labels like ransomware, phobos, and cyber. Even better, these were all marked TLP:CLEAR, which makes them perfect for lab and educational use.

This kind of automatic ingestion gives you an excellent jumpstart if you don’t already have a live feed from a SIEM, SOAR, or third-party system. It transforms OpenCTI from a slick-looking empty shell into an active CTI environment ready for exploration, analysis, and learning.

Outro

Getting to this point wasn’t quick — but it was absolutely worth the effort. I now have a functional OpenCTI environment that pulls in timely, relevant threat data from AlienVault OTX and is ready for enrichment via VirusTotal.

This setup has not only made OpenCTI feel useful but has also given me hands-on experience managing Docker containers, debugging connector issues, and learning what makes CTI tools tick.

Next steps? I'll likely explore adding MISP or Abuse.ch connectors, try manually uploading STIX files, and maybe even start testing correlation rules.

If you’re setting up your own OpenCTI instance, I hope this guide helps you skip the headache and get to the good part: diving into the data.


Next
Next

From ESXi to Proxmox — My Weekend Down the Rabbit Hole