🔍 Log Analysis & Security Scripts
Các scripts trong phần này giúp bạn phân tích log hệ thống, giám sát bảo mật và phát hiện các hoạt động bất thường một cách tự động.
📊 1. Script Phân Tích Log Tự Động
Comprehensive Log Analyzer
#!/bin/bash
# log_analyzer.sh - Phân tích log hệ thống tự động
# Cấu hình
LOG_DIR="/var/log"
REPORT_DIR="/var/log/analysis"
ALERT_EMAIL="[email protected]"
DATE=$(date +"%Y%m%d")
REPORT_FILE="$REPORT_DIR/log_analysis_$DATE.txt"
ALERT_THRESHOLD=50 # Số lượng events bất thường để gửi cảnh báo
# Tạo thư mục report
mkdir -p "$REPORT_DIR"
# Hàm ghi log
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$REPORT_FILE"
}
# Hàm gửi cảnh báo
send_alert() {
local subject="$1"
local message="$2"
echo "$message" | mail -s "[SECURITY ALERT] $subject" "$ALERT_EMAIL"
log_message "ALERT SENT: $subject"
}
# Hàm phân tích SSH logs
analyze_ssh_logs() {
log_message "=== SSH LOG ANALYSIS ==="
local ssh_log="/var/log/auth.log"
if [ ! -f "$ssh_log" ]; then
ssh_log="/var/log/secure" # CentOS/RHEL
fi
if [ -f "$ssh_log" ]; then
# Failed login attempts
local failed_logins=$(grep "Failed password" "$ssh_log" | grep "$(date +%b\ %d)" | wc -l)
log_message "Failed SSH logins today: $failed_logins"
if [ "$failed_logins" -gt "$ALERT_THRESHOLD" ]; then
local top_ips=$(grep "Failed password" "$ssh_log" | grep "$(date +%b\ %d)" | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -5)
send_alert "High SSH Failed Logins" "Failed SSH logins: $failed_logins\n\nTop attacking IPs:\n$top_ips"
fi
# Successful logins
local successful_logins=$(grep "Accepted password" "$ssh_log" | grep "$(date +%b\ %d)" | wc -l)
log_message "Successful SSH logins today: $successful_logins"
# Root login attempts
local root_attempts=$(grep "root" "$ssh_log" | grep "$(date +%b\ %d)" | wc -l)
if [ "$root_attempts" -gt 0 ]; then
log_message "WARNING: Root login attempts today: $root_attempts"
local root_details=$(grep "root" "$ssh_log" | grep "$(date +%b\ %d)" | tail -10)
send_alert "Root Login Attempts" "Root login attempts: $root_attempts\n\nDetails:\n$root_details"
fi
# Unusual login times (outside 6 AM - 10 PM)
local unusual_logins=$(grep "Accepted password" "$ssh_log" | grep "$(date +%b\ %d)" | awk '{print $3}' | awk -F: '{if($1<6 || $1>22) print}' | wc -l)
if [ "$unusual_logins" -gt 0 ]; then
log_message "WARNING: Unusual time logins: $unusual_logins"
fi
else
log_message "SSH log file not found"
fi
}
# Hàm phân tích Web server logs
analyze_web_logs() {
log_message "=== WEB SERVER LOG ANALYSIS ==="
local access_log="/var/log/nginx/access.log"
local error_log="/var/log/nginx/error.log"
# Kiểm tra Apache logs nếu Nginx không có
if [ ! -f "$access_log" ]; then
access_log="/var/log/apache2/access.log"
error_log="/var/log/apache2/error.log"
fi
if [ -f "$access_log" ]; then
# Top IPs
log_message "Top 10 IP addresses:"
awk '{print $1}' "$access_log" | sort | uniq -c | sort -nr | head -10 | tee -a "$REPORT_FILE"
# 404 errors
local error_404=$(grep " 404 " "$access_log" | wc -l)
log_message "404 errors today: $error_404"
if [ "$error_404" -gt 100 ]; then
local top_404=$(grep " 404 " "$access_log" | awk '{print $7}' | sort | uniq -c | sort -nr | head -10)
log_message "Top 404 URLs:\n$top_404"
fi
# Potential attacks
local sql_injection=$(grep -i "union\|select\|insert\|delete\|drop" "$access_log" | wc -l)
local xss_attempts=$(grep -i "script\|javascript\|alert" "$access_log" | wc -l)
local path_traversal=$(grep "\.\." "$access_log" | wc -l)
log_message "Potential SQL injection attempts: $sql_injection"
log_message "Potential XSS attempts: $xss_attempts"
log_message "Path traversal attempts: $path_traversal"
if [ "$sql_injection" -gt 10 ] || [ "$xss_attempts" -gt 10 ] || [ "$path_traversal" -gt 10 ]; then
send_alert "Web Attack Detected" "SQL injection: $sql_injection\nXSS attempts: $xss_attempts\nPath traversal: $path_traversal"
fi
# Large requests (potential DoS)
local large_requests=$(awk '{if($10 > 1000000) print}' "$access_log" | wc -l)
if [ "$large_requests" -gt 0 ]; then
log_message "WARNING: Large requests detected: $large_requests"
fi
else
log_message "Web server access log not found"
fi
# Error log analysis
if [ -f "$error_log" ]; then
local today_errors=$(grep "$(date +%Y/%m/%d)" "$error_log" | wc -l)
log_message "Web server errors today: $today_errors"
if [ "$today_errors" -gt 50 ]; then
local error_summary=$(grep "$(date +%Y/%m/%d)" "$error_log" | tail -20)
send_alert "High Web Server Errors" "Errors today: $today_errors\n\nRecent errors:\n$error_summary"
fi
fi
}
# Hàm phân tích System logs
analyze_system_logs() {
log_message "=== SYSTEM LOG ANALYSIS ==="
# Syslog analysis
local syslog="/var/log/syslog"
if [ ! -f "$syslog" ]; then
syslog="/var/log/messages" # CentOS/RHEL
fi
if [ -f "$syslog" ]; then
# Error messages
local system_errors=$(grep -i "error\|fail\|critical" "$syslog" | grep "$(date +%b\ %d)" | wc -l)
log_message "System errors today: $system_errors"
if [ "$system_errors" -gt 20 ]; then
local error_details=$(grep -i "error\|fail\|critical" "$syslog" | grep "$(date +%b\ %d)" | tail -10)
send_alert "High System Errors" "System errors: $system_errors\n\nRecent errors:\n$error_details"
fi
# Kernel messages
local kernel_errors=$(grep "kernel:" "$syslog" | grep "$(date +%b\ %d)" | grep -i "error\|fail" | wc -l)
if [ "$kernel_errors" -gt 0 ]; then
log_message "WARNING: Kernel errors today: $kernel_errors"
local kernel_details=$(grep "kernel:" "$syslog" | grep "$(date +%b\ %d)" | grep -i "error\|fail" | tail -5)
log_message "Kernel error details:\n$kernel_details"
fi
# OOM (Out of Memory) events
local oom_events=$(grep "Out of memory" "$syslog" | grep "$(date +%b\ %d)" | wc -l)
if [ "$oom_events" -gt 0 ]; then
log_message "CRITICAL: OOM events today: $oom_events"
send_alert "Out of Memory Events" "OOM events detected: $oom_events"
fi
else
log_message "System log file not found"
fi
}
# Hàm phân tích Database logs
analyze_database_logs() {
log_message "=== DATABASE LOG ANALYSIS ==="
# MySQL logs
local mysql_error_log="/var/log/mysql/error.log"
if [ -f "$mysql_error_log" ]; then
local mysql_errors=$(grep "$(date +%Y-%m-%d)" "$mysql_error_log" | grep -i "error\|warning" | wc -l)
log_message "MySQL errors/warnings today: $mysql_errors"
if [ "$mysql_errors" -gt 10 ]; then
local mysql_details=$(grep "$(date +%Y-%m-%d)" "$mysql_error_log" | grep -i "error\|warning" | tail -10)
send_alert "MySQL Errors" "MySQL errors: $mysql_errors\n\nDetails:\n$mysql_details"
fi
# Connection issues
local connection_errors=$(grep "$(date +%Y-%m-%d)" "$mysql_error_log" | grep -i "connection\|timeout" | wc -l)
if [ "$connection_errors" -gt 5 ]; then
log_message "WARNING: MySQL connection issues: $connection_errors"
fi
fi
# PostgreSQL logs
local pg_log_dir="/var/log/postgresql"
if [ -d "$pg_log_dir" ]; then
local pg_log=$(find "$pg_log_dir" -name "*.log" -mtime -1 | head -1)
if [ -n "$pg_log" ]; then
local pg_errors=$(grep "$(date +%Y-%m-%d)" "$pg_log" | grep -i "error\|fatal" | wc -l)
log_message "PostgreSQL errors today: $pg_errors"
if [ "$pg_errors" -gt 10 ]; then
local pg_details=$(grep "$(date +%Y-%m-%d)" "$pg_log" | grep -i "error\|fatal" | tail -10)
send_alert "PostgreSQL Errors" "PostgreSQL errors: $pg_errors\n\nDetails:\n$pg_details"
fi
fi
fi
}
# Hàm tạo summary report
generate_summary() {
log_message "=== LOG ANALYSIS SUMMARY ==="
log_message "Analysis Date: $(date)"
log_message "Server: $(hostname)"
log_message "Report File: $REPORT_FILE"
# Disk usage của log directory
local log_size=$(du -sh "$LOG_DIR" 2>/dev/null | cut -f1)
log_message "Log directory size: $log_size"
# Oldest and newest log files
local oldest_log=$(find "$LOG_DIR" -name "*.log" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | head -1 | cut -d' ' -f2-)
local newest_log=$(find "$LOG_DIR" -name "*.log" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2-)
if [ -n "$oldest_log" ]; then
log_message "Oldest log: $oldest_log"
fi
if [ -n "$newest_log" ]; then
log_message "Newest log: $newest_log"
fi
}
# Main execution
log_message "Starting log analysis"
generate_summary
analyze_ssh_logs
analyze_web_logs
analyze_system_logs
analyze_database_logs
log_message "Log analysis completed"
# Compress old reports
find "$REPORT_DIR" -name "log_analysis_*.txt" -mtime +7 -exec gzip {} \;
🛡️ 2. Script Giám Sát Bảo Mật
Security Monitoring & Intrusion Detection
#!/bin/bash
# security_monitor.sh - Giám sát bảo mật và phát hiện xâm nhập
# Cấu hình
SECURITY_LOG="/var/log/security_monitor.log"
ALERT_EMAIL="[email protected]"
WHITELIST_IPS="/etc/security/whitelist_ips.txt"
BLACKLIST_IPS="/etc/security/blacklist_ips.txt"
MAX_FAILED_ATTEMPTS=5
TIME_WINDOW=300 # 5 phút
# Tạo thư mục cấu hình
mkdir -p /etc/security
# Hàm ghi log bảo mật
security_log() {
echo "$(date '+%Y-%m-%d %H:%M:%S') [SECURITY] $1" | tee -a "$SECURITY_LOG"
}
# Hàm gửi cảnh báo bảo mật
security_alert() {
local level="$1"
local message="$2"
local subject="[SECURITY-$level] $(hostname) - $3"
echo "$message" | mail -s "$subject" "$ALERT_EMAIL"
security_log "ALERT-$level: $3"
}
# Hàm kiểm tra IP trong whitelist
is_whitelisted() {
local ip="$1"
if [ -f "$WHITELIST_IPS" ]; then
grep -q "^$ip$" "$WHITELIST_IPS"
return $?
fi
return 1
}
# Hàm thêm IP vào blacklist
add_to_blacklist() {
local ip="$1"
local reason="$2"
if ! is_whitelisted "$ip"; then
echo "$ip" >> "$BLACKLIST_IPS"
security_log "BLOCKED: $ip - $reason"
# Block IP using iptables (nếu có quyền)
if command -v iptables >/dev/null 2>&1; then
iptables -A INPUT -s "$ip" -j DROP 2>/dev/null
security_log "IPTABLES: Blocked $ip"
fi
security_alert "HIGH" "IP $ip has been blocked\nReason: $reason\nTime: $(date)" "IP Blocked"
fi
}
# Hàm phát hiện brute force attacks
detect_brute_force() {
security_log "Checking for brute force attacks"
local auth_log="/var/log/auth.log"
if [ ! -f "$auth_log" ]; then
auth_log="/var/log/secure"
fi
if [ -f "$auth_log" ]; then
# Tìm IPs có nhiều failed attempts trong time window
local suspicious_ips=$(awk -v time_window="$TIME_WINDOW" -v max_attempts="$MAX_FAILED_ATTEMPTS" '
/Failed password/ {
ip = $(NF-3)
timestamp = $1 " " $2 " " $3
cmd = "date -d \"" timestamp "\" +%s"
cmd | getline epoch
close(cmd)
current_time = systime()
if (current_time - epoch <= time_window) {
failed_attempts[ip]++
}
}
END {
for (ip in failed_attempts) {
if (failed_attempts[ip] >= max_attempts) {
print ip, failed_attempts[ip]
}
}
}' "$auth_log")
if [ -n "$suspicious_ips" ]; then
echo "$suspicious_ips" | while read ip attempts; do
if ! is_whitelisted "$ip"; then
add_to_blacklist "$ip" "Brute force attack: $attempts failed attempts"
fi
done
fi
fi
}
# Hàm kiểm tra file integrity
check_file_integrity() {
security_log "Checking critical file integrity"
local critical_files=(
"/etc/passwd"
"/etc/shadow"
"/etc/sudoers"
"/etc/ssh/sshd_config"
"/etc/hosts"
)
local checksums_file="/var/lib/security/file_checksums.txt"
mkdir -p "$(dirname "$checksums_file")"
for file in "${critical_files[@]}"; do
if [ -f "$file" ]; then
local current_checksum=$(sha256sum "$file" | cut -d' ' -f1)
local stored_checksum=""
if [ -f "$checksums_file" ]; then
stored_checksum=$(grep "$file" "$checksums_file" | cut -d' ' -f1)
fi
if [ -z "$stored_checksum" ]; then
# First time - store checksum
echo "$current_checksum $file" >> "$checksums_file"
security_log "BASELINE: Stored checksum for $file"
elif [ "$current_checksum" != "$stored_checksum" ]; then
# File changed!
security_alert "CRITICAL" "Critical file modified: $file\nOld checksum: $stored_checksum\nNew checksum: $current_checksum\nTime: $(date)" "File Integrity Violation"
# Update checksum
sed -i "s|.*$file|$current_checksum $file|" "$checksums_file"
fi
fi
done
}
# Hàm kiểm tra processes bất thường
check_suspicious_processes() {
security_log "Checking for suspicious processes"
# Processes chạy với quyền root
local suspicious_root_procs=$(ps aux | awk '$1=="root" && $11!~/^\[/ && $11!~/^\/usr\/bin/ && $11!~/^\/bin/ && $11!~/^\/sbin/ && $11!~/^\/usr\/sbin/ {print $2, $11}' | grep -v "PID COMMAND")
if [ -n "$suspicious_root_procs" ]; then
security_log "WARNING: Suspicious root processes detected"
echo "$suspicious_root_procs" | while read pid command; do
security_log "SUSPICIOUS: PID $pid - $command"
done
fi
# Processes listening trên ports bất thường
local unusual_listeners=$(netstat -tlnp 2>/dev/null | awk '$1=="tcp" && ($4~/:(2[2-9][0-9][0-9]|[3-9][0-9][0-9][0-9]|[1-9][0-9][0-9][0-9][0-9]+):/) {print $4, $7}')
if [ -n "$unusual_listeners" ]; then
security_log "WARNING: Unusual port listeners detected"
echo "$unusual_listeners" | while read port process; do
security_log "UNUSUAL: Port $port - $process"
done
fi
# Processes với tên nghi ngờ
local suspicious_names=$(ps aux | grep -E '(nc|netcat|ncat|socat|wget|curl)' | grep -v grep | awk '{print $2, $11}')
if [ -n "$suspicious_names" ]; then
security_log "INFO: Network tools detected (may be legitimate)"
echo "$suspicious_names" | while read pid command; do
security_log "NETWORK_TOOL: PID $pid - $command"
done
fi
}
# Hàm kiểm tra network connections
check_network_connections() {
security_log "Checking network connections"
# Connections đến IPs nước ngoài (không phải private IPs)
local foreign_connections=$(netstat -tn 2>/dev/null | awk '$1=="tcp" && $6=="ESTABLISHED" {print $5}' | cut -d: -f1 | grep -v -E '^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.|::1|localhost)' | sort | uniq -c | sort -nr)
if [ -n "$foreign_connections" ]; then
security_log "INFO: Foreign connections detected"
echo "$foreign_connections" | head -10 | while read count ip; do
if [ "$count" -gt 10 ]; then
security_log "WARNING: High connection count to $ip: $count connections"
else
security_log "FOREIGN: $count connections to $ip"
fi
done
fi
# Kiểm tra connections đến ports bất thường
local unusual_outbound=$(netstat -tn 2>/dev/null | awk '$1=="tcp" && $6=="ESTABLISHED" {print $5}' | cut -d: -f2 | sort | uniq -c | sort -nr | awk '$2>1024 && $2<65535 && $1>5')
if [ -n "$unusual_outbound" ]; then
security_log "WARNING: High outbound connections to unusual ports"
echo "$unusual_outbound" | while read count port; do
security_log "UNUSUAL_PORT: $count connections to port $port"
done
fi
}
# Hàm kiểm tra user activities
check_user_activities() {
security_log "Checking user activities"
# Users đăng nhập hiện tại
local current_users=$(who | wc -l)
security_log "Current logged in users: $current_users"
if [ "$current_users" -gt 5 ]; then
security_log "WARNING: High number of concurrent users: $current_users"
who | while read user tty date time ip; do
security_log "LOGGED_IN: $user from $ip on $tty"
done
fi
# Kiểm tra sudo usage
local sudo_usage=$(grep "sudo:" /var/log/auth.log 2>/dev/null | grep "$(date +%b\ %d)" | wc -l)
if [ "$sudo_usage" -gt 20 ]; then
security_log "WARNING: High sudo usage today: $sudo_usage commands"
fi
# Kiểm tra user account changes
local account_changes=$(grep -E "(useradd|userdel|usermod|passwd)" /var/log/auth.log 2>/dev/null | grep "$(date +%b\ %d)" | wc -l)
if [ "$account_changes" -gt 0 ]; then
security_alert "MEDIUM" "User account changes detected: $account_changes\nDate: $(date)" "Account Changes"
fi
}
# Hàm tạo security report
generate_security_report() {
local report_file="/var/log/security_report_$(date +%Y%m%d).txt"
{
echo "=== SECURITY MONITORING REPORT ==="
echo "Date: $(date)"
echo "Server: $(hostname)"
echo ""
echo "=== BLACKLISTED IPS ==="
if [ -f "$BLACKLIST_IPS" ]; then
cat "$BLACKLIST_IPS"
else
echo "No blacklisted IPs"
fi
echo ""
echo "=== RECENT SECURITY EVENTS ==="
tail -50 "$SECURITY_LOG"
} > "$report_file"
security_log "Security report generated: $report_file"
}
# Main execution
security_log "Starting security monitoring"
detect_brute_force
check_file_integrity
check_suspicious_processes
check_network_connections
check_user_activities
generate_security_report
security_log "Security monitoring completed"