(Virtually) headless

Deploy Operator on remote servers and have the GUI "pop" on your desktop

The instructions in this post offer more context than those in our GitHub repository, so feel free to head there if you are just looking for commands. Note this feature is still in early beta, as it has been tested on a limited variety of machines. If you run into trouble, please post your issue in GitHub.

So you’ve been watching the Operator project since we kicked off our beta in November 2020 and you’ve been thinking, “that sounds cool, I’ll try that out once I can run it on a server.”

Well now’s the time!

Recently, we released our first approach for installing Operator on a server and programmatically running (and tearing down) the full lifecycle of an automated red team.

To start, clone the open-source Operator Support repository. Got it? In this repository, you’ll find all open-source plugins, along with a set of tools which are designed to work with the Operator ecosystem.

If you haven’t used Vagrant before, you’ll want to pause here and install Vagrant and VirtualBox for your operating system. If you’re on a modern MacOS, this may be as easy as brew install virtualbox vagrant. If you’re on a MacOS, you’ll additionally need to install xQuartz, which is required for X11 forwarding.

From a terminal, change directory to the tools/dialup directory and issue the standard vagrant up command to boot the server. This typically takes a few minutes as a new Ubuntu 20.04 image gets pulled down and provisioned within your VirtualBox environment. You shouldn’t see any errors while this runs. Move on to the next step once the terminal gives you the prompt back.

Run the quick vagrant ssh-config command to generate a configuration file for establishing normal SSH connection.

Next it’s time to start Operator, which you can do remotely by starting the app via SSH. You’ll get a password prompt, which will be vagrant by default.

ssh -XC -p 2222 vagrant@localhost operator

This command runs a remote command (operator) on the server (localhost) by connecting to it over port 2222 using the vagrant user account. It compresses (C) the traffic to make the application faster, as running a networked instance of an application like this will be slower than a locally installed one.

At this point, Operator should have popped up on screen and you should see the login screen. Success!

Enter your email (and the corresponding code) to login and use Operator normally.

If you want to connect agents to this instance, head to the Settings section and change your exposed IP address from to so you can accept beacons. Then point Pneuma agents to your host (laptop) IP address which will forward the traffic to your Vagrant box. It does this through the configured forwarded ports in the Vagrantfile.

This process can be repeated on permanent (or cloud) servers, if you’re looking for a non-Vagrant option. Just apply the steps in the Vagrantfile to your specific environment. The same advice holds true if you’re looking to integrate Operator into a cyber test range or other Vagrant or server-based solution.

Operator, meet Jenkins

OK this is great but what if you want to go completely hands off and deploy an adversary automatically after installing Operator? The whole login process seems like it’d create a non-starter, right? Wrong!

If you’re looking for this type of option, you’re likely looking to run autonomous red team actions through a continuous deployment/integration tool like Jenkins.

This will obviously require some custom tinkering on your custom Jenkins instance but let’s tackle what to do from the Operator side.

Again, make sure you have Operator Support cloned before continuing.

There are three things we’ll need to do:

  1. Supply the settings file from our personal Operator instance, which will log us into the new instance automatically

  2. Add adversary profiles, so they’re available immediately after installation

  3. Add schedules, which will run the adversaries automatically at configured days/times.

Copy your settings file

Install and log in to an Operator instance on your laptop. This process will generate a custom settings file, containing (among other things) a token to log you in automatically on other machines. Copy this file (settings.yml) into the operator-support/tools/dialup/configs directory.

Hint: you can find your settings file in the workspace directory referenced in the ‘Protecting your data’ doc page inside Operator. Just move back one directory from your workspace to find your settings.yml.

After copying it, open the file and change your workspace path to:


Add an adversary

Next, we’ll need to prebuild adversary profile(s). In the operator-support/tools/dialup/adversary directory create a file named e541fcb5-cbdf-47b5-9da7-9e05b422d1a5.yml and apply the following contents:

id: e541fcb5-cbdf-47b5-9da7-9e05b422d1a5  
name: Hacker I am not  
  - 85341c8c-4ecb-4579-8f53-43e3e91d7617    
  - ed71b093-fa66-4f06-86a0-ba4e514e4b28  
goals: [] 

This is a simple adversary profile containing two TTPs. Interested in what these procedures do? See if you can find them in your Operator’s Editor section or in the Community repository!

Instead of creating a brand new adversary file you can alternatively copy an existing adversary file from your laptop’s workspace.

Apply a schedule

Next, we need to add a schedule. In the operator-support/tools/dialup/configs directory create a file named schedules.yml and add the following:

- range: red         
  stealth: 'no'         
  adversary: e541fcb5-cbdf-47b5-9da7-9e05b422d1a5         
  dayOfWeek: '2'         
  hour: '14'         
  minute: '30' 

This will deploy the adversary profile you created above at 2:30pm against any agents in the “red range”.

Of course, you’ll want to deploy Pneuma agents in the red range as part of your build pipeline. That’s a pretty easy process but out of scope for this article.

Now, when you start Operator like before, you’ll log directly in (no email or code prompt) and you’ll see the adversary already there when you click into Emulate.

We hope this wet your appetite for deploying Operator “headless” on local or remote servers. Reach out any time with questions or to get support!