186 أسطر
4.2 KiB
Bash
ملف تنفيذي
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 "=================================================="
|