Deploying an incident response platform on the open internet is not always a good idea. For whatever reason you choose to do so, there are some things you need to do before going live with TheHive and Cortex.
In this post, I talk about hardening TheHive and Cortex for an Internet-accessible deployment. This includes the application of TLS v1.2+ and the configuration of multi-factor authentication. Cortex can be further hardened through IP whitelisting, and even walled gardens implemented through Cloudflare.
Install Firewalld
First and foremost, we are going to start from a hardened baseline and not expose any services to the Internet until we can adequately harden the environment. For this to work properly, we are going to install firewalld and progressively open up ports as appropriate as the installation progresses.
sudo apt install firewalld -y
sudo firewall-cmd --permanent --add-port 443/tcp
sudo firewall-cmd --reload
The above commands will permit TLS and non-TLS traffic (on ports 443 and 80 respectively) to access the server externally. All other ports should be denied by default, however care does need to be taken in accidently permitting more ports to open than are necessary.
Install TheHive4
By default, TheHive will talk on a non-TLS enabled port which creates issues for confidentiality when using TheHive in an uncontrolled environment. But also, any case artifacts being input by the analyst to the interface will be clear-text through the network.

Local authentication to TheHive is managed through an internal credential management system, which may be subjected to attempts for brute-forcing without being detected. In addition, expiring a user from TheHive requires another user administrative action to remove access, so centralized management is not possible out of the box.
In addition to the local authentication database issue mentioned above, by default two-factor authentication is not enabled by default and is something each analyst is required to implement of their own volition.
Configure TheHive4
Configuring TheHive has been covered numerous times on this blog, so there is no shortage of information in that regard. There is one aspect I have not described, and that is in changing the network port and host on which TheHive allows connections.
This can be changed from 0.0.0.0 (all interfaces) to 127.0.0.1 by adding the following line to the /etc/thehive/application.conf file:
network.host: 127.0.0.1

Next, we will restart the service, and once up again you should notice the interface now bound to 127.0.0.1:9000
This will move TheHive’s web interface to the localhost, which means we can now reverse proxy to that from Nginx, and apply TLS encryption and certificates.
Install Cortex
Similar to TheHive, Cortex talks on a non-TLS protocol which makes interception of traffic to and from the Cortex interface possible.
Whilst Cortex is not intended to be a multi-user appliance, there will inevitably be a range of appliances which will need to talk to Cortex. This may include:
- TheHive
- MISP
- N8N
- And custom integrations
So whilst Cortex and TheHive are intended to work together, and have some level of diligence behind their design and implementation, that may not always be true of other integrations. So access to Cortex should be limited to only those who have a need to know of the system and the analyses which have been conducted in there.
Configure Cortex
Much the same as TheHive, the listening host and port can be configured in the /etc/cortex/application.conf file as well. The objective we are looking for is to have Cortex reply on localhost:9001
This can be changed from 0.0.0.0 (all interfaces) to 127.0.0.1 by adding the following line to the /etc/cortex/application.conf file:

network.host: 127.0.0.1
We should be able to verify now that both services are now running on the localhost interface, and will no longer be accessible from the outside environment.

Install Nginx
To alleviate the issues described in TheHive and Cortex regarding TLS, we are going to implement Nginx as a reverse proxy, and implement TLS related controls and requirements as derived for the ACSC ISM.
Namely, we are going to implement a strong cipher configuration using TLS v1.3 and use LetsEncrypt to generate (and regenerate renewal) certificates. We are also going to isolate TheHive and Cortex access to be only attainable on localhost, thus reducing the likelihood of access via the non-TLS ports.
sudo apt install nginx -y
Configuration for your TheHive and Cortex instances will be located in the /etc/nginx/sites-available/ directory, and we will get into configuring those virtual hosts in the next section.
Configure Nginx
In the /etc/nginx/sites-available/ directory we will create a configuration file for cortex named ‘cortex_9001’, and in that file, we will describe them below:
server {
listen 443;
server_name cortex.yourdomain.com;
ssl on;
ssl_certificate /etc/nginx/ssl/cortex_cert.pem;
ssl_certificate_key /etc/nginx/ssl/cortex_key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
client_max_body_size 2G;
proxy_buffering off;
client_header_buffer_size 8k;
location / {
proxy_pass http://127.0.0.1:9001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Much the same as for TheHive, we will also describe a similar configuration for that service too, in /etc/nginx/sites-available/thehive_9000:
server {
listen 443;
server_name thehive.yourdomain.com;
ssl on;
ssl_certificate /etc/nginx/ssl/thehive_cert.pem;
ssl_certificate_key /etc/nginx/ssl/thehive_key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA HIGH !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS";
proxy_connect_timeout 600;
proxy_send_timeout 600;
proxy_read_timeout 600;
send_timeout 600;
client_max_body_size 2G;
proxy_buffering off;
client_header_buffer_size 8k;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Install Certbot
LetsEncrypt’s Certbot will be generating certificates for TheHive and Cortex’s web services. Technically, you could implement a single certificate on both services however it would be advisable to implement a certificate for each service.
sudo snap install core; sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Configure Certbot
For this next part, you will require your subdomains as configured above in your nginx configurations to resolve to the IP address for your TheHive and Cortex installation. In my case, I will be updating Cloudflare to resolve the subdomains in DNS only mode to my server’s IP address.
For each of your subdomains on this host, you can run the below, substituting the subdomains with your own:
sudo certbot certonly -d 'thehive.yourdomain.com' --server https://acme-v02.api.letsencrypt.org/directory
When asked to choose how to authenticate, choose option 1 (Nginx Web Server plugin).

Repeat this process for the remaining subdomains.
Within the /etc/letsencrypt/live/ directory, you should now have directories that will refer to your generated private keys and full chain certificates. We are going to now create symlinks to those files using the references from the nginx configurations above.
sudo ln -s /etc/letsencrypt/live/cortex.yourdomain.com/fullchain.pem /etc/nginx/ssl/cortex_cert.pem
sudo ln -s /etc/letsencrypt/live/cortex.yourdomain.com/privkey.pem /etc/nginx/ssl/cortex_key.pem
sudo ln -s /etc/letsencrypt/live/thehive.yourdomain.com/fullchain.pem /etc/nginx/ssl/thehive_cert.pem
sudo ln -s /etc/letsencrypt/live/thehive.yourdomain.com/privkey.pem /etc/nginx/ssl/thehive_key.pem
We can validate these symbolic links by running cat over the links and proving that the certificate is linked properly.
sudo cat /etc/nginx/ssl/cortex_key.pem
Automatic Renewal Configuration
To make sure that your appliance continues running without a hitch, and your TLS certificates do not expire, we will need to make sure the certbot cron file has been established. We can validate that by cat’ing the /etc/cron.d/certbot file and proving the entry is there.
cat /etc/cron.d/certbot

Furthermore, we can test the how certbot will respond by using the dry run command and watching the regeneration simulation.
sudo certbot renew --dry-run
If successful, you should see the Congratulations message at the end of the process. This will be the process which is executed (minus the simulation) when the crontab above is fired.
Activating Nginx Configurations
You will recall that the configuration for Cortex and TheHive were created in the sites-available folder, now we are going to activate them through symbolic links.
sudo ln -s /etc/nginx/sites-available/thehive_9000 /etc/nginx/sites-enabled/thehive_9000
sudo ln -s /etc/nginx/sites-available/cortex_9001 /etc/nginx/sites-enabled/cortex_9001
sudo rm /etc/nginx/sites-enabled/default
The last command above once entered, will remove the default Nginx profile which opens port 80 with the default web page. This is just another method of reducing the visible attack profile of the system.
Testing Nginx with Certificates
Now that we have certificates, we can test nginx’s configuration using the below command to determine if we have any errors.
sudo nginx -t
If your configuration is good, you should see a successful message. Now we can restart nginx and watch for the services to be established in the background.
sudo nginx -s reload
You should now see a service started on port 443 (unless you had something there previously), and this should be both Cortex and TheHive responding on their respective virtualhosts.


Testing the TLS configuration with SSLLabs
Now that we have TLS implemented with certificates generated by Certbot, and we have specified the TLS protocol requirements; we can now perform an external validation of those certificates to ensure we have properly configured and hardened the service cryptographically.
For this test, I will be using Qualys SSL Labs to perform an external audit and scoring of the configuration.

As you can see from the above scoreboard, both services have been afforded a very favourable score according to SSL Labs. There are still some weaker ciphers within the result, however the protocols being used have been isolated to TLS 1.2 and above, with no ability for attackers to try to downscale to weaker and exploitable protocols.
Enabling Multi-Factor Authentication in TheHive
If you are going to be parking TheHive on the internet, I would highly suggest implementing Two-Factor authentication within TheHive.
Within the user drop-down menu in the top right of TheHive, you will find the Settings page. Within here you will find configuration options pertinent to the currently logged in user.

MFA is enabled through the use of the QR code, and any application you have which compatible with rotating PINs. TheHive makes suggestions to use particular applications, however I have a preference to use Lastpass’ Authenticator

Once activated, logins to TheHive for the MFA hardened account look like the below:

1 comment so far