CalejoControl/scripts/security_audit.sh

313 lines
9.3 KiB
Bash

#!/bin/bash
# Calejo Control Adapter Security Audit Script
# This script performs basic security checks on the deployment
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging functions
log() {
echo -e "${GREEN}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}
warn() {
echo -e "${YELLOW}[$(date +'%Y-%m-%d %H:%M:%S')] WARNING:${NC} $1"
}
error() {
echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] ERROR:${NC} $1"
}
info() {
echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')] INFO:${NC} $1"
}
# Function to check if command exists
command_exists() {
command -v "$1" >/dev/null 2>&1
}
# Function to check Docker security
check_docker_security() {
log "Checking Docker security..."
if command_exists docker; then
# Check if containers are running as root
local containers=$(docker ps --format "table {{.Names}}\t{{.Image}}\t{{.RunningFor}}")
if echo "$containers" | grep -q "root"; then
warn "Some containers may be running as root"
else
log "✓ Containers not running as root"
fi
# Check for exposed ports
local exposed_ports=$(docker ps --format "table {{.Names}}\t{{.Ports}}")
if echo "$exposed_ports" | grep -q "0.0.0.0"; then
warn "Some containers have ports exposed to all interfaces"
else
log "✓ Container ports properly configured"
fi
else
info "Docker not found, skipping Docker checks"
fi
}
# Function to check network security
check_network_security() {
log "Checking network security..."
# Check if firewall is active
if command_exists ufw; then
if ufw status | grep -q "Status: active"; then
log "✓ Firewall (ufw) is active"
else
warn "Firewall (ufw) is not active"
fi
elif command_exists firewall-cmd; then
if firewall-cmd --state 2>/dev/null | grep -q "running"; then
log "✓ Firewall (firewalld) is active"
else
warn "Firewall (firewalld) is not active"
fi
else
warn "No firewall management tool detected"
fi
# Check for open ports
if command_exists netstat; then
local open_ports=$(netstat -tulpn 2>/dev/null | grep LISTEN)
if echo "$open_ports" | grep -q ":8080\|:4840\|:502\|:9090"; then
log "✓ Application ports are listening"
fi
elif command_exists ss; then
local open_ports=$(ss -tulpn 2>/dev/null | grep LISTEN)
if echo "$open_ports" | grep -q ":8080\|:4840\|:502\|:9090"; then
log "✓ Application ports are listening"
fi
fi
}
# Function to check application security
check_application_security() {
log "Checking application security..."
# Check if application is running
if curl -f http://localhost:8080/health >/dev/null 2>&1; then
log "✓ Application is running and responding"
# Check health endpoint
local health_status=$(curl -s http://localhost:8080/health | grep -o '"status":"[^"]*' | cut -d'"' -f4)
if [ "$health_status" = "healthy" ]; then
log "✓ Application health status: $health_status"
else
warn "Application health status: $health_status"
fi
# Check if metrics endpoint is accessible
if curl -f http://localhost:8080/metrics >/dev/null 2>&1; then
log "✓ Metrics endpoint is accessible"
else
warn "Metrics endpoint is not accessible"
fi
else
error "Application is not running or not accessible"
fi
# Check for default credentials
if [ -f ".env" ]; then
if grep -q "your-secret-key-change-in-production" .env; then
error "Default JWT secret key found in .env"
else
log "✓ JWT secret key appears to be customized"
fi
if grep -q "your-api-key-here" .env; then
error "Default API key found in .env"
else
log "✓ API key appears to be customized"
fi
if grep -q "password" .env && grep -q "postgresql://calejo:password" .env; then
warn "Default database password found in .env"
else
log "✓ Database password appears to be customized"
fi
else
warn ".env file not found, cannot check credentials"
fi
}
# Function to check file permissions
check_file_permissions() {
log "Checking file permissions..."
# Check for world-writable files
local world_writable=$(find . -type f -perm -o+w 2>/dev/null | head -10)
if [ -n "$world_writable" ]; then
warn "World-writable files found:"
echo "$world_writable"
else
log "✓ No world-writable files found"
fi
# Check for sensitive files
if [ -f ".env" ] && [ "$(stat -c %a .env 2>/dev/null)" = "644" ]; then
log "✓ .env file has secure permissions"
elif [ -f ".env" ]; then
warn ".env file permissions: $(stat -c %a .env 2>/dev/null)"
fi
}
# Function to check database security
check_database_security() {
log "Checking database security..."
if command_exists docker-compose && docker-compose ps | grep -q postgres; then
# Check if PostgreSQL is listening on localhost only
local pg_listen=$(docker-compose exec postgres psql -U calejo -c "SHOW listen_addresses;" -t 2>/dev/null | tr -d ' ')
if [ "$pg_listen" = "localhost" ]; then
log "✓ PostgreSQL listening on localhost only"
else
warn "PostgreSQL listening on: $pg_listen"
fi
# Check if SSL is enabled
local ssl_enabled=$(docker-compose exec postgres psql -U calejo -c "SHOW ssl;" -t 2>/dev/null | tr -d ' ')
if [ "$ssl_enabled" = "on" ]; then
log "✓ PostgreSQL SSL enabled"
else
warn "PostgreSQL SSL disabled"
fi
else
info "PostgreSQL container not found, skipping database checks"
fi
}
# Function to check monitoring security
check_monitoring_security() {
log "Checking monitoring security..."
# Check if Prometheus is accessible
if curl -f http://localhost:9091 >/dev/null 2>&1; then
log "✓ Prometheus is accessible"
else
info "Prometheus is not accessible (may be expected)"
fi
# Check if Grafana is accessible
if curl -f http://localhost:3000 >/dev/null 2>&1; then
log "✓ Grafana is accessible"
# Check if default credentials are changed
if curl -u admin:admin http://localhost:3000/api/user/preferences >/dev/null 2>&1; then
error "Grafana default credentials (admin/admin) are still in use"
else
log "✓ Grafana default credentials appear to be changed"
fi
else
info "Grafana is not accessible (may be expected)"
fi
}
# Function to generate security report
generate_report() {
log "Generating security audit report..."
local report_file="security_audit_report_$(date +%Y%m%d_%H%M%S).txt"
cat > "$report_file" << EOF
Calejo Control Adapter Security Audit Report
============================================
Audit Date: $(date)
System: $(uname -a)
Summary:
--------
$(date): Security audit completed
Findings:
---------
EOF
# Run checks and append to report
{
echo "\nDocker Security:"
check_docker_security 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
echo "\nNetwork Security:"
check_network_security 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
echo "\nApplication Security:"
check_application_security 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
echo "\nFile Permissions:"
check_file_permissions 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
echo "\nDatabase Security:"
check_database_security 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
echo "\nMonitoring Security:"
check_monitoring_security 2>&1 | sed 's/\x1b\[[0-9;]*m//g'
} >> "$report_file"
log "Security audit report saved to: $report_file"
# Show summary
echo
echo "=== SECURITY AUDIT SUMMARY ==="
grep -E "(✓|WARNING|ERROR):" "$report_file" | tail -20
}
# Main function
main() {
echo "Calejo Control Adapter Security Audit"
echo "====================================="
echo
# Run all security checks
check_docker_security
check_network_security
check_application_security
check_file_permissions
check_database_security
check_monitoring_security
# Generate report
generate_report
echo
log "Security audit completed"
echo
echo "Recommendations:"
echo "1. Review and address all warnings and errors"
echo "2. Change default credentials if found"
echo "3. Ensure firewall is properly configured"
echo "4. Regular security audits are recommended"
}
# Parse command line arguments
case "${1:-}" in
--help|-h)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --help, -h Show this help message"
echo ""
echo "This script performs a security audit of the Calejo Control Adapter deployment."
exit 0
;;
*)
main
;;
esac