Files
servers_security_sys/system_check.sh
2026-02-05 13:22:27 +03:00

464 lines
17 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/bin/bash
# ════════════════════════════════════════════════════════════════
# 🔍 TRIPZ FORTRESS v8.2 - Comprehensive System Check
# ════════════════════════════════════════════════════════════════
# استخدم هذا السكريبت لفحص حالة النظام الأمني بالكامل
# ════════════════════════════════════════════════════════════════
set -euo pipefail
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
NC='\033[0m'
# Counters
TOTAL_CHECKS=0
PASSED_CHECKS=0
FAILED_CHECKS=0
WARNING_CHECKS=0
# Functions
check_pass() {
echo -e "${GREEN}$1${NC}"
((PASSED_CHECKS++))
((TOTAL_CHECKS++))
}
check_fail() {
echo -e "${RED}$1${NC}"
((FAILED_CHECKS++))
((TOTAL_CHECKS++))
}
check_warn() {
echo -e "${YELLOW}⚠️ $1${NC}"
((WARNING_CHECKS++))
((TOTAL_CHECKS++))
}
info() {
echo -e "${CYAN} $1${NC}"
}
section() {
echo ""
echo -e "${BLUE}════════════════════════════════════════════════════════${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}════════════════════════════════════════════════════════${NC}"
}
# Main
clear
cat <<'BANNER'
════════════════════════════════════════════════════════════════
🔍 TRIPZ FORTRESS v8.2 - System Health Check
════════════════════════════════════════════════════════════════
BANNER
echo ""
info "Starting comprehensive system check..."
info "Date: $(date '+%Y-%m-%d %H:%M:%S')"
info "Hostname: $(hostname)"
echo ""
# ════════════════════════════════════════════════════════════════
# 1. BASIC SYSTEM INFO
# ════════════════════════════════════════════════════════════════
section "1⃣ BASIC SYSTEM INFORMATION"
# OS Info
if [ -f /etc/os-release ]; then
OS_NAME=$(grep PRETTY_NAME /etc/os-release | cut -d'"' -f2)
info "Operating System: $OS_NAME"
check_pass "OS detected"
else
check_fail "Cannot detect OS"
fi
# Kernel
KERNEL=$(uname -r)
info "Kernel: $KERNEL"
check_pass "Kernel detected"
# Uptime
UPTIME=$(uptime -p)
info "Uptime: $UPTIME"
# Resources
MEMORY_TOTAL=$(free -h | awk '/^Mem:/ {print $2}')
MEMORY_USED=$(free -h | awk '/^Mem:/ {print $3}')
MEMORY_PERCENT=$(free | awk '/^Mem:/ {printf "%.0f", $3/$2 * 100}')
info "Memory: $MEMORY_USED / $MEMORY_TOTAL (${MEMORY_PERCENT}%)"
if [ "$MEMORY_PERCENT" -lt 80 ]; then
check_pass "Memory usage OK"
elif [ "$MEMORY_PERCENT" -lt 90 ]; then
check_warn "Memory usage high: ${MEMORY_PERCENT}%"
else
check_fail "Memory usage critical: ${MEMORY_PERCENT}%"
fi
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
DISK_USED=$(df -h / | awk 'NR==2 {print $3}')
DISK_TOTAL=$(df -h / | awk 'NR==2 {print $2}')
info "Disk: $DISK_USED / $DISK_TOTAL (${DISK_USAGE}%)"
if [ "$DISK_USAGE" -lt 80 ]; then
check_pass "Disk usage OK"
elif [ "$DISK_USAGE" -lt 90 ]; then
check_warn "Disk usage high: ${DISK_USAGE}%"
else
check_fail "Disk usage critical: ${DISK_USAGE}%"
fi
# ════════════════════════════════════════════════════════════════
# 2. NETWORK CONNECTIVITY
# ════════════════════════════════════════════════════════════════
section "2⃣ NETWORK CONNECTIVITY"
# Internet
if ping -c 2 8.8.8.8 &>/dev/null; then
check_pass "Internet connectivity"
else
check_fail "No internet connection"
fi
# DNS
if ping -c 2 google.com &>/dev/null; then
check_pass "DNS resolution"
else
check_fail "DNS resolution failed"
fi
# External IP
EXTERNAL_IP=$(curl -s ifconfig.me 2>/dev/null || echo "unknown")
info "External IP: $EXTERNAL_IP"
# ════════════════════════════════════════════════════════════════
# 3. SECURITY SERVICES
# ════════════════════════════════════════════════════════════════
section "3⃣ SECURITY SERVICES"
# SSH
if systemctl is-active --quiet sshd; then
check_pass "SSH (sshd) active"
# SSH Config
SSH_PORT=$(grep -E "^Port " /etc/ssh/sshd_config | awk '{print $2}' || echo "22")
info "SSH Port: $SSH_PORT"
if [ "$SSH_PORT" != "22" ]; then
check_pass "SSH port changed from default"
else
check_warn "SSH still on default port 22"
fi
# Password Authentication
if grep -q "^PasswordAuthentication no" /etc/ssh/sshd_config; then
check_pass "Password authentication disabled"
else
check_warn "Password authentication enabled"
fi
# Root Login
if grep -q "^PermitRootLogin no" /etc/ssh/sshd_config; then
check_pass "Root login disabled"
else
check_warn "Root login enabled"
fi
else
check_fail "SSH (sshd) not running"
fi
# UFW
if systemctl is-active --quiet ufw; then
check_pass "UFW firewall active"
UFW_STATUS=$(ufw status | head -1 | awk '{print $2}')
if [ "$UFW_STATUS" == "active" ]; then
check_pass "UFW enabled"
else
check_fail "UFW not enabled"
fi
else
check_fail "UFW not installed/running"
fi
# Fail2Ban
if systemctl is-active --quiet fail2ban 2>/dev/null; then
check_pass "Fail2Ban active"
# Banned IPs
if command -v fail2ban-client &>/dev/null; then
BANNED_COUNT=$(fail2ban-client status sshd 2>/dev/null | grep "Currently banned:" | awk '{print $4}' || echo "0")
info "Currently banned IPs: $BANNED_COUNT"
fi
else
check_warn "Fail2Ban not active (optional but recommended)"
fi
# Knockd (Port Knocking)
if systemctl is-active --quiet knockd 2>/dev/null; then
check_pass "Port Knocking (knockd) active"
if [ -f /etc/knockd.conf ]; then
KNOCK_SEQ=$(grep -A 1 "\[openSSH\]" /etc/knockd.conf | grep sequence | awk '{print $3}')
info "Knock sequence: $KNOCK_SEQ"
fi
else
check_warn "Port Knocking not active (optional)"
fi
# Endlessh (Honeypot)
if systemctl is-active --quiet endlessh 2>/dev/null; then
check_pass "Endlessh honeypot active"
else
check_warn "Endlessh honeypot not active (optional)"
fi
# Fake MySQL
if systemctl is-active --quiet fake-mysql 2>/dev/null; then
check_pass "Fake MySQL trap active"
else
check_warn "Fake MySQL trap not active (optional)"
fi
# ════════════════════════════════════════════════════════════════
# 4. SYSTEM HARDENING
# ════════════════════════════════════════════════════════════════
section "4⃣ SYSTEM HARDENING"
# sysctl checks
if grep -q "net.ipv4.tcp_syncookies = 1" /etc/sysctl.conf; then
check_pass "SYN flood protection enabled"
else
check_warn "SYN flood protection not configured"
fi
if grep -q "net.ipv4.conf.all.rp_filter = 1" /etc/sysctl.conf; then
check_pass "Reverse path filtering enabled"
else
check_warn "Reverse path filtering not configured"
fi
if grep -q "kernel.kptr_restrict = 2" /etc/sysctl.conf; then
check_pass "Kernel pointer protection enabled"
else
check_warn "Kernel pointer protection not configured"
fi
# ════════════════════════════════════════════════════════════════
# 5. USERS & AUTHENTICATION
# ════════════════════════════════════════════════════════════════
section "5⃣ USERS & AUTHENTICATION"
# Admin user
ADMIN_USER=$(grep -E "^AllowUsers" /etc/ssh/sshd_config | awk '{print $2}' || echo "unknown")
if [ "$ADMIN_USER" != "unknown" ]; then
info "Admin user: $ADMIN_USER"
check_pass "Admin user configured"
# Check sudo access
if [ -f "/etc/sudoers.d/$ADMIN_USER" ]; then
check_pass "Sudo access configured"
fi
else
check_warn "No specific admin user configured"
fi
# Check for users with UID 0 (root equivalents)
ROOT_USERS=$(awk -F: '$3 == 0 {print $1}' /etc/passwd | grep -v "^root$" | wc -l)
if [ "$ROOT_USERS" -eq 0 ]; then
check_pass "No additional UID 0 users"
else
check_warn "Found $ROOT_USERS additional UID 0 users"
fi
# ════════════════════════════════════════════════════════════════
# 6. BACKUPS
# ════════════════════════════════════════════════════════════════
section "6⃣ BACKUP SYSTEM"
# Check backup directory
if [ -d "/backup/fortress" ]; then
check_pass "Backup directory exists"
# Count backups
BACKUP_COUNT=$(ls -1 /backup/fortress/*.enc 2>/dev/null | wc -l || echo "0")
info "Backup files: $BACKUP_COUNT"
if [ "$BACKUP_COUNT" -gt 0 ]; then
check_pass "Backups found"
# Last backup
LAST_BACKUP=$(ls -t /backup/fortress/*.enc 2>/dev/null | head -1)
if [ -n "$LAST_BACKUP" ]; then
LAST_BACKUP_DATE=$(stat -c %y "$LAST_BACKUP" | cut -d' ' -f1)
info "Last backup: $LAST_BACKUP_DATE"
# Check if recent (within 2 days)
DAYS_SINCE_BACKUP=$(( ($(date +%s) - $(stat -c %Y "$LAST_BACKUP")) / 86400 ))
if [ "$DAYS_SINCE_BACKUP" -le 2 ]; then
check_pass "Recent backup available"
else
check_warn "Last backup is $DAYS_SINCE_BACKUP days old"
fi
fi
else
check_warn "No backups found"
fi
else
check_warn "Backup directory not found"
fi
# Check cron job
if crontab -l 2>/dev/null | grep -q "fortress/backup.sh"; then
check_pass "Backup cron job configured"
else
check_warn "No backup cron job found"
fi
# ════════════════════════════════════════════════════════════════
# 7. MONITORING & LOGGING
# ════════════════════════════════════════════════════════════════
section "7⃣ MONITORING & LOGGING"
# Log directory
if [ -d "/var/log/fortress" ]; then
check_pass "Fortress log directory exists"
LOG_SIZE=$(du -sh /var/log/fortress 2>/dev/null | awk '{print $1}')
info "Log directory size: $LOG_SIZE"
else
check_warn "Fortress log directory not found"
fi
# Check for large log files
LARGE_LOGS=$(find /var/log -type f -size +100M 2>/dev/null | wc -l)
if [ "$LARGE_LOGS" -gt 0 ]; then
check_warn "Found $LARGE_LOGS log files >100MB"
else
check_pass "No excessively large log files"
fi
# Telegram notifications
if [ -x "/usr/local/bin/fortress/telegram_notify.sh" ]; then
check_pass "Telegram notification script available"
else
check_warn "Telegram notifications not configured"
fi
# ════════════════════════════════════════════════════════════════
# 8. OPEN PORTS
# ════════════════════════════════════════════════════════════════
section "8⃣ OPEN PORTS"
info "Listening ports:"
ss -tuln | grep LISTEN | awk '{print " " $5}' | sort -u
# Critical ports check
CRITICAL_PORTS=("22" "80" "443")
for port in "${CRITICAL_PORTS[@]}"; do
if ss -tuln | grep -q ":$port "; then
info "Port $port is listening"
fi
done
# ════════════════════════════════════════════════════════════════
# 9. SECURITY ADVISORIES
# ════════════════════════════════════════════════════════════════
section "9⃣ SECURITY RECOMMENDATIONS"
RECOMMENDATIONS=()
# Check if running as root unnecessarily
if [ "$(id -u)" -eq 0 ]; then
RECOMMENDATIONS+=("⚠️ Don't run routine tasks as root - use sudo when needed")
fi
# Check SSH on default port
if ss -tuln | grep -q ":22 " && ! systemctl is-active --quiet endlessh; then
RECOMMENDATIONS+=("⚠️ SSH on port 22 without honeypot - consider using Port Knocking")
fi
# Check for pending updates
if command -v apt &>/dev/null; then
PENDING_UPDATES=$(apt list --upgradable 2>/dev/null | grep -c "upgradable" || echo "0")
if [ "$PENDING_UPDATES" -gt 0 ]; then
RECOMMENDATIONS+=("⚠️ $PENDING_UPDATES pending system updates - run: sudo apt update && sudo apt upgrade")
fi
fi
# Display recommendations
if [ ${#RECOMMENDATIONS[@]} -gt 0 ]; then
echo ""
for rec in "${RECOMMENDATIONS[@]}"; do
echo -e "${YELLOW}$rec${NC}"
done
else
check_pass "No critical recommendations"
fi
# ════════════════════════════════════════════════════════════════
# 10. FINAL SUMMARY
# ════════════════════════════════════════════════════════════════
section "📊 FINAL SUMMARY"
echo ""
echo -e "${CYAN}Total Checks: $TOTAL_CHECKS${NC}"
echo -e "${GREEN}Passed: $PASSED_CHECKS${NC}"
echo -e "${RED}Failed: $FAILED_CHECKS${NC}"
echo -e "${YELLOW}Warnings: $WARNING_CHECKS${NC}"
echo ""
# Calculate score
SCORE=$(( (PASSED_CHECKS * 100) / TOTAL_CHECKS ))
if [ "$SCORE" -ge 90 ]; then
echo -e "${GREEN}═══════════════════════════════════════════════════════${NC}"
echo -e "${GREEN}✅ EXCELLENT SECURITY POSTURE (Score: $SCORE%)${NC}"
echo -e "${GREEN}═══════════════════════════════════════════════════════${NC}"
elif [ "$SCORE" -ge 70 ]; then
echo -e "${YELLOW}═══════════════════════════════════════════════════════${NC}"
echo -e "${YELLOW}⚠️ GOOD SECURITY, SOME IMPROVEMENTS NEEDED (Score: $SCORE%)${NC}"
echo -e "${YELLOW}═══════════════════════════════════════════════════════${NC}"
else
echo -e "${RED}═══════════════════════════════════════════════════════${NC}"
echo -e "${RED}❌ SECURITY NEEDS ATTENTION (Score: $SCORE%)${NC}"
echo -e "${RED}═══════════════════════════════════════════════════════${NC}"
fi
echo ""
info "Check completed at: $(date '+%Y-%m-%d %H:%M:%S')"
info "For detailed logs, check: /var/log/fortress/"
echo ""
# ════════════════════════════════════════════════════════════════
# Exit with appropriate code
# ════════════════════════════════════════════════════════════════
if [ "$FAILED_CHECKS" -gt 0 ]; then
exit 1
elif [ "$WARNING_CHECKS" -gt 3 ]; then
exit 2
else
exit 0
fi