الملفات
ghaymah-exam-mahmoud-secops/q1-security-audit/security-audit.sh
2026-07-27 00:08:02 +03:00

186 أسطر
4.2 KiB
Bash
ملف تنفيذي

#!/usr/bin/env bash
# security-audit.sh
# Security audit script for applications hosted on Ghaymah or any VPS/PaaS environment.
# Checks:
# 1. Open ports
# 2. SSL certificate status
# 3. Sensitive file permissions
set -euo pipefail
DOMAIN="${1:-}"
PORT="${2:-443}"
APP_DIR="${3:-.}"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
pass() {
echo -e "${GREEN}[OK]${NC} $1"
}
warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
fail() {
echo -e "${RED}[FAIL]${NC} $1"
}
echo "=================================================="
echo " Automated Security Audit - $(date '+%Y-%m-%d %H:%M:%S')"
echo "=================================================="
# --------------------------------------------------
# 1. Open Ports Check
# --------------------------------------------------
echo
echo "---- Checking Open Ports ----"
if command -v ss >/dev/null 2>&1; then
OPEN_PORTS=$(ss -tuln | awk 'NR>1 {print $5}' | sed -E 's/.*:([0-9]+)$/\1/' | sort -un)
elif command -v netstat >/dev/null 2>&1; then
OPEN_PORTS=$(netstat -tuln | awk 'NR>2 {print $4}' | sed -E 's/.*:([0-9]+)$/\1/' | sort -un)
else
warn "Neither ss nor netstat is available. Skipping port check."
OPEN_PORTS=""
fi
ALLOWED_PORTS="22 80 443"
if [ -n "$OPEN_PORTS" ]; then
echo "Open ports: $OPEN_PORTS"
for port in $OPEN_PORTS; do
if echo "$ALLOWED_PORTS" | grep -qw "$port"; then
pass "Port $port is allowed"
else
warn "Port $port is open and not in the allowed list"
fi
done
else
warn "No ports detected"
fi
# --------------------------------------------------
# 2. SSL Certificate Check
# --------------------------------------------------
echo
echo "---- Checking SSL Certificate ----"
if [ -z "$DOMAIN" ]; then
warn "No domain provided. Skipping SSL check."
else
if command -v openssl >/dev/null 2>&1; then
CERT_INFO=$(echo | timeout 10 openssl s_client \
-connect "${DOMAIN}:${PORT}" \
-servername "$DOMAIN" 2>/dev/null | \
openssl x509 -noout -dates -issuer -subject 2>/dev/null) || true
if [ -z "$CERT_INFO" ]; then
fail "Unable to retrieve SSL certificate"
else
echo "$CERT_INFO"
EXPIRY_DATE=$(echo "$CERT_INFO" | grep "notAfter" | cut -d= -f2)
if [ -n "$EXPIRY_DATE" ]; then
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s 2>/dev/null || echo 0)
CURRENT_EPOCH=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_EPOCH - CURRENT_EPOCH) / 86400 ))
if [ "$DAYS_LEFT" -lt 0 ]; then
fail "SSL certificate expired"
elif [ "$DAYS_LEFT" -lt 30 ]; then
warn "SSL certificate expires in $DAYS_LEFT days"
else
pass "SSL certificate valid for $DAYS_LEFT days"
fi
fi
fi
else
warn "OpenSSL is not installed"
fi
fi
# --------------------------------------------------
# 3. Sensitive File Permissions Check
# --------------------------------------------------
echo
echo "---- Checking Sensitive File Permissions ----"
SENSITIVE_FILES=(
".env"
"*.pem"
"*.key"
"id_rsa"
"config/secrets*"
)
for pattern in "${SENSITIVE_FILES[@]}"; do
while IFS= read -r -d '' file; do
PERMISSIONS=$(stat -c "%a" "$file" 2>/dev/null || stat -f "%A" "$file")
if [ -n "$PERMISSIONS" ]; then
LAST_DIGIT="${PERMISSIONS: -1}"
if [ "$LAST_DIGIT" -ge 4 ] 2>/dev/null; then
fail "$file has insecure permissions ($PERMISSIONS)"
else
pass "$file permissions are secure ($PERMISSIONS)"
fi
fi
done < <(find "$APP_DIR" -type f -iname "$pattern" -print0 2>/dev/null)
done
echo
echo "Checking world-writable files..."
WORLD_WRITABLE=$(find "$APP_DIR" -type f -perm -o+w 2>/dev/null | grep -v "/.git/" || true)
if [ -n "$WORLD_WRITABLE" ]; then
fail "World-writable files found:"
echo "$WORLD_WRITABLE"
else
pass "No world-writable files found."
fi
echo
echo "=================================================="
echo " Security Audit Completed"
echo "=================================================="