TheHive Cheat Sheet
Overview
TheHive is a scalable, open-source security incident response platform designed for SOCs, CSIRTs, CERTs and any information security practitioner dealing with security incidents that need to be investigated and acted upon swiftly.
🚀 Installation
Docker Installation (Recommended)
# Create directory structure
mkdir -p /opt/thehive
cd /opt/thehive
# Download docker-compose file
wget https://raw.githubusercontent.com/TheHive-Project/TheHive/master/docker/thehive/docker-compose.yml
# Create data directories
mkdir -p data/elasticsearch data/thehive
# Set permissions
sudo chown -R 1000:1000 data/
# Start services
docker-compose up -d
# Check status
docker-compose ps
Manual Installation (Ubuntu/Debian)
# Add TheHive repository
wget -qO- https://raw.githubusercontent.com/TheHive-Project/TheHive/master/PGP-PUBLIC-KEY|sudo apt-key add -
echo 'deb https://deb.thehive-project.org release main'|sudo tee -a /etc/apt/sources.list.d/thehive-project.list
# Update package list
sudo apt-get update
# Install Java 8
sudo apt-get install openjdk-8-jre-headless
# Install Elasticsearch
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch|sudo apt-key add -
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main"|sudo tee /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get update
sudo apt-get install elasticsearch
# Configure Elasticsearch
sudo vi /etc/elasticsearch/elasticsearch.yml
# Add:
# cluster.name: hive
# thread_pool.search.queue_size: 100000
# path.logs: "/var/log/elasticsearch"
# path.data: "/var/lib/elasticsearch"
# http.host: 127.0.0.1
# transport.host: 127.0.0.1
# http.port: 9200
# discovery.type: single-node
# Start Elasticsearch
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
# Install TheHive
sudo apt-get install thehive4
# Configure TheHive
sudo vi /etc/thehive/application.conf
CentOS/RHEL Installation
# Add TheHive repository
sudo rpm --import https://raw.githubusercontent.com/TheHive-Project/TheHive/master/PGP-PUBLIC-KEY
sudo tee /etc/yum.repos.d/thehive-project.repo > /dev/null << 'EOF'
[thehive-project]
enabled=1
priority=1
name=TheHive-Project RPM repository
baseurl=https://rpm.thehive-project.org/release/noarch
gpgcheck=1
EOF
# Install Java 8
sudo yum install java-1.8.0-openjdk-headless
# Install Elasticsearch
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
sudo tee /etc/yum.repos.d/elasticsearch.repo > /dev/null ``<< 'EOF'
[elasticsearch]
name=Elasticsearch repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=0
autorefresh=1
type=rpm-md
EOF
sudo yum install --enablerepo=elasticsearch elasticsearch
# Install TheHive
sudo yum install thehive4
🔧 Configuration
Basic Configuration
# TheHive configuration file
sudo vi /etc/thehive/application.conf
# Basic configuration
include file("/etc/thehive/secret.conf")
## Database configuration
db.janusgraph \\\{
storage \\\{
backend: berkeleyje
directory: /opt/thp/thehive/database
\\\}
index.search \\\{
backend: elasticsearch
hostname: ["127.0.0.1"]
index-name: thehive
\\\}
\\\}
## Attachment storage configuration
storage \\\{
provider: localfs
localfs.location: /opt/thp/thehive/files
\\\}
## Authentication configuration
auth \\\{
providers: [
\\\{name: session\\\}
\\\{name: basic, realm: thehive\\\}
\\\{name: local\\\}
\\\{name: key\\\}
]
\\\}
## Cortex configuration
play.modules.enabled += org.thp.thehive.connector.cortex.CortexModule
cortex \\\{
servers: [
\\\{
name: local
url: "http://127.0.0.1:9001"
auth \\\{
type: "bearer"
key: "API_KEY"
\\\}
\\\}
]
refreshDelay: 1 minute
maxRetryOnError: 3
statusCheckInterval: 1 minute
\\\}
## MISP configuration
play.modules.enabled += org.thp.thehive.connector.misp.MispModule
misp \\\{
interval: 1 hour
servers: [
\\\{
name: "MISP-SERVER"
url: "https://misp.example.com"
auth \\\{
type: key
key: "MISP_API_KEY"
\\\}
wsConfig \\\{\\\}
\\\}
]
\\\}
## Notification configuration
notification.webhook.endpoints = [
\\\{
name: local
url: "http://127.0.0.1:5000/"
version: 0
wsConfig: \\\{\\\}
includedTheHiveOrganisations: ["*"]
excludedTheHiveOrganisations: []
\\\}
]
## Service configuration
http.address: 0.0.0.0
http.port: 9000
play.http.secret.key: "CHANGE_ME_PLEASE"
# Secret configuration
sudo vi /etc/thehive/secret.conf
# Add secret key
play.http.secret.key="$(cat /dev/urandom|tr -dc 'a-zA-Z0-9'|fold -w 64|head -n 1)"
Database Configuration
# Elasticsearch configuration for TheHive
sudo vi /etc/elasticsearch/elasticsearch.yml
# Cluster settings
cluster.name: thehive
node.name: thehive-node-1
# Network settings
network.host: 127.0.0.1
http.port: 9200
discovery.type: single-node
# Memory settings
bootstrap.memory_lock: true
# Thread pool settings
thread_pool.search.queue_size: 100000
thread_pool.write.queue_size: 10000
# Index settings
indices.query.bool.max_clause_count: 100000
# Configure JVM heap
sudo vi /etc/elasticsearch/jvm.options
# Set heap size to 50% of available RAM
-Xms4g
-Xmx4g
# Start Elasticsearch
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
# Verify Elasticsearch
curl -X GET "localhost:9200/_cluster/health?pretty"
SSL/TLS Configuration
# Generate SSL certificate
sudo openssl req -x509 -newkey rsa:4096 -keyout /etc/thehive/thehive-key.pem -out /etc/thehive/thehive-cert.pem -days 365 -nodes
# Configure HTTPS in TheHive
sudo vi /etc/thehive/application.conf
# Add HTTPS configuration
https \\\{
port: 9443
keyStore \\\{
path: "/etc/thehive/thehive.p12"
type: "PKCS12"
password: "changeme"
\\\}
\\\}
# Convert PEM to PKCS12
sudo openssl pkcs12 -export -out /etc/thehive/thehive.p12 -inkey /etc/thehive/thehive-key.pem -in /etc/thehive/thehive-cert.pem
# Set permissions
sudo chown thehive:thehive /etc/thehive/thehive*
sudo chmod 600 /etc/thehive/thehive*
👥 User Management
Initial Setup
# Start TheHive
sudo systemctl start thehive
# Access web interface
http://localhost:9000
# Default admin credentials
Username: admin@thehive.local
Password: secret
# Change admin password immediately
# Navigate to Admin ->`` Users -> admin@thehive.local -> Edit
User Creation via API
# Get API key
API_KEY="your-api-key"
THEHIVE_URL="http://localhost:9000"
# Create user
curl -X POST "$THEHIVE_URL/api/user" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"login": "analyst@company.com",
"name": "Security Analyst",
"roles": ["read", "write"],
"password": "TempPassword123!"
\\\\}'
# Create organization
curl -X POST "$THEHIVE_URL/api/organisation" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"name": "Security Team",
"description": "Main security organization"
\\\\}'
# Assign user to organization
curl -X POST "$THEHIVE_URL/api/organisation/Security%20Team/user/analyst@company.com" \
-H "Authorization: Bearer $API_KEY"
Role Management
# Available roles
# - read: Read-only access
# - write: Read and write access
# - admin: Full administrative access
# Update user roles
curl -X PATCH "$THEHIVE_URL/api/user/analyst@company.com" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"roles": ["read", "write", "admin"]
\\\\}'
📋 Case Management
Creating Cases
# Create case via API
curl -X POST "$THEHIVE_URL/api/case" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"title": "Suspicious Network Activity",
"description": "Unusual traffic patterns detected",
"severity": 2,
"tlp": 2,
"pap": 2,
"tags": ["network", "suspicious", "investigation"],
"customFields": \\\\{
"businessUnit": \\\\{
"string": "IT Department"
\\\\}
\\\\}
\\\\}'
# Create case with template
curl -X POST "$THEHIVE_URL/api/case" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"title": "Malware Incident",
"description": "Potential malware infection detected",
"severity": 3,
"tlp": 3,
"template": "malware-investigation"
\\\\}'
Case Updates
# Update case status
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"status": "InProgress"
\\\\}'
# Add tags to case
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"tags": ["malware", "endpoint", "critical"]
\\\\}'
# Assign case
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"assignee": "analyst@company.com"
\\\\}'
Case Search
# Search cases
curl -X POST "$THEHIVE_URL/api/case/_search" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"query": \\\\{
"_and": [
\\\\{"status": "Open"\\\\},
\\\\{"severity": \\\\{"_gte": 2\\\\}\\\\}
]
\\\\}
\\\\}'
# Search by date range
curl -X POST "$THEHIVE_URL/api/case/_search" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"query": \\\\{
"_and": [
\\\\{"createdAt": \\\\{"_gte": 1609459200000\\\\}\\\\},
\\\\{"createdAt": \\\\{"_lt": 1612137600000\\\\}\\\\}
]
\\\\}
\\\\}'
📝 Task Management
Creating Tasks
# Create task
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/task" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"title": "Analyze Network Logs",
"description": "Review firewall and proxy logs for suspicious activity",
"status": "Waiting",
"assignee": "analyst@company.com"
\\\\}'
# Create task with due date
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/task" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"title": "Containment Actions",
"description": "Isolate affected systems",
"status": "InProgress",
"dueDate": 1640995200000
\\\\}'
Task Updates
# Update task status
curl -X PATCH "$THEHIVE_URL/api/case/task/TASK_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"status": "Completed"
\\\\}'
# Add task log
curl -X POST "$THEHIVE_URL/api/case/task/TASK_ID/log" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"message": "Completed analysis of network logs. Found 15 suspicious connections.",
"startDate": 1640995200000,
"status": "Ok"
\\\\}'
🔍 Observable Management
Adding Observables
# Add IP observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"dataType": "ip",
"data": "192.168.1.100",
"message": "Suspicious IP address from network logs",
"tlp": 2,
"ioc": true,
"sighted": true,
"tags": ["suspicious", "network"]
\\\\}'
# Add file hash observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"dataType": "hash",
"data": "d41d8cd98f00b204e9800998ecf8427e",
"message": "MD5 hash of suspicious file",
"tlp": 3,
"ioc": true,
"tags": ["malware", "hash"]
\\\\}'
# Add domain observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"dataType": "domain",
"data": "malicious-domain.com",
"message": "C2 domain identified in traffic",
"tlp": 2,
"ioc": true,
"tags": ["c2", "domain"]
\\\\}'
Observable Analysis
# Run analyzer on observable
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/ANALYZER_ID/artifact/OBSERVABLE_ID" \
-H "Authorization: Bearer $API_KEY"
# Get analysis results
curl -X GET "$THEHIVE_URL/api/connector/cortex/job/JOB_ID" \
-H "Authorization: Bearer $API_KEY"
# Get observable details
curl -X GET "$THEHIVE_URL/api/case/artifact/OBSERVABLE_ID" \
-H "Authorization: Bearer $API_KEY"
🔗 Cortex Integration
Cortex Configuration
# Configure Cortex in TheHive
sudo vi /etc/thehive/application.conf
# Add Cortex configuration
play.modules.enabled += org.thp.thehive.connector.cortex.CortexModule
cortex \\\\{
servers: [
\\\\{
name: local
url: "http://127.0.0.1:9001"
auth \\\\{
type: "bearer"
key: "CORTEX_API_KEY"
\\\\}
wsConfig \\\\{
ssl \\\\{
loose \\\\{
acceptAnyCertificate: true
allowWeakProtocols: true
\\\\}
\\\\}
\\\\}
\\\\}
]
refreshDelay: 1 minute
maxRetryOnError: 3
statusCheckInterval: 1 minute
\\\\}
Running Analyzers
# List available analyzers
curl -X GET "$THEHIVE_URL/api/connector/cortex/analyzer" \
-H "Authorization: Bearer $API_KEY"
# Run VirusTotal analyzer
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/VirusTotal_GetReport_3_0/artifact/OBSERVABLE_ID" \
-H "Authorization: Bearer $API_KEY"
# Run multiple analyzers
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/_search" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"query": \\\\{
"dataTypeList": ["ip"]
\\\\}
\\\\}'|jq -r '.[].id'|while read analyzer_id; do
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/$analyzer_id/artifact/OBSERVABLE_ID" \
-H "Authorization: Bearer $API_KEY"
done
📊 MISP Integration
MISP Configuration
# Configure MISP in TheHive
sudo vi /etc/thehive/application.conf
# Add MISP configuration
play.modules.enabled += org.thp.thehive.connector.misp.MispModule
misp \\\\{
interval: 1 hour
servers: [
\\\\{
name: "MISP-PROD"
url: "https://misp.company.com"
auth \\\\{
type: key
key: "MISP_API_KEY"
\\\\}
wsConfig \\\\{
ssl \\\\{
loose \\\\{
acceptAnyCertificate: false
\\\\}
\\\\}
\\\\}
purpose: ImportAndExport
caseTemplate: "misp-event"
tags: ["misp", "threat-intel"]
max: 100
age: 7 days
includedTheHiveOrganisations: ["*"]
excludedTheHiveOrganisations: []
\\\\}
]
\\\\}
MISP Operations
# Export case to MISP
curl -X POST "$THEHIVE_URL/api/connector/misp/export/case/CASE_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"server": "MISP-PROD",
"organisation": "Security Team",
"sharing": 1,
"tlp": 2,
"tags": ["investigation", "incident"]
\\\\}'
# Import MISP event
curl -X POST "$THEHIVE_URL/api/connector/misp/import/event/EVENT_ID" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"server": "MISP-PROD",
"organisation": "Security Team"
\\\\}'
📈 Reporting and Analytics
Case Statistics
# Get case statistics
curl -X POST "$THEHIVE_URL/api/case/_stats" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"query": \\\\{
"status": "Resolved"
\\\\},
"stats": [
\\\\{"_field": "severity"\\\\},
\\\\{"_field": "resolutionStatus"\\\\},
\\\\{"_field": "tags"\\\\}
]
\\\\}'
# Get cases by time range
curl -X POST "$THEHIVE_URL/api/case/_search" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"query": \\\\{
"_and": [
\\\\{"createdAt": \\\\{"_gte": "2023-01-01T00:00:00Z"\\\\}\\\\},
\\\\{"createdAt": \\\\{"_lt": "2023-12-31T23:59:59Z"\\\\}\\\\}
]
\\\\},
"range": "all"
\\\\}'
Custom Reports
# Generate monthly report
curl -X POST "$THEHIVE_URL/api/case/_search" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '\\\\{
"query": \\\\{
"_and": [
\\\\{"createdAt": \\\\{"_gte": "2023-10-01T00:00:00Z"\\\\}\\\\},
\\\\{"createdAt": \\\\{"_lt": "2023-11-01T00:00:00Z"\\\\}\\\\}
]
\\\\},
"range": "all"
\\\\}'|jq '\\\\{
total_cases: length,
by_severity: group_by(.severity)|map(\\\\{severity: .[0].severity, count: length\\\\}),
by_status: group_by(.status)|map(\\\\{status: .[0].status, count: length\\\\})
\\\\}'
🔧 Automation Scripts
Python Case Management
#!/usr/bin/env python3
import requests
import json
from datetime import datetime, timedelta
class TheHiveAPI:
def __init__(self, url, api_key):
self.url = url.rstrip('/')
self.api_key = api_key
self.headers = \\\\{
'Authorization': f'Bearer \\\\{api_key\\\\}',
'Content-Type': 'application/json'
\\\\}
def create_case(self, title, description, severity=2, tlp=2, tags=None):
"""Create a new case"""
data = \\\\{
'title': title,
'description': description,
'severity': severity,
'tlp': tlp,
'tags': tags or []
\\\\}
response = requests.post(
f'\\\\{self.url\\\\}/api/case',
headers=self.headers,
json=data
)
if response.status_code == 201:
return response.json()
else:
raise Exception(f"Failed to create case: \\\\{response.text\\\\}")
def add_observable(self, case_id, data_type, data, message="", ioc=False, tags=None):
"""Add observable to case"""
observable_data = \\\\{
'dataType': data_type,
'data': data,
'message': message,
'ioc': ioc,
'tags': tags or []
\\\\}
response = requests.post(
f'\\\\{self.url\\\\}/api/case/\\\\{case_id\\\\}/artifact',
headers=self.headers,
json=observable_data
)
if response.status_code == 201:
return response.json()
else:
raise Exception(f"Failed to add observable: \\\\{response.text\\\\}")
def create_task(self, case_id, title, description="", assignee=None):
"""Create task in case"""
task_data = \\\\{
'title': title,
'description': description,
'status': 'Waiting'
\\\\}
if assignee:
task_data['assignee'] = assignee
response = requests.post(
f'\\\\{self.url\\\\}/api/case/\\\\{case_id\\\\}/task',
headers=self.headers,
json=task_data
)
if response.status_code == 201:
return response.json()
else:
raise Exception(f"Failed to create task: \\\\{response.text\\\\}")
def search_cases(self, query):
"""Search cases"""
response = requests.post(
f'\\\\{self.url\\\\}/api/case/_search',
headers=self.headers,
json=\\\\{'query': query\\\\}
)
if response.status_code == 200:
return response.json()
else:
raise Exception(f"Failed to search cases: \\\\{response.text\\\\}")
def get_case_stats(self):
"""Get case statistics"""
# Get cases from last 30 days
thirty_days_ago = int((datetime.now() - timedelta(days=30)).timestamp() * 1000)
query = \\\\{
'createdAt': \\\\{'_gte': thirty_days_ago\\\\}
\\\\}
cases = self.search_cases(query)
stats = \\\\{
'total_cases': len(cases),
'by_severity': \\\\{\\\\},
'by_status': \\\\{\\\\},
'by_assignee': \\\\{\\\\}
\\\\}
for case in cases:
# Count by severity
severity = case.get('severity', 'Unknown')
stats['by_severity'][severity] = stats['by_severity'].get(severity, 0) + 1
# Count by status
status = case.get('status', 'Unknown')
stats['by_status'][status] = stats['by_status'].get(status, 0) + 1
# Count by assignee
assignee = case.get('assignee', 'Unassigned')
stats['by_assignee'][assignee] = stats['by_assignee'].get(assignee, 0) + 1
return stats
def main():
# Initialize API client
api = TheHiveAPI('http://localhost:9000', 'YOUR_API_KEY')
# Example: Create incident case
case = api.create_case(
title="Suspicious Email Investigation",
description="Phishing email reported by user",
severity=2,
tags=["phishing", "email", "investigation"]
)
case_id = case['_id']
print(f"Created case: \\\\{case_id\\\\}")
# Add observables
api.add_observable(
case_id,
'mail',
'suspicious@malicious-domain.com',
'Sender email address',
ioc=True,
tags=['sender', 'email']
)
api.add_observable(
case_id,
'domain',
'malicious-domain.com',
'Suspicious domain',
ioc=True,
tags=['domain', 'c2']
)
# Create tasks
api.create_task(
case_id,
'Analyze Email Headers',
'Review email headers for routing information'
)
api.create_task(
case_id,
'Check Domain Reputation',
'Verify domain reputation in threat intelligence feeds'
)
print("Case setup completed")
# Get statistics
stats = api.get_case_stats()
print("\nCase Statistics (Last 30 days):")
print(json.dumps(stats, indent=2))
if __name__ == "__main__":
main()
Bash Monitoring Script
#!/bin/bash
# TheHive Health Check and Monitoring Script
THEHIVE_URL="http://localhost:9000"
API_KEY="YOUR_API_KEY"
LOG_FILE="/var/log/thehive-monitor.log"
EMAIL="admin@company.com"
# Function to log messages
log_message() \\\\{
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1"|tee -a $LOG_FILE
\\\\}
# Check TheHive service status
check_thehive_status() \\\\{
log_message "Checking TheHive service status..."
if systemctl is-active --quiet thehive; then
log_message "✓ TheHive service is running"
return 0
else
log_message "✗ TheHive service is not running"
echo "TheHive service is down on $(hostname)"|mail -s "TheHive Alert" $EMAIL
return 1
fi
\\\\}
# Check TheHive API connectivity
check_api_connectivity() \\\\{
log_message "Checking TheHive API connectivity..."
response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" \
-H "Authorization: Bearer $API_KEY" \
"$THEHIVE_URL/api/status")
if [ "$response" = "200" ]; then
log_message "✓ TheHive API is accessible"
return 0
else
log_message "✗ TheHive API is not accessible (HTTP $response)"
echo "TheHive API is not accessible on $(hostname)"|mail -s "TheHive API Alert" $EMAIL
return 1
fi
\\\\}
# Check Elasticsearch connectivity
check_elasticsearch() \\\\{
log_message "Checking Elasticsearch connectivity..."
response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" "http://localhost:9200/_cluster/health")
if [ "$response" = "200" ]; then
log_message "✓ Elasticsearch is accessible"
return 0
else
log_message "✗ Elasticsearch is not accessible (HTTP $response)"
echo "Elasticsearch is not accessible on $(hostname)"|mail -s "TheHive ES Alert" $EMAIL
return 1
fi
\\\\}
# Check disk usage
check_disk_usage() \\\\{
log_message "Checking disk usage..."
usage=$(df /opt/thp|tail -1|awk '\\\\{print $5\\\\}'|sed 's/%//')
if [ $usage -gt 80 ]; then
log_message "⚠ Disk usage is $\\\\{usage\\\\}%"
echo "TheHive disk usage is $\\\\{usage\\\\}% on $(hostname)"|mail -s "TheHive Disk Alert" $EMAIL
else
log_message "✓ Disk usage is $\\\\{usage\\\\}%"
fi
\\\\}
# Check recent cases
check_recent_cases() \\\\{
log_message "Checking recent case activity..."
# Get cases created in last 24 hours
yesterday=$(date -d "yesterday" +%s)000
case_count=$(curl -s \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-X POST "$THEHIVE_URL/api/case/_search" \
-d "\\\\{\"query\":\\\\{\"createdAt\":\\\\{\"_gte\":$yesterday\\\\}\\\\}\\\\}"|\
jq '.|length')
if [ "$case_count" != "null" ] && [ "$case_count" -ge 0 ]; then
log_message "✓ $case_count cases created in last 24 hours"
else
log_message "⚠ Unable to retrieve case statistics"
fi
\\\\}
# Generate health report
generate_report() \\\\{
log_message "Generating health report..."
report_file="/tmp/thehive-health-report.txt"
echo "TheHive Health Report - $(date)" > $report_file
echo "=================================" >> $report_file
echo "" >> $report_file
# Service status
if systemctl is-active --quiet thehive; then
echo "TheHive Service: RUNNING" >> $report_file
else
echo "TheHive Service: STOPPED" >> $report_file
fi
# API status
api_response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" \
-H "Authorization: Bearer $API_KEY" \
"$THEHIVE_URL/api/status")
echo "API Status: HTTP $api_response" >> $report_file
# Elasticsearch status
es_response=$(curl -s -o /dev/null -w "%\\\\{http_code\\\\}" "http://localhost:9200/_cluster/health")
echo "Elasticsearch Status: HTTP $es_response" >> $report_file
# Disk usage
usage=$(df /opt/thp|tail -1|awk '\\\\{print $5\\\\}')
echo "Disk Usage: $usage" >> $report_file
# Case statistics
yesterday=$(date -d "yesterday" +%s)000
case_count=$(curl -s \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-X POST "$THEHIVE_URL/api/case/_search" \
-d "\\\\{\"query\":\\\\{\"createdAt\":\\\\{\"_gte\":$yesterday\\\\}\\\\}\\\\}"|\
jq '.|length' 2>/dev/null||echo "N/A")
echo "Cases (24h): $case_count" >> $report_file
log_message "Health report generated: $report_file"
\\\\}
# Main execution
main() \\\\{
log_message "Starting TheHive health check..."
check_thehive_status
check_api_connectivity
check_elasticsearch
check_disk_usage
check_recent_cases
generate_report
log_message "Health check completed"
\\\\}
# Run main function
main "$@"
🔍 Troubleshooting
Common Issues
# TheHive won't start
sudo systemctl status thehive
sudo journalctl -u thehive -f
# Check configuration syntax
sudo /opt/thehive/bin/thehive -Dconfig.file=/etc/thehive/application.conf
# Database connection issues
curl -X GET "localhost:9200/_cluster/health?pretty"
sudo tail -f /var/log/thehive/application.log
# Permission issues
sudo chown -R thehive:thehive /opt/thp/
sudo chmod -R 750 /opt/thp/
# Memory issues
sudo vi /etc/thehive/application.conf
# Add: play.server.akka.max-header-value-length = 16k
Performance Issues
# High CPU usage
top -p $(pgrep -f thehive)
# Memory issues
free -h
sudo cat /proc/meminfo
# Database performance
curl -X GET "localhost:9200/_nodes/stats?pretty"
curl -X GET "localhost:9200/_cluster/stats?pretty"
# Network issues
sudo netstat -tlnp|grep 9000
sudo tcpdump -i any port 9000
📖 Best Practices
Security
- Change default passwords and API keys
- Use HTTPS for web interface
- Implement proper firewall rules
- Regular security updates
- Monitor access logs
Performance
- Tune Elasticsearch configuration
- Implement proper indexing strategy
- Monitor resource usage
- Use SSD storage for database
- Regular maintenance and cleanup
Operations
- Regular backup of data and configuration
- Implement monitoring and alerting
- Document incident response procedures
- Train staff on TheHive usage
- Regular testing of integrations
⚠️ Security Notice: TheHive should only be used for authorized incident response activities. Ensure compliance with organizational policies and legal requirements.
📚 Additional Resources: - TheHive Documentation - TheHive GitHub - TheHive Community