Add reporter.sh
This commit is contained in:
parent
f05c0c62ab
commit
c9a4ee06c8
1 changed files with 193 additions and 0 deletions
193
reporter.sh
Normal file
193
reporter.sh
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
#!/bin/bash
|
||||
|
||||
LOG_FILE="/var/log/ufw.log"
|
||||
ENCODED_API_KEY_FILE="./encoded_token.txt"
|
||||
REPORTED_IPS_FILE="/tmp/reported_ips.txt"
|
||||
REPORT_INTERVAL=18000 # 5h (seconds)
|
||||
|
||||
declare -A reported_ips
|
||||
|
||||
log() {
|
||||
local level="$1"
|
||||
local message="$2"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message"
|
||||
}
|
||||
|
||||
if [[ -f "$ENCODED_API_KEY_FILE" ]]; then
|
||||
DECODED_API_KEY=$(openssl enc -d -base64 -in "$ENCODED_API_KEY_FILE")
|
||||
if [[ -z "$DECODED_API_KEY" ]]; then
|
||||
log "ERROR" "Failed to decode API key from $ENCODED_API_KEY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log "ERROR" "API key file not found at $ENCODED_API_KEY_FILE"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ABUSEIPDB_API_KEY="$DECODED_API_KEY"
|
||||
|
||||
load_reported_ips() {
|
||||
if [[ -f "$REPORTED_IPS_FILE" ]]; then
|
||||
while IFS= read -r line; do
|
||||
[[ -z "$line" ]] && continue
|
||||
IFS=' ' read -r ip report_time <<< "$line"
|
||||
if [[ -n "$ip" && -n "$report_time" ]]; then
|
||||
reported_ips["$ip"]=$report_time
|
||||
else
|
||||
log "WARN" "Invalid line format: '$line'"
|
||||
fi
|
||||
done < "$REPORTED_IPS_FILE"
|
||||
log "INFO" "Loaded ${#reported_ips[@]} IPs from $REPORTED_IPS_FILE"
|
||||
else
|
||||
log "INFO" "$REPORTED_IPS_FILE does not exist. No data to load!"
|
||||
fi
|
||||
}
|
||||
|
||||
save_reported_ips() {
|
||||
: > "$REPORTED_IPS_FILE"
|
||||
for ip in "${!reported_ips[@]}"; do
|
||||
echo "$ip ${reported_ips[$ip]}" >> "$REPORTED_IPS_FILE"
|
||||
done
|
||||
}
|
||||
|
||||
is_local_ip() {
|
||||
local ip="$1"
|
||||
[[ "$ip" =~ ^(10\.|172\.(1[6-9]|2[0-9]|3[01])\.|192\.168\.|127\.|fc|fd|fe80|::1) ]]
|
||||
}
|
||||
|
||||
report_to_abuseipdb() {
|
||||
local ip="$1" categories="$2" proto="$3" spt="$4" dpt="$5" ttl="$6" len="$7" tos="$8" warsaw_time="$9"
|
||||
|
||||
local comment="IP: $ip
|
||||
Protocol: $proto
|
||||
Source port: $spt
|
||||
Destination port: $dpt"
|
||||
|
||||
[[ -n "$ttl" ]] && comment+="
|
||||
TTL: $ttl"
|
||||
|
||||
[[ -n "$len" ]] && comment+="
|
||||
Packet length: $len"
|
||||
|
||||
[[ -n "$tos" ]] && comment+="
|
||||
TOS: $tos"
|
||||
|
||||
comment+="
|
||||
Timestamp: $warsaw_time [Europe/Warsaw]
|
||||
|
||||
The IP address was blocked by the Uncomplicated Firewall (UFW) due to suspicious activity. Packet details suggest a possible unauthorized access or port scanning attempt."
|
||||
|
||||
local response
|
||||
response=$(curl -s -X POST "https://api.abuseipdb.com/api/v2/report" \
|
||||
--data-urlencode "ip=$ip" \
|
||||
--data-urlencode "categories=$categories" \
|
||||
--data-urlencode "comment=$comment" \
|
||||
-H "Key: $ABUSEIPDB_API_KEY" \
|
||||
-H "Accept: application/json")
|
||||
|
||||
local abuse_confidence_score
|
||||
abuse_confidence_score=$(echo "$response" | jq -r '.data.abuseConfidenceScore')
|
||||
|
||||
if [[ "$abuse_confidence_score" =~ ^[0-9]+$ ]]; then
|
||||
log "INFO" "Successfully reported IP $ip to AbuseIPDB with score: $abuse_confidence_score"
|
||||
else
|
||||
log "ERROR" "Failed to report IP $ip to AbuseIPDB: $response"
|
||||
fi
|
||||
}
|
||||
|
||||
is_ip_reported_recently() {
|
||||
local ip="$1"
|
||||
local current_time
|
||||
current_time=$(date +%s)
|
||||
|
||||
if [[ -v reported_ips["$ip"] ]]; then
|
||||
local report_time=${reported_ips["$ip"]}
|
||||
(( current_time - report_time < REPORT_INTERVAL )) && return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
mark_ip_as_reported() {
|
||||
local ip="$1"
|
||||
reported_ips["$ip"]=$(date +%s)
|
||||
}
|
||||
|
||||
determine_categories() {
|
||||
local proto="$1"
|
||||
local dpt="$2"
|
||||
|
||||
# See https://www.abuseipdb.com/categories for more
|
||||
case "$proto" in
|
||||
"TCP")
|
||||
case "$dpt" in
|
||||
22) echo "14,22,18" ;; # Port Scan | SSH | Brute-Force
|
||||
80 | 443 | 8080) echo "14,21" ;; # Port Scan | Web App Attack
|
||||
25) echo "11" ;; # Email Spam
|
||||
21) echo "5,18" ;; # FTP Brute-Force | Brute-Force
|
||||
53) echo "1,2" ;; # DNS Compromise | DNS Poisoning
|
||||
23 | 3389) echo "14,15,18" ;; # Port Scan | Hacking | Brute-Force
|
||||
3306) echo "16" ;; # SQL Injection
|
||||
6666 | 6667 | 6668 | 6669) echo "14,8" ;; # Port Scan | Fraud VoIP
|
||||
9999) echo "6" ;; # Ping of Death
|
||||
*) echo "14" ;; # Port Scan
|
||||
esac
|
||||
;;
|
||||
"UDP")
|
||||
case "$dpt" in
|
||||
53) echo "14,1,2" ;; # Port Scan | DNS Compromise | DNS Poisoning
|
||||
123) echo "14,17" ;; # Port Scan | Spoofing
|
||||
*) echo "14,4" ;; # Port Scan | DDoS Attack
|
||||
esac
|
||||
;;
|
||||
*) echo "14,15" ;; # Port Scan | Hacking
|
||||
esac
|
||||
}
|
||||
|
||||
process_log_line() {
|
||||
local line="$1"
|
||||
if [[ "$line" == *"[UFW BLOCK]"* ]]; then
|
||||
local timestamp src_ip proto spt dpt ttl len tos categories warsaw_time
|
||||
|
||||
timestamp=$(echo "$line" | awk '{print $1, $2, $3}')
|
||||
[[ -z "$timestamp" ]] && timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
src_ip=$(echo "$line" | grep -oP 'SRC=\K[^\s]+')
|
||||
|
||||
if is_local_ip "$src_ip"; then
|
||||
log "INFO" "Ignoring local IP: $src_ip"
|
||||
return
|
||||
fi
|
||||
|
||||
proto=$(echo "$line" | grep -oP 'PROTO=\K[^\s]+')
|
||||
spt=$(echo "$line" | grep -oP 'SPT=\K[^\s]+')
|
||||
dpt=$(echo "$line" | grep -oP 'DPT=\K[^\s]+')
|
||||
ttl=$(echo "$line" | grep -oP 'TTL=\K[^\s]+')
|
||||
len=$(echo "$line" | grep -oP 'LEN=\K[^\s]+')
|
||||
tos=$(echo "$line" | grep -oP 'TOS=\K[^\s]+')
|
||||
|
||||
if is_ip_reported_recently "$src_ip"; then
|
||||
log "INFO" "IP $src_ip ($proto) was reported recently. Skipping..."
|
||||
return
|
||||
fi
|
||||
|
||||
categories=$(determine_categories "$proto" "$dpt")
|
||||
warsaw_time=$(TZ="Europe/Warsaw" date -d "$timestamp" '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
log "INFO" "Reporting IP $src_ip ($proto $dpt) with categories $categories..."
|
||||
report_to_abuseipdb "$src_ip" "$categories" "$proto" "$spt" "$dpt" "$ttl" "$len" "$tos" "$warsaw_time"
|
||||
mark_ip_as_reported "$src_ip"
|
||||
save_reported_ips
|
||||
fi
|
||||
}
|
||||
|
||||
load_reported_ips
|
||||
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log "ERROR" "jq is not installed. Please install jq to run this script."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log "INFO" "Starting to monitor $LOG_FILE"
|
||||
|
||||
tail -Fn0 "$LOG_FILE" | while read -r line; do
|
||||
process_log_line "$line"
|
||||
done
|
||||
Loading…
Add table
Reference in a new issue