Skip to main content

Script untuk check log based by spesific time

Berikut FItur bash script nya

  • Highlight IP yang hit-nya melebihi threshold (default: >100)
  • Deteksi pola serangan umum, seperti:
    • Bot flood (User-Agent kosong / suspicious)
    • 404 spike
    • Request berulang ke path yang sama
  • Export hasil ke CSV (opsional)
  • Filter berdasarkan User-Agent berbahaya (curl, python-requests, libweb, wget, bot murahan)
  • bisa detek HTTP Status
    • Banyak 5xx → server error (down)
    • Banyak 4xx → client/bot error
    • Banyak 502/504 → upstream/downstream error
    • Banyak 499 → client close connection (biasanya karena lambat → server overload)
    • Dan lain-lain.

Arti Warna BOT

  • [DANGEROUS BOT]MERAH TERANG

  • [SUSPICIOUS BOT]KUNING

  • [LEGIT BOT]HIJAU

  • [UNKNOWN] → NORMAL

Arti Warna HTTP Status

  • Warna status code (2xx hijau, 4xx kuning, 5xx merah)
#!/bin/bash

# ======================================================
#   Usage:
#       ./top-ip-range-advanced.sh <logfile> "<start>" "<end>"
#
#   Example:
#       ./top-ip-range-advanced.sh /var/log/nginx/access.log \
#       "18/Nov/2025:09:00" "18/Nov/2025:09:15"
# ======================================================

# ANSI COLORS
RED="\033[1;31m"
YELLOW="\033[1;33m"
GREEN="\033[1;32m"
CYAN="\033[1;36m"
MAGENTA="\033[1;35m"
RESET="\033[0m"

if [ $# -ne 3 ]; then
    echo "Usage: $0 <logfile> <start 'dd/Mon/yyyy:HH:MM'> <end 'dd/Mon/yyyy:HH:MM'>"
    exit 1
fi

LOGFILE="$1"
START="$2"
END="$3"

if [ ! -f "$LOGFILE" ]; then
    echo "Error: File log '$LOGFILE' tidak ditemukan!"
    exit 2
fi

echo "=================================================="
echo " ANALYZING LOG RANGE"
echo " File  : $LOGFILE"
echo " Start : $START"
echo " End   : $END"
echo "=================================================="
echo

TMPFILE=$(mktemp)

# Filter timestamp
awk -v start="[$START" -v end="[$END" '
    $4 >= start && $4 <= end { print }
' "$LOGFILE" > "$TMPFILE"

echo ">> Total entries in range : $(wc -l < $TMPFILE)"
echo


# ======================================================
# HTTP STATUS BREAKDOWN (COLORED)
# ======================================================
echo "=================================================="
echo " HTTP STATUS BREAKDOWN (COLORED)"
echo "=================================================="

awk -v RED="$RED" -v YELLOW="$YELLOW" -v GREEN="$GREEN" -v RESET="$RESET" '
{
    status=$9
    if (status ~ /^5/) color=RED
    else if (status ~ /^4/) color=YELLOW
    else if (status ~ /^2/) color=GREEN
    else color=RESET
    print color status RESET
}' "$TMPFILE" | sort | uniq -c | sort -nr | head -20
echo


# ======================================================
# STATUS SUMMARY (COLORED)
# ======================================================
echo "=================================================="
echo " STATUS SUMMARY (GROUPED + COLORED)"
echo "=================================================="

echo -e "2xx Success:   ${GREEN}$(awk '$9 ~ /^2/ {c++} END {print c+0}' $TMPFILE)${RESET}"
echo -e "3xx Redirect:  ${CYAN}$(awk '$9 ~ /^3/ {c++} END {print c+0}' $TMPFILE)${RESET}"
echo -e "4xx ClientErr: ${YELLOW}$(awk '$9 ~ /^4/ {c++} END {print c+0}' $TMPFILE)${RESET}"
echo -e "5xx ServerErr: ${RED}$(awk '$9 ~ /^5/ {c++} END {print c+0}' $TMPFILE)${RESET}"
echo


# ======================================================
# TOP IP WITH 5xx ERRORS
# ======================================================
echo "=================================================="
echo " TOP IP WITH SERVER ERRORS (5xx)"
echo "=================================================="
awk '$9 ~ /^5/ {print $1}' "$TMPFILE" | sort | uniq -c | sort -nr | head -15
echo


# ======================================================
# TOP IP (HIGHLIGHT TOP 1)
# ======================================================
echo "=================================================="
echo " TOP IP (Top 20, Highlight Highest)"
echo "=================================================="

TOP_IPS=$(awk '{print $1}' "$TMPFILE" | sort | uniq -c | sort -nr | head -20)
TOP1=$(echo "$TOP_IPS" | head -1)

echo "$TOP_IPS" | while read count ip; do
    if [[ "$count $ip" == "$TOP1" ]]; then
        echo -e "${GREEN}[TOP] $count $ip${RESET}"
    else
        echo "$count $ip"
    fi
done
echo


# ======================================================
# BOT DETECTION + CLASSIFICATION + COLOR
# ======================================================
echo "=================================================="
echo " BOT DETECTION (Classified + Highlight)"
echo "=================================================="

LEGIT='googlebot|bingbot|baiduspider|yandexbot|duckduckbot|applebot|slurp'
SUSPICIOUS='curl|wget|spider|crawler|httpclient|node|libwww|java|scrapy'
DANGEROUS='sqlmap|zerodium|dirbuster|acunetix|nmap|nikto|fuzz|attack|python-requests|python|masscan|zgrab|hydra|wpscan|metasploit|bruteforce|Nexus'

grep -Ei "$LEGIT|$SUSPICIOUS|$DANGEROUS" "$TMPFILE" | \
awk -v legit="$LEGIT" -v susp="$SUSPICIOUS" -v danger="$DANGEROUS" \
    -v RED="$RED" -v YELLOW="$YELLOW" -v GREEN="$GREEN" -v RESET="$RESET" '
{
    ip=$1
    ua=""
    for (i=12;i<=NF;i++) ua=ua" "$i

    if (ua ~ danger) label=RED"[DANGEROUS BOT]"RESET
    else if (ua ~ susp) label=YELLOW"[SUSPICIOUS BOT]"RESET
    else if (ua ~ legit) label=GREEN"[LEGIT BOT]"RESET
    else label="[UNKNOWN]"

    print label, ip, ua
}' | sort | uniq -c | sort -nr | head -30
echo


# ======================================================
# GROUP IP + STATUS + PATH
# ======================================================
echo "=================================================="
echo " GROUPED BY IP + STATUS + PATH"
echo "=================================================="

awk '{
    ip=$1;
    status=$9;
    path=$7;
    key=ip" "status" "path;
    count[key]++;
}
END {
    for (k in count) print count[k], k;
}' "$TMPFILE" | sort -nr | head -50
echo


# ======================================================
# 404 SPIKE (HIGHLIGHT TOP 1)
# ======================================================
echo "=================================================="
echo " TOP 404 PATH (Highlight Spike)"
echo "=================================================="

DATA_404=$(grep ' 404 ' "$TMPFILE" | awk '{print $7}' | sort | uniq -c | sort -nr | head -15)
TOP_404=$(echo "$DATA_404" | head -1)

echo "$DATA_404" | while read count path; do
    if [[ "$count $path" == "$TOP_404" ]]; then
        echo -e "${RED}[SPIKE] $count $path${RESET}"
    else
        echo "$count $path"
    fi
done
echo


# ======================================================
# MOST ACCESSED PATH
# ======================================================
echo "=================================================="
echo " MOST ACCESSED PATH (Top 20)"
echo "=================================================="
awk '{print $7}' "$TMPFILE" | sort | uniq -c | sort -nr | head -20

rm -f "$TMPFILE"