83 lines
2.1 KiB
Bash
Executable file
83 lines
2.1 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
PORT=8080
|
|
DB="/usr/share/GeoIP/GeoLite2-Country.mmdb"
|
|
LOGFILE="/dev/null"
|
|
COUNTRY_FILE="countries.txt"
|
|
|
|
declare -A COUNTRY_COUNT
|
|
declare -A SEEN
|
|
declare -A COUNTRY_NAME
|
|
|
|
# --- Parse -N flag (e.g. -10 means show top 10) ---
|
|
TOPN=0
|
|
if [[ "$1" =~ ^-([0-9]+)$ ]]; then
|
|
TOPN="${BASH_REMATCH[1]}"
|
|
fi
|
|
|
|
# --- Load external country list ---
|
|
while IFS='=' read -r ISO NAME; do
|
|
[[ -z "$ISO" ]] && continue
|
|
COUNTRY_NAME["$ISO"]="$NAME"
|
|
done < "$COUNTRY_FILE"
|
|
|
|
echo "Monitoring port $PORT..."
|
|
echo "Updating table every 5 seconds."
|
|
[[ $TOPN -gt 0 ]] && echo "Showing only Top $TOPN countries."
|
|
|
|
LAST_REFRESH=0
|
|
|
|
while true; do
|
|
# FAST LOOP: collect new connections
|
|
IPS=$(ss -tn sport = :$PORT | awk 'NR>1 {print $5}' | cut -d: -f1)
|
|
|
|
for IP in $IPS; do
|
|
[[ "$IP" == "127.0.0.1" ]] && continue
|
|
|
|
if [[ -z "${SEEN[$IP]}" ]]; then
|
|
SEEN[$IP]=1
|
|
|
|
RAW=$(mmdblookup --file "$DB" --ip "$IP" country iso_code 2>/dev/null)
|
|
ISO=$(echo "$RAW" | grep -oE '[A-Z]{2}')
|
|
[[ -z "$ISO" ]] && ISO="UNKNOWN"
|
|
|
|
COUNTRY_COUNT["$ISO"]=$(( COUNTRY_COUNT["$ISO"] + 1 ))
|
|
|
|
NAME="${COUNTRY_NAME[$ISO]}"
|
|
[[ -z "$NAME" ]] && NAME="Unknown Country"
|
|
|
|
echo "$(date '+%F %T') - $IP - $ISO ($NAME)" >> "$LOGFILE"
|
|
fi
|
|
done
|
|
|
|
# SLOW LOOP: refresh display every 5 seconds
|
|
NOW=$(date +%s)
|
|
if (( NOW - LAST_REFRESH >= 5 )); then
|
|
LAST_REFRESH=$NOW
|
|
|
|
clear
|
|
echo "=== Live GeoIP Stats (Port $PORT) ==="
|
|
echo "(Updated: $(date '+%H:%M:%S'))"
|
|
echo
|
|
|
|
# Sort by count (descending)
|
|
SORTED=$(for ISO in "${!COUNTRY_COUNT[@]}"; do
|
|
echo "${COUNTRY_COUNT[$ISO]} $ISO"
|
|
done | sort -rn)
|
|
|
|
COUNT=0
|
|
while read -r LINE; do
|
|
NUM=$(echo "$LINE" | awk '{print $1}')
|
|
ISO=$(echo "$LINE" | awk '{print $2}')
|
|
NAME="${COUNTRY_NAME[$ISO]}"
|
|
[[ -z "$NAME" ]] && NAME="Unknown Country"
|
|
|
|
echo "$ISO ($NAME): $NUM"
|
|
|
|
((COUNT++))
|
|
[[ $TOPN -gt 0 && $COUNT -ge $TOPN ]] && break
|
|
done <<< "$SORTED"
|
|
fi
|
|
|
|
sleep 0.1
|
|
done
|