Aller au contenu

TheHive aide-mémoire

Overview

TheHive is a scalable, open-source security réponse aux incidents 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

# 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-clé|sudo apt-clé 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-clé-elasticsearch|sudo apt-clé 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.hôte: 127.0.0.1
# transport.hôte: 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-clé
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-clé-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
gpgclé=https://artifacts.elastic.co/GPG-clé-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
    hôtename: ["127.0.0.1"]
    index-name: thehive
  \\\}
\\\}

## Attachment storage configuration
storage \\\{
  provider: localfs
  localfs.location: /opt/thp/thehive/files
\\\}

## authentification configuration
auth \\\{
  providers: [
    \\\{name: session\\\}
    \\\{name: basic, realm: thehive\\\}
    \\\{name: local\\\}
    \\\{name: clé\\\}
  ]
\\\}

## 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"
        clé: "API_clé"
      \\\}
    \\\}
  ]
  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.exemple.com"
      auth \\\{
        type: clé
        clé: "MISP_API_clé"
      \\\}
      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.clé: "CHANGE_ME_PLEASE"

# Secret configuration
sudo vi /etc/thehive/secret.conf

# Add secret clé
| play.http.secret.clé="$(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.hôte: 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 "localhôte:9200/_cluster/health?pretty"

SSL/TLS configuration

# Generate SSL certificat
sudo openssl req -x509 -newclé rsa:4096 -cléout /etc/thehive/thehive-clé.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
  cléStore \\\{
    path: "/etc/thehive/thehive.p12"
    type: "PKCS12"
    mot de passe: "changeme"
  \\\}
\\\}

# Convert PEM to PKCS12
sudo openssl pkcs12 -export -out /etc/thehive/thehive.p12 -inclé /etc/thehive/thehive-clé.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://localhôte:9000

# Default admin identifiants
nom d'utilisateur: admin@thehive.local
mot de passe: secret

# Change admin mot de passe immediately
# Navigate to Admin ->`` Users -> admin@thehive.local -> Edit

User Creation via API

# Get API clé
API_clé="your-api-clé"
THEHIVE_URL="http://localhôte:9000"

# Create user
curl -X POST "$THEHIVE_URL/api/user" \
  -H "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "login": "analyst@company.com",
    "name": "Security Analyst",
    "roles": ["read", "write"],
    "mot de passe": "Tempmot de passe123!"
  \\\\}'

# Create organization
curl -X POST "$THEHIVE_URL/api/organisation" \
  -H "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé"

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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "title": "logiciel malveillant Incident",
    "Description": "Potential logiciel malveillant infection detected",
    "severity": 3,
    "tlp": 3,
    "template": "logiciel malveillant-investigation"
  \\\\}'

Case Updates

# Update case status
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
  -H "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "status": "InProgress"
  \\\\}'

# Add tags to case
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
  -H "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "tags": ["logiciel malveillant", "endpoint", "critical"]
  \\\\}'

# Assign case
curl -X PATCH "$THEHIVE_URL/api/case/CASE_ID" \
  -H "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "assignee": "analyst@company.com"
  \\\\}'
# Search cases
curl -X POST "$THEHIVE_URL/api/case/_search" \
  -H "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "status": "Completed"
  \\\\}'

# Add task log
curl -X POST "$THEHIVE_URL/api/case/task/TASK_ID/log" \
  -H "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "message": "Completed analysis of network logs. Found 15 suspicious connexions.",
    "startDate": 1640995200000,
    "status": "Ok"
  \\\\}'

🔍 Observable Management

Adding Observables

# Add IP observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
  -H "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -H "Content-Type: application/json" \
  -d '\\\\{
    "dataType": "hash",
    "data": "d41d8cd98f00b204e9800998ecf8427e",
    "message": "MD5 hash of suspicious file",
    "tlp": 3,
    "ioc": true,
    "tags": ["logiciel malveillant", "hash"]
  \\\\}'

# Add domain observable
curl -X POST "$THEHIVE_URL/api/case/CASE_ID/artifact" \
  -H "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé"

# Get analysis results
curl -X GET "$THEHIVE_URL/api/connector/cortex/job/JOB_ID" \
  -H "autorisation: Bearer $API_clé"

# Get observable details
curl -X GET "$THEHIVE_URL/api/case/artifact/OBSERVABLE_ID" \
  -H "autorisation: Bearer $API_clé"

🔗 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"
        clé: "CORTEX_API_clé"
      \\\\}
      wsConfig \\\\{
        ssl \\\\{
          loose \\\\{
            acceptAnycertificat: true
            allowWeakprotocoles: true
          \\\\}
        \\\\}
      \\\\}
    \\\\}
  ]
  refreshDelay: 1 minute
  maxRetryOnError: 3
  statusCheckInterval: 1 minute
\\\\}

Running Analyzers

# List available analyzers
curl -X GET "$THEHIVE_URL/api/connector/cortex/analyzer" \
  -H "autorisation: Bearer $API_clé"

# Run VirusTotal analyzer
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/VirusTotal_GetReport_3_0/artifact/OBSERVABLE_ID" \
  -H "autorisation: Bearer $API_clé"

# Run multiple analyzers
curl -X POST "$THEHIVE_URL/api/connector/cortex/analyzer/_search" \
  -H "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé"
  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: clé
        clé: "MISP_API_clé"
      \\\\}
      wsConfig \\\\{
        ssl \\\\{
          loose \\\\{
            acceptAnycertificat: 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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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 "autorisation: Bearer $API_clé" \
  -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_clé):
        self.url = url.rstrip('/')
        self.api_clé = api_clé
        self.headers = \\\\{
            'autorisation': f'Bearer \\\\{api_clé\\\\}',
            '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://localhôte:9000', 'YOUR_API_clé')

    # exemple: Create incident case
    case = api.create_case(
        title="Suspicious Email Investigation",
        Description="hameçonnage email reported by user",
        severity=2,
        tags=["hameçonnage", "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 Renseignement sur les Menaces 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://localhôte:9000"
API_clé="YOUR_API_clé"
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 $(hôtename)"|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 "autorisation: Bearer $API_clé" \
        "$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 $(hôtename)"|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://localhôte: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 $(hôtename)"|mail -s "TheHive ES Alert" $EMAIL
        return 1
    fi
\\\\}

# Check disk utilisation
check_disk_utilisation() \\\\{
    log_message "Checking disk utilisation..."

| utilisation=$(df /opt/thp | tail -1 | awk '\\\\{print $5\\\\}' | sed 's/%//') |

    if [ $utilisation -gt 80 ]; then
        log_message "⚠ Disk utilisation is $\\\\{utilisation\\\\}%"
        echo "TheHive disk utilisation is $\\\\{utilisation\\\\}% on $(hôtename)"|mail -s "TheHive Disk Alert" $EMAIL
    else
        log_message "✓ Disk utilisation is $\\\\{utilisation\\\\}%"
    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 "autorisation: Bearer $API_clé" \
        -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 "autorisation: Bearer $API_clé" \
        "$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://localhôte:9200/_cluster/health")
    echo "Elasticsearch Status: HTTP $es_response" >> $report_file

    # Disk utilisation
| utilisation=$(df /opt/thp | tail -1 | awk '\\\\{print $5\\\\}') |
    echo "Disk utilisation: $utilisation" >> $report_file

    # Case statistics
    yesterday=$(date -d "yesterday" +%s)000
    case_count=$(curl -s \
        -H "autorisation: Bearer $API_clé" \
        -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_utilisation
    check_recent_cases
    generate_report

    log_message "Health check completed"
\\\\}

# Run main function
main "$@"

🔍 dépannage

Common Issues

# TheHive won't start
sudo systemctl status thehive
sudo journalctl -u thehive -f

# Check configuration syntaxe
sudo /opt/thehive/bin/thehive -Dconfig.file=/etc/thehive/application.conf

# Database connexion issues
curl -X GET "localhôte: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 utilisation
top -p $(pgrep -f thehive)

# Memory issues
free -h
sudo cat /proc/meminfo

# Database performance
curl -X GET "localhôte:9200/_nodes/stats?pretty"
curl -X GET "localhôte:9200/_cluster/stats?pretty"

# Network issues
sudo netstat -tlnp|grep 9000
sudo tcpdump -i any port 9000

📖 Best Practices

Security

  • Change default mot de passes and API clés
  • 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 utilisation
  • Use SSD storage for database
  • Regular maintenance and cleanup

Operations

  • Regular backup of data and configuration
  • Implement monitoring and alerting
  • Document réponse aux incidents procedures
  • Train staff on TheHive utilisation
  • Regular testing of integrations

⚠️ Security Notice: TheHive should only be used for authorized réponse aux incidents activities. Ensure compliance with organizational policies and legal requirements.

📚 Additional Resources: - TheHive documentation - TheHive GitHub - TheHive Community