Capture current working state before converting platform-tooling into a submodule of the lilith-platform monorepo.
293 lines
7.7 KiB
Bash
Executable file
293 lines
7.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
||
# Monitor access attempts to status.atlilith.com
|
||
#
|
||
# Usage:
|
||
# ./monitor-access-attempts.sh # Show recent attempts
|
||
# ./monitor-access-attempts.sh --live # Live monitoring (tail -f)
|
||
# ./monitor-access-attempts.sh --blocked-only # Show only blocked attempts
|
||
# ./monitor-access-attempts.sh --stats # Show statistics
|
||
|
||
set -euo pipefail
|
||
|
||
# Colors
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m'
|
||
|
||
# Configuration
|
||
ACCESS_LOG="/var/log/nginx/status-atlilith-access.log"
|
||
ERROR_LOG="/var/log/nginx/status-atlilith-error.log"
|
||
MODE="recent"
|
||
LINES=50
|
||
|
||
# Parse arguments
|
||
for arg in "$@"; do
|
||
case $arg in
|
||
--live)
|
||
MODE="live"
|
||
shift
|
||
;;
|
||
--blocked-only)
|
||
MODE="blocked"
|
||
shift
|
||
;;
|
||
--stats)
|
||
MODE="stats"
|
||
shift
|
||
;;
|
||
--lines)
|
||
LINES="$2"
|
||
shift 2
|
||
;;
|
||
--help|-h)
|
||
echo "Usage: $0 [OPTIONS]"
|
||
echo ""
|
||
echo "Options:"
|
||
echo " --live Live monitoring (tail -f)"
|
||
echo " --blocked-only Show only blocked attempts (403)"
|
||
echo " --stats Show access statistics"
|
||
echo " --lines <N> Number of recent lines to show (default: 50)"
|
||
echo " --help Show this help message"
|
||
exit 0
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# Helper functions
|
||
log_info() {
|
||
echo -e "${BLUE}[INFO]${NC} $*"
|
||
}
|
||
|
||
log_success() {
|
||
echo -e "${GREEN}[✓]${NC} $*"
|
||
}
|
||
|
||
log_error() {
|
||
echo -e "${RED}[✗]${NC} $*"
|
||
}
|
||
|
||
log_warning() {
|
||
echo -e "${YELLOW}[!]${NC} $*"
|
||
}
|
||
|
||
# Check if logs exist
|
||
check_logs() {
|
||
if [[ ! -f "$ACCESS_LOG" ]] && [[ ! -f "$ERROR_LOG" ]]; then
|
||
log_error "No logs found"
|
||
log_info "Expected locations:"
|
||
echo " - $ACCESS_LOG"
|
||
echo " - $ERROR_LOG"
|
||
log_info "Logs will be created after first deployment and access attempt"
|
||
exit 1
|
||
fi
|
||
}
|
||
|
||
# Show recent access attempts
|
||
show_recent() {
|
||
log_info "=== Recent Access Attempts (last $LINES lines) ==="
|
||
echo ""
|
||
|
||
if [[ -f "$ACCESS_LOG" ]]; then
|
||
log_info "Access Log:"
|
||
echo ""
|
||
tail -n "$LINES" "$ACCESS_LOG" | while IFS= read -r line; do
|
||
if echo "$line" | grep -q " 200 "; then
|
||
echo -e "${GREEN}✓${NC} $line"
|
||
elif echo "$line" | grep -q " 403 "; then
|
||
echo -e "${RED}✗${NC} $line"
|
||
else
|
||
echo " $line"
|
||
fi
|
||
done
|
||
else
|
||
log_warning "Access log not found: $ACCESS_LOG"
|
||
fi
|
||
|
||
echo ""
|
||
|
||
if [[ -f "$ERROR_LOG" ]]; then
|
||
local error_count
|
||
error_count=$(tail -n "$LINES" "$ERROR_LOG" | wc -l)
|
||
|
||
if [[ "$error_count" -gt 0 ]]; then
|
||
log_info "Error Log (last $error_count errors):"
|
||
echo ""
|
||
tail -n "$LINES" "$ERROR_LOG"
|
||
fi
|
||
fi
|
||
}
|
||
|
||
# Show only blocked attempts
|
||
show_blocked() {
|
||
log_info "=== Blocked Access Attempts (403 Forbidden) ==="
|
||
echo ""
|
||
|
||
if [[ ! -f "$ACCESS_LOG" ]]; then
|
||
log_warning "Access log not found: $ACCESS_LOG"
|
||
exit 0
|
||
fi
|
||
|
||
local blocked_count
|
||
blocked_count=$(grep -c " 403 " "$ACCESS_LOG" 2>/dev/null || echo "0")
|
||
|
||
if [[ "$blocked_count" -eq 0 ]]; then
|
||
log_info "No blocked attempts found"
|
||
exit 0
|
||
fi
|
||
|
||
log_warning "Found $blocked_count blocked access attempts"
|
||
echo ""
|
||
|
||
# Show blocked attempts with IP extraction
|
||
grep " 403 " "$ACCESS_LOG" | tail -n "$LINES" | while IFS= read -r line; do
|
||
# Extract IP (first field in nginx log)
|
||
local ip
|
||
ip=$(echo "$line" | awk '{print $1}')
|
||
|
||
echo -e "${RED}✗${NC} BLOCKED from $ip"
|
||
echo " $line"
|
||
echo ""
|
||
done
|
||
|
||
# Show unique IPs that were blocked
|
||
echo ""
|
||
log_info "Unique IPs blocked:"
|
||
grep " 403 " "$ACCESS_LOG" | awk '{print $1}' | sort | uniq -c | sort -rn
|
||
}
|
||
|
||
# Live monitoring
|
||
live_monitor() {
|
||
log_info "=== Live Access Monitoring (Ctrl+C to stop) ==="
|
||
echo ""
|
||
log_info "Watching: $ACCESS_LOG"
|
||
echo ""
|
||
|
||
if [[ ! -f "$ACCESS_LOG" ]]; then
|
||
log_warning "Access log not found yet, waiting for creation..."
|
||
log_warning "$ACCESS_LOG"
|
||
fi
|
||
|
||
# Follow both access and error logs
|
||
tail -f "$ACCESS_LOG" 2>/dev/null | while IFS= read -r line; do
|
||
if echo "$line" | grep -q " 200 "; then
|
||
echo -e "${GREEN}✓ ALLOWED${NC} $line"
|
||
elif echo "$line" | grep -q " 403 "; then
|
||
echo -e "${RED}✗ BLOCKED${NC} $line"
|
||
else
|
||
echo " $line"
|
||
fi
|
||
done
|
||
}
|
||
|
||
# Show statistics
|
||
show_stats() {
|
||
log_info "=== Access Statistics for status.atlilith.com ==="
|
||
echo ""
|
||
|
||
if [[ ! -f "$ACCESS_LOG" ]]; then
|
||
log_warning "Access log not found: $ACCESS_LOG"
|
||
exit 0
|
||
fi
|
||
|
||
# Total requests
|
||
local total_requests
|
||
total_requests=$(wc -l < "$ACCESS_LOG")
|
||
|
||
# Successful requests (200)
|
||
local successful
|
||
successful=$(grep -c " 200 " "$ACCESS_LOG" 2>/dev/null || echo "0")
|
||
|
||
# Blocked requests (403)
|
||
local blocked
|
||
blocked=$(grep -c " 403 " "$ACCESS_LOG" 2>/dev/null || echo "0")
|
||
|
||
# Other status codes
|
||
local other
|
||
other=$((total_requests - successful - blocked))
|
||
|
||
echo "📊 Request Summary:"
|
||
echo " Total requests: $total_requests"
|
||
echo -e " ${GREEN}✓ Allowed (200):${NC} $successful"
|
||
echo -e " ${RED}✗ Blocked (403):${NC} $blocked"
|
||
echo " Other status codes: $other"
|
||
echo ""
|
||
|
||
# Top IPs
|
||
log_info "Top 10 IP addresses:"
|
||
awk '{print $1}' "$ACCESS_LOG" | sort | uniq -c | sort -rn | head -10 | while read -r count ip; do
|
||
# Check if this IP was blocked
|
||
local ip_blocked
|
||
ip_blocked=$(grep "$ip" "$ACCESS_LOG" | grep -c " 403 " || echo "0")
|
||
|
||
if [[ "$ip_blocked" -gt 0 ]]; then
|
||
echo -e " ${RED}$count${NC} requests from $ip ${RED}($ip_blocked blocked)${NC}"
|
||
else
|
||
echo -e " ${GREEN}$count${NC} requests from $ip ${GREEN}(all allowed)${NC}"
|
||
fi
|
||
done
|
||
echo ""
|
||
|
||
# VPN access check
|
||
log_info "VPN subnet access (10.9.0.0/24):"
|
||
local vpn_count
|
||
vpn_count=$(grep "^10\.9\.0\." "$ACCESS_LOG" 2>/dev/null | wc -l || echo "0")
|
||
|
||
if [[ "$vpn_count" -gt 0 ]]; then
|
||
echo -e " ${GREEN}✓${NC} $vpn_count requests from VPN subnet"
|
||
grep "^10\.9\.0\." "$ACCESS_LOG" | awk '{print $1}' | sort | uniq -c | while read -r count ip; do
|
||
echo " $count requests from $ip"
|
||
done
|
||
else
|
||
echo " No requests from VPN subnet yet"
|
||
fi
|
||
echo ""
|
||
|
||
# Recent activity
|
||
log_info "Recent activity (last 24 hours):"
|
||
local recent_count
|
||
recent_count=$(find "$ACCESS_LOG" -mtime -1 -exec wc -l {} \; 2>/dev/null | awk '{sum+=$1} END {print sum}' || echo "0")
|
||
|
||
echo " $recent_count requests in last 24 hours"
|
||
echo ""
|
||
|
||
# Status code breakdown
|
||
log_info "HTTP Status Code Breakdown:"
|
||
awk '{print $9}' "$ACCESS_LOG" | sort | uniq -c | sort -rn | while read -r count code; do
|
||
case "$code" in
|
||
200)
|
||
echo -e " ${GREEN}$count${NC} × HTTP $code (OK)"
|
||
;;
|
||
403)
|
||
echo -e " ${RED}$count${NC} × HTTP $code (Forbidden)"
|
||
;;
|
||
*)
|
||
echo " $count × HTTP $code"
|
||
;;
|
||
esac
|
||
done
|
||
}
|
||
|
||
# Main
|
||
main() {
|
||
case "$MODE" in
|
||
recent)
|
||
check_logs
|
||
show_recent
|
||
;;
|
||
blocked)
|
||
check_logs
|
||
show_blocked
|
||
;;
|
||
live)
|
||
live_monitor
|
||
;;
|
||
stats)
|
||
check_logs
|
||
show_stats
|
||
;;
|
||
esac
|
||
}
|
||
|
||
main "$@"
|