+
+
+
phpstorm
+
+
+
vault
+
+
stimulus
+
sails
*
xcode
+
+
+
istio
+
adonis
termux
+
deno
micronaut
+
+
+
!
+
+
nuxt
+
+
+
xml
php
saml
go
oauth
fastapi
junit
zig
+
+
+
haiku
rest
+
riot
bundler
vb
+
+
arch
+
+
clion
[]
+
+
qdrant
+
+
$
++
+
lua
+
crystal
astro
mongo
+
ฯ€
cypress
nuxt
+
+
#
k8s
+
xml
+
fastapi
+
+
ts
+
eslint
Back to Blog
๐Ÿ“Š Creating Security Dashboards on AlmaLinux: Visualize Threats in Real-Time!
almalinux security-dashboards monitoring

๐Ÿ“Š Creating Security Dashboards on AlmaLinux: Visualize Threats in Real-Time!

Published Sep 8, 2025

Build beautiful security dashboards on AlmaLinux! Learn to visualize logs, create alerts, monitor threats, and build situational awareness displays. Perfect for beginners wanting professional security monitoring! ๐ŸŽฏ

5 min read
0 views
Table of Contents

๐Ÿ“Š Creating Security Dashboards on AlmaLinux: Visualize Threats in Real-Time!

Imagine walking into a Security Operations Center with walls of screens showing real-time threats, attack maps, and system health - looks cool, right? ๐Ÿ˜Ž Well, today weโ€™re building exactly that for your AlmaLinux infrastructure! No more digging through logs or running commands repeatedly. Weโ€™re creating beautiful, interactive dashboards that show you everything at a glance. Letโ€™s transform your security monitoring from command-line chaos to visual victory! ๐Ÿš€

๐Ÿค” Why are Security Dashboards Important?

Think of security dashboards as your mission control center - showing everything important on one screen, updating in real-time! Itโ€™s like having X-ray vision for your infrastructure! ๐Ÿ‘๏ธ

Hereโ€™s why security dashboards are game-changing:

  • ๐Ÿ‘€ Instant visibility - See threats as they happen
  • ๐ŸŽฏ Pattern recognition - Spot trends humans might miss
  • โšก Faster response - Visual alerts grab attention immediately
  • ๐Ÿ“Š Executive reporting - Show security posture to management
  • ๐Ÿค Team coordination - Everyone sees the same picture
  • ๐Ÿ“ˆ Historical analysis - Track security trends over time
  • ๐Ÿ”” Smart alerting - Visual and audio alerts for critical events
  • ๐Ÿ’ก Situational awareness - Understand your security landscape

๐ŸŽฏ What You Need

Before we build your security command center, letโ€™s check requirements! Donโ€™t worry, itโ€™s manageable:

  • โœ… AlmaLinux system (2GB+ RAM recommended)
  • โœ… Root or sudo access (weโ€™re installing services! ๐Ÿ’ช)
  • โœ… Web browser for viewing dashboards
  • โœ… Basic understanding of JSON
  • โœ… About 45 minutes to set up
  • โœ… Logs to visualize (obviously! ๐Ÿ˜„)
  • โœ… Coffee or energy drink (this is fun but detailed! โšก)

๐Ÿ“ Step 1: Install Dashboard Stack

Weโ€™ll use Grafana for visualization and Prometheus for metrics! Letโ€™s set them up.

# Add Grafana repository
cat << 'EOF' > /etc/yum.repos.d/grafana.repo
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF

# Install Grafana
sudo dnf install -y grafana

# Install Prometheus
cd /opt
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xzf prometheus-2.45.0.linux-amd64.tar.gz
mv prometheus-2.45.0.linux-amd64 prometheus

# Install Loki for log aggregation
wget https://github.com/grafana/loki/releases/download/v2.9.0/loki-linux-amd64.zip
unzip loki-linux-amd64.zip
mv loki-linux-amd64 /opt/loki

# Install Promtail (log collector)
wget https://github.com/grafana/loki/releases/download/v2.9.0/promtail-linux-amd64.zip
unzip promtail-linux-amd64.zip
mv promtail-linux-amd64 /opt/promtail

# Enable and start Grafana
sudo systemctl enable --now grafana-server

# Verify Grafana is running
sudo systemctl status grafana-server
# Should show active (running)

echo "Grafana URL: http://$(hostname -I | awk '{print $1}'):3000"
echo "Default login: admin/admin"

๐Ÿ”ง Step 2: Configure Log Collection and Metrics

Letโ€™s set up data sources for our dashboards!

# Configure Prometheus
cat << 'EOF' > /opt/prometheus/prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']
  
  - job_name: 'security-metrics'
    static_configs:
      - targets: ['localhost:9090']
EOF

# Create Prometheus service
cat << 'EOF' > /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus
After=network.target

[Service]
User=root
ExecStart=/opt/prometheus/prometheus \
  --config.file=/opt/prometheus/prometheus.yml \
  --storage.tsdb.path=/opt/prometheus/data
Restart=always

[Install]
WantedBy=multi-user.target
EOF

# Configure Loki
cat << 'EOF' > /opt/loki-config.yaml
auth_enabled: false

server:
  http_listen_port: 3100

ingester:
  lifecycler:
    address: 127.0.0.1
    ring:
      kvstore:
        store: inmemory
      replication_factor: 1

schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

storage_config:
  boltdb_shipper:
    active_index_directory: /tmp/loki/boltdb-shipper-active
    cache_location: /tmp/loki/boltdb-shipper-cache
    shared_store: filesystem
  filesystem:
    directory: /tmp/loki/chunks

limits_config:
  enforce_metric_name: false
  reject_old_samples: true
  reject_old_samples_max_age: 168h
EOF

# Configure Promtail to collect logs
cat << 'EOF' > /opt/promtail-config.yaml
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://localhost:3100/loki/api/v1/push

scrape_configs:
  - job_name: security
    static_configs:
      - targets:
          - localhost
        labels:
          job: security-logs
          __path__: /var/log/secure
      
      - targets:
          - localhost
        labels:
          job: audit-logs
          __path__: /var/log/audit/audit.log
      
      - targets:
          - localhost
        labels:
          job: system-logs
          __path__: /var/log/messages
EOF

# Start all services
sudo systemctl daemon-reload
sudo systemctl start prometheus
/opt/loki -config.file=/opt/loki-config.yaml &
/opt/promtail -config.file=/opt/promtail-config.yaml &

๐ŸŒŸ Step 3: Create Security Metrics Collector

Letโ€™s build a custom exporter for security metrics!

# Create security metrics exporter
cat << 'EOF' > /opt/security-metrics.py
#!/usr/bin/env python3
import time
import re
import subprocess
from prometheus_client import start_http_server, Gauge, Counter
from datetime import datetime, timedelta

# Define metrics
failed_login_attempts = Gauge('security_failed_logins', 'Failed login attempts in last hour')
active_connections = Gauge('security_active_connections', 'Current active network connections')
suspicious_processes = Gauge('security_suspicious_processes', 'Number of suspicious processes')
firewall_blocks = Counter('security_firewall_blocks', 'Total firewall blocked connections')
sudo_commands = Counter('security_sudo_commands', 'Total sudo commands executed')
ssh_sessions = Gauge('security_ssh_sessions', 'Active SSH sessions')
selinux_denials = Counter('security_selinux_denials', 'SELinux denial count')
open_ports = Gauge('security_open_ports', 'Number of open ports')

def collect_metrics():
    while True:
        try:
            # Failed login attempts
            result = subprocess.run(['grep', 'Failed password', '/var/log/secure'], 
                                  capture_output=True, text=True)
            failed_count = len(result.stdout.splitlines())
            failed_login_attempts.set(failed_count)
            
            # Active connections
            result = subprocess.run(['ss', '-tun'], capture_output=True, text=True)
            conn_count = len(result.stdout.splitlines()) - 1
            active_connections.set(conn_count)
            
            # Suspicious processes
            result = subprocess.run(['ps', 'aux'], capture_output=True, text=True)
            suspicious = sum(1 for line in result.stdout.splitlines() 
                           if any(s in line for s in ['nc', 'nmap', 'tcpdump']))
            suspicious_processes.set(suspicious)
            
            # SSH sessions
            result = subprocess.run(['who'], capture_output=True, text=True)
            ssh_count = len([l for l in result.stdout.splitlines() if 'pts' in l])
            ssh_sessions.set(ssh_count)
            
            # Open ports
            result = subprocess.run(['ss', '-ltn'], capture_output=True, text=True)
            ports = len(result.stdout.splitlines()) - 1
            open_ports.set(ports)
            
        except Exception as e:
            print(f"Error collecting metrics: {e}")
        
        time.sleep(10)  # Collect every 10 seconds

if __name__ == '__main__':
    # Start Prometheus metrics server
    start_http_server(9091)
    print("Security metrics exporter started on port 9091")
    collect_metrics()
EOF

chmod +x /opt/security-metrics.py

# Install Python Prometheus client
pip3 install prometheus-client

# Create service for metrics exporter
cat << 'EOF' > /etc/systemd/system/security-metrics.service
[Unit]
Description=Security Metrics Exporter
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/python3 /opt/security-metrics.py
Restart=always

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now security-metrics

โœ… Step 4: Build Security Dashboards

Now for the fun part - creating beautiful dashboards! ๐ŸŽจ

# Create dashboard configuration
cat << 'EOF' > /opt/security-dashboard.json
{
  "dashboard": {
    "title": "Security Operations Dashboard",
    "panels": [
      {
        "title": "๐Ÿšจ Failed Login Attempts",
        "type": "graph",
        "gridPos": {"h": 8, "w": 12, "x": 0, "y": 0},
        "targets": [
          {
            "expr": "rate(security_failed_logins[5m])",
            "legendFormat": "Failed Logins/sec"
          }
        ]
      },
      {
        "title": "๐Ÿ” Active SSH Sessions",
        "type": "stat",
        "gridPos": {"h": 4, "w": 6, "x": 12, "y": 0},
        "targets": [
          {
            "expr": "security_ssh_sessions"
          }
        ]
      },
      {
        "title": "๐ŸŒ Network Connections",
        "type": "gauge",
        "gridPos": {"h": 4, "w": 6, "x": 18, "y": 0},
        "targets": [
          {
            "expr": "security_active_connections"
          }
        ]
      },
      {
        "title": "โš ๏ธ Suspicious Processes",
        "type": "stat",
        "gridPos": {"h": 4, "w": 6, "x": 12, "y": 4},
        "targets": [
          {
            "expr": "security_suspicious_processes"
          }
        ],
        "thresholds": {
          "mode": "absolute",
          "steps": [
            {"color": "green", "value": 0},
            {"color": "yellow", "value": 1},
            {"color": "red", "value": 3}
          ]
        }
      },
      {
        "title": "๐Ÿ›ก๏ธ Firewall Blocks",
        "type": "graph",
        "gridPos": {"h": 8, "w": 12, "x": 0, "y": 8},
        "targets": [
          {
            "expr": "rate(security_firewall_blocks[5m])",
            "legendFormat": "Blocks/sec"
          }
        ]
      },
      {
        "title": "๐Ÿ“Š Security Event Log",
        "type": "logs",
        "gridPos": {"h": 8, "w": 12, "x": 12, "y": 8},
        "targets": [
          {
            "expr": "{job=\"security-logs\"} |~ \"Failed|error|attack\""
          }
        ]
      }
    ],
    "refresh": "5s",
    "time": {"from": "now-1h", "to": "now"}
  }
}
EOF

# Import dashboard via API
curl -X POST \
  http://admin:admin@localhost:3000/api/dashboards/db \
  -H 'Content-Type: application/json' \
  -d @/opt/security-dashboard.json

๐ŸŽฎ Quick Examples

Letโ€™s create specialized security dashboards! ๐Ÿ”ฅ

Example 1: Attack Map Dashboard

# Create geographic attack visualization
cat << 'EOF' > /opt/attack-map-collector.sh
#!/bin/bash
# Collect IP addresses and geolocate

FAILED_IPS=$(grep "Failed password" /var/log/secure | \
  awk '{print $11}' | \
  sort -u)

for IP in $FAILED_IPS; do
  # Get geolocation (requires geoiplookup)
  LOCATION=$(geoiplookup $IP 2>/dev/null | grep "GeoIP Country" | cut -d: -f2)
  echo "attack_source{ip=\"$IP\",country=\"$LOCATION\"} 1" >> /opt/attack-metrics.txt
done

# Expose metrics for Prometheus
cat /opt/attack-metrics.txt
EOF

chmod +x /opt/attack-map-collector.sh

Example 2: Real-time Threat Feed

# Create threat intelligence dashboard
cat << 'EOF' > /opt/threat-dashboard.py
#!/usr/bin/env python3
import json
import time
from flask import Flask, render_template
from flask_socketio import SocketIO, emit
import subprocess
import threading

app = Flask(__name__)
socketio = SocketIO(app)

def monitor_threats():
    """Monitor logs and emit threats in real-time"""
    proc = subprocess.Popen(['tail', '-F', '/var/log/secure'],
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE)
    
    while True:
        line = proc.stdout.readline().decode('utf-8')
        if 'Failed password' in line:
            threat = {
                'type': 'brute_force',
                'severity': 'high',
                'message': line.strip(),
                'timestamp': time.time()
            }
            socketio.emit('new_threat', threat, broadcast=True)
        elif 'sudo' in line:
            threat = {
                'type': 'privilege_escalation',
                'severity': 'medium',
                'message': line.strip(),
                'timestamp': time.time()
            }
            socketio.emit('new_threat', threat, broadcast=True)

@app.route('/')
def index():
    return '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>Real-time Threat Dashboard</title>
        <script src="https://cdn.socket.io/4.0.0/socket.io.min.js"></script>
        <style>
            .threat { padding: 10px; margin: 5px; border-radius: 5px; }
            .high { background: #ff4444; color: white; }
            .medium { background: #ffaa00; }
            .low { background: #44ff44; }
        </style>
    </head>
    <body>
        <h1>๐Ÿšจ Real-time Threat Feed</h1>
        <div id="threats"></div>
        <script>
            const socket = io();
            socket.on('new_threat', function(threat) {
                const div = document.createElement('div');
                div.className = 'threat ' + threat.severity;
                div.innerHTML = `<strong>${threat.type}</strong>: ${threat.message}`;
                document.getElementById('threats').prepend(div);
            });
        </script>
    </body>
    </html>
    '''

if __name__ == '__main__':
    # Start threat monitoring in background
    thread = threading.Thread(target=monitor_threats)
    thread.daemon = True
    thread.start()
    
    # Run web server
    socketio.run(app, host='0.0.0.0', port=5000)
EOF

# Install requirements
pip3 install flask flask-socketio

# Run threat dashboard
python3 /opt/threat-dashboard.py &

Example 3: Executive Security Dashboard

# Create executive summary dashboard
cat << 'EOF' > /opt/executive-dashboard.sh
#!/bin/bash
# Generate executive security metrics

generate_report() {
  cat << HTML > /var/www/html/executive-dashboard.html
<!DOCTYPE html>
<html>
<head>
  <title>Executive Security Dashboard</title>
  <meta http-equiv="refresh" content="30">
  <style>
    body { font-family: Arial; background: #1a1a1a; color: white; }
    .metric { 
      display: inline-block; 
      margin: 20px; 
      padding: 20px; 
      background: #2a2a2a; 
      border-radius: 10px; 
      text-align: center;
    }
    .value { font-size: 48px; font-weight: bold; }
    .label { font-size: 18px; color: #888; }
    .green { color: #4CAF50; }
    .yellow { color: #FFC107; }
    .red { color: #f44336; }
  </style>
</head>
<body>
  <h1>๐Ÿ›ก๏ธ Security Status - $(date)</h1>
  
  <div class="metric">
    <div class="value green">$(systemctl is-active firewalld | grep -c active)</div>
    <div class="label">Firewall Active</div>
  </div>
  
  <div class="metric">
    <div class="value yellow">$(grep -c "Failed password" /var/log/secure)</div>
    <div class="label">Failed Logins (24h)</div>
  </div>
  
  <div class="metric">
    <div class="value green">$(dnf check-update 2>/dev/null | grep -c "^$" || echo "0")</div>
    <div class="label">Pending Updates</div>
  </div>
  
  <div class="metric">
    <div class="value red">$(grep -c "CRITICAL" /var/log/messages)</div>
    <div class="label">Critical Events</div>
  </div>
  
  <div class="metric">
    <div class="value green">$(who | wc -l)</div>
    <div class="label">Active Users</div>
  </div>
  
  <div class="metric">
    <div class="value yellow">$(ss -tun | wc -l)</div>
    <div class="label">Network Connections</div>
  </div>
</body>
</html>
HTML
}

# Generate report every minute
while true; do
  generate_report
  sleep 60
done
EOF

chmod +x /opt/executive-dashboard.sh
/opt/executive-dashboard.sh &

๐Ÿšจ Fix Common Problems

Donโ€™t worry if dashboards donโ€™t work perfectly at first! Here are fixes! ๐Ÿ’ช

Problem 1: โ€œNo data showing in Grafanaโ€

# Solution: Check data sources
# Verify Prometheus is collecting data
curl http://localhost:9090/metrics

# Check Loki is receiving logs
curl http://localhost:3100/ready

# Add data sources in Grafana
curl -X POST http://admin:admin@localhost:3000/api/datasources \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Prometheus",
    "type": "prometheus",
    "url": "http://localhost:9090",
    "access": "proxy"
  }'

curl -X POST http://admin:admin@localhost:3000/api/datasources \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Loki",
    "type": "loki",
    "url": "http://localhost:3100",
    "access": "proxy"
  }'

Problem 2: โ€œDashboard too slowโ€

# Solution: Optimize queries and retention
# Reduce data retention
cat << EOF >> /opt/prometheus/prometheus.yml
storage:
  tsdb:
    retention.time: 7d
    retention.size: 5GB
EOF

# Optimize Grafana queries
# Use recording rules for complex queries
cat << EOF > /opt/prometheus/rules.yml
groups:
  - name: security_rules
    interval: 30s
    rules:
      - record: security:failed_logins:rate5m
        expr: rate(security_failed_logins[5m])
EOF

# Restart services
systemctl restart prometheus
systemctl restart grafana-server

Problem 3: โ€œAlerts not workingโ€

# Solution: Configure alerting
# Set up alert rules
cat << 'EOF' > /opt/grafana-alerts.json
{
  "alert": {
    "name": "High Failed Logins",
    "message": "Failed login attempts exceeded threshold",
    "conditions": [
      {
        "evaluator": {
          "params": [10],
          "type": "gt"
        },
        "query": {
          "model": "security_failed_logins",
          "params": ["5m", "now"]
        }
      }
    ],
    "notifications": [
      {
        "uid": "email-channel"
      }
    ]
  }
}
EOF

# Configure email notifications
cat << EOF >> /etc/grafana/grafana.ini
[smtp]
enabled = true
host = localhost:25
from_address = grafana@$(hostname)
EOF

systemctl restart grafana-server

๐Ÿ“‹ Simple Commands Summary

Your dashboard management cheat sheet! ๐Ÿ“Œ

ComponentURLDefault LoginPurpose
Grafanahttp://server:3000admin/adminDashboards
Prometheushttp://server:9090NoneMetrics
Lokihttp://server:3100NoneLogs
Customhttp://server:5000NoneThreat Feed

๐Ÿ’ก Tips for Success

Master security dashboards with these pro tips! ๐Ÿš€

Dashboard Design Principles

  • ๐ŸŽฏ Most important metrics at top
  • ๐ŸŽจ Use color coding (red=bad, green=good)
  • ๐Ÿ“Š Mix graph types for variety
  • โฑ๏ธ Auto-refresh critical dashboards

Essential Security Metrics

Authentication:
  - Failed login attempts
  - Successful logins
  - Password changes
  - Account lockouts

Network:
  - Active connections
  - Firewall blocks
  - Port scans detected
  - Data transfer volumes

System:
  - Process anomalies
  - File integrity changes
  - Service failures
  - Resource usage spikes

Performance Optimization

  • ๐Ÿ“Š Pre-aggregate common queries
  • ๐Ÿ’พ Limit data retention periods
  • ๐Ÿ”„ Use caching for static data
  • โšก Optimize database indexes

Integration Ideas

  • ๐Ÿ“ง Email dashboard snapshots daily
  • ๐Ÿ“ฑ Mobile-responsive dashboards
  • ๐Ÿ”” Slack/Teams notifications
  • ๐Ÿ“บ TV display mode for SOC

๐Ÿ† What You Learned

Incredible work! Youโ€™ve built a professional security monitoring center! ๐ŸŽŠ

  • โœ… Installed and configured Grafana stack
  • โœ… Set up Prometheus metrics collection
  • โœ… Configured Loki log aggregation
  • โœ… Built custom security metrics exporter
  • โœ… Created beautiful security dashboards
  • โœ… Implemented real-time threat visualization
  • โœ… Built executive summary dashboards
  • โœ… Set up alerting and notifications
  • โœ… Optimized dashboard performance
  • โœ… Created enterprise-grade monitoring

๐ŸŽฏ Why This Matters

Youโ€™ve transformed security monitoring from reactive to proactive! ๐Ÿ‘๏ธ No more staring at log files or missing critical events. Your dashboards provide instant situational awareness, making it impossible for threats to hide.

This isnโ€™t just pretty pictures - itโ€™s actionable intelligence. You can now spot attack patterns, track security metrics, prove compliance, and respond to incidents faster. Your security posture is visible to everyone from analysts to executives.

Your AlmaLinux infrastructure now has enterprise-grade security visualization that rivals commercial SOC platforms. You built this with open-source tools and your own creativity! ๐ŸŽจ

Keep visualizing, keep monitoring, and remember - a picture is worth a thousand log lines! Youโ€™ve got this! โญ

Happy dashboarding, AlmaLinux security artist! ๐Ÿ™Œ