mirror of https://github.com/fail2ban/fail2ban
Merge f8a269eaad
into 1c2ace2958
commit
1a67fb3a1a
|
@ -0,0 +1,74 @@
|
|||
# Fail2Ban AbuseIPDB Integration (Enhanced)
|
||||
#
|
||||
# Author: Hasan CALISIR
|
||||
# GitHub: https://github.com/hsntgm
|
||||
#
|
||||
# Description:
|
||||
# Enhanced AbuseIPDB integration for Fail2Ban with improved control,
|
||||
# tracking, and isolation for IP abuse reporting.
|
||||
#
|
||||
# Key Features:
|
||||
# - Isolated AbuseIPDB SQLite database to track reports independently.
|
||||
# - Dual API calls: /v2/check and /v2/report for efficient reporting.
|
||||
# - Optimizes AbuseIPDB daily API usage by reducing unnecessary report calls
|
||||
# - Supports norestored=1 to avoid duplicate reports on restart.
|
||||
# - Maintains a separate, long-term persistent database of banned IPs to ensure accurate tracking
|
||||
# and avoid reliance on Fail2Ban’s bantimes or ban state, even if Fail2Ban’s
|
||||
# internal ban management becomes inconsistent over time.
|
||||
# - Customizable report comments to avoid leaking sensitive info.
|
||||
#
|
||||
# Example 'jail' configuration in 'jail.local' to prevent leaking sensitive information in AbuseIPDB reports:
|
||||
# [nginx-botsearch]
|
||||
# enabled = true
|
||||
# logpath = /var/log/nginx/*.log
|
||||
# port = http,https
|
||||
# backend = polling
|
||||
# tp_comment = Fail2Ban - NGINX bad requests 400-401-403-404-444, high level vulnerability scanning
|
||||
# maxretry = 3
|
||||
# findtime = 1d
|
||||
# bantime = 7200
|
||||
# action = %(action_mwl)s
|
||||
# %(action_abuseipdb)s[matches="%(tp_comment)s", abuseipdb_apikey="YOUR_API_KEY", abuseipdb_category="21,15", bantime="%(bantime)s"]
|
||||
|
||||
|
||||
[Definition]
|
||||
# Option: norestored
|
||||
######################
|
||||
# Notes.: Ensure norestored is set to 0
|
||||
# We control this at the script level to provide users with more control over how restored tickets are handled.
|
||||
# We will also be able to log all triggered events by norestored
|
||||
# Do not modify this value directly. Instead, adjust 'BYPASS_FAIL2BAN' below as needed.
|
||||
# norestored = 0
|
||||
|
||||
|
||||
# Option: User defined settings
|
||||
######################
|
||||
# Notes.: * Path to AbuseIPDB SQLite database used by the action script.
|
||||
# * Path to the log file where actions and events are recorded by the action script.
|
||||
# * Rely on Fail2Ban for restarts (0) or completely isolate it by bypassing Fail2Ban (1)
|
||||
# ! Bypassing Fail2Ban on restarts (BYPASS_FAIL2BAN = 1) can overhelm your server and AbuseIPDB API on restarts.
|
||||
# ! SET 1 if you want to completely isolate from Fail2Ban and rely solely on the AbuseIPDB SQLite database for reporting on restart.
|
||||
# SQLITE_DB = "/var/lib/fail2ban/abuseipdb/fail2ban_abuseipdb"
|
||||
# LOG_FILE = "/var/log/abuseipdb/abuseipdb.log"
|
||||
# BYPASS_FAIL2BAN = 0
|
||||
|
||||
|
||||
# Option: actionstart
|
||||
######################
|
||||
# Notes.: Uncomment and leave as-is
|
||||
# actionstart = nohup /etc/fail2ban/action.d/fail2ban-abuseipdb.sh \
|
||||
# "--actionstart" "<SQLITE_DB>" "<LOG_FILE>" &
|
||||
|
||||
|
||||
# Option: actionban
|
||||
######################
|
||||
# Notes.: Uncomment and leave as-is
|
||||
# actionban = /etc/fail2ban/action.d/fail2ban-abuseipdb.sh \
|
||||
# "<abuseipdb_apikey>" "<matches>" "<ip>" "<abuseipdb_category>" "<bantime>" "<restored>" "<BYPASS_FAIL2BAN>" "<SQLITE_DB>" "<LOG_FILE>"
|
||||
|
||||
|
||||
[Init]
|
||||
# Option: abuseipdb_apikey
|
||||
######################
|
||||
# Notes Set your API key and uncomment
|
||||
# abuseipdb_apikey =
|
|
@ -0,0 +1,472 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Description:
|
||||
# This script acts as a Fail2Ban `actionstart|actionban` to report offending IPs to AbuseIPDB.
|
||||
# It allows for 'custom comments' to prevent leaking sensitive information. The main goal is to
|
||||
# avoid relying on Fail2Ban and instead use a separate AbuseIPDB SQLite database for complete isolation.
|
||||
# It can also be used with Fail2Ban's `norestored=1` feature to rely on Fail2Ban for preventing
|
||||
# redundant reporting on restarts. Users can toggle this behavior as needed.
|
||||
#
|
||||
# The script performs two API calls for each ban action:
|
||||
# 1. **/v2/check** - Checks if the IP has already been reported.
|
||||
# 2. **/v2/report** - Reports the IP if necessary and updates the local banned IP list.
|
||||
# These two endpoints have separate daily limits, so they do not impact your reporting quota.
|
||||
#
|
||||
# To view any failures, check `/var/log/abuseipdb/abuseipdb.log`.
|
||||
#
|
||||
# Integration with Fail2Ban:
|
||||
# 1. Edit only 'abuseipdb.local' in 'action.d/abuseipdb.local' and uncomment pre-configured settings.
|
||||
# 2. Adjust your jails to prevent leaking sensitive information in custom comments via 'tp_comment'.
|
||||
#
|
||||
# Example 'jail' configuration in 'jail.local' to prevent leaking sensitive information in AbuseIPDB reports:
|
||||
# [nginx-botsearch]
|
||||
# enabled = true
|
||||
# logpath = /var/log/nginx/*.log
|
||||
# port = http,https
|
||||
# backend = polling
|
||||
# tp_comment = Fail2Ban - NGINX bad requests 400-401-403-404-444, high level vulnerability scanning
|
||||
# maxretry = 3
|
||||
# findtime = 1d
|
||||
# bantime = 7200
|
||||
# action = %(action_mwl)s
|
||||
# %(action_abuseipdb)s[matches="%(tp_comment)s", abuseipdb_apikey="YOUR_API_KEY", abuseipdb_category="21,15", bantime="%(bantime)s"]
|
||||
#
|
||||
# Usage:
|
||||
# This script is designed to be triggered automatically by Fail2Ban (`actionstart|actionban`).
|
||||
# For testing (manual execution):
|
||||
# - For testing purpose before production;
|
||||
# /etc/fail2ban/action.d/fail2ban_abuseipdb.sh "your_api_key" "Failed SSH login attempts" "192.0.2.1" "18" "600"
|
||||
#
|
||||
# Arguments:
|
||||
# $1 APIKEY - Required (Core). Retrieved automatically from the Fail2Ban 'jail'. | Your AbuseIPDB API key.
|
||||
# $2 COMMENT - Required (Core). Retrieved automatically from the Fail2Ban 'jail'. | A custom comment to prevent the leakage of sensitive data when reporting
|
||||
# $3 IP - Required (Core). Retrieved automatically from the Fail2Ban 'jail'. | The IP address to report.
|
||||
# $4 CATEGORIES - Required (Core). Retrieved automatically from the Fail2Ban 'jail'. | Abuse categories as per AbuseIPDB's API
|
||||
# $5 BANTIME - Required (Core). Retrieved automatically from the Fail2Ban 'jail'. | Ban duration
|
||||
# $6 RESTORED - Required (Core). Retrieved automatically from the Fail2Ban '<restored>' | Status of restored tickets
|
||||
# $7 BYPASS_FAIL2BAN - Required (User defined). Must be defined in 'action.d/abuseipdb.local'. | Bypassing Fail2Ban on restarts
|
||||
# $2|$8 SQLITE_DB - Required (User defined). Must be defined in 'action.d/abuseipdb.local'. | Path to the main AbuseIPDB SQLite database
|
||||
# $3|$9 LOG_FILE - Required (User defined). Must be defined in 'action.d/abuseipdb.local'. | Path to the log file where actions and events are recorded by the script
|
||||
#
|
||||
# Dependencies:
|
||||
# curl: For making API requests to AbuseIPDB.
|
||||
# jq: For parsing JSON responses.
|
||||
# sqlite3: Local AbuseIPDB db.
|
||||
#
|
||||
# Author:
|
||||
# Hasan ÇALIŞIR
|
||||
# https://github.com/hsntgm
|
||||
|
||||
#######################################
|
||||
# HELPERS: (START)
|
||||
#######################################
|
||||
|
||||
APIKEY="$1"
|
||||
COMMENT="$2"
|
||||
IP="$3"
|
||||
CATEGORIES="$4"
|
||||
BANTIME="$5"
|
||||
RESTORED="$6"
|
||||
BYPASS_FAIL2BAN="${7:-0}"
|
||||
|
||||
if [[ "$1" == "--actionstart" ]]; then
|
||||
SQLITE_DB="${2:-/var/lib/fail2ban/abuseipdb/fail2ban_abuseipdb}"
|
||||
LOG_FILE="${3:-/var/log/abuseipdb/abuseipdb.log}"
|
||||
else
|
||||
SQLITE_DB="${8:-/var/lib/fail2ban/abuseipdb/fail2ban_abuseipdb}"
|
||||
LOG_FILE="${9:-/var/log/abuseipdb/abuseipdb.log}"
|
||||
fi
|
||||
|
||||
log_message() {
|
||||
local message="$1"
|
||||
echo "$(date +"%Y-%m-%d %H:%M:%S") - ${message}" >> "${LOG_FILE}"
|
||||
}
|
||||
|
||||
LOCK_INIT="/tmp/abuseipdb_actionstart_init.lock"
|
||||
LOCK_BAN="/tmp/abuseipdb_actionstart_ban.lock"
|
||||
LOCK_DONE="/tmp/abuseipdb_actionstart_done.lock"
|
||||
|
||||
remove_lock() {
|
||||
[[ -f "${LOCK_BAN}" ]] && rm -f "${LOCK_BAN}"
|
||||
}
|
||||
|
||||
create_lock() {
|
||||
[[ ! -f "${LOCK_BAN}" ]] && touch "${LOCK_BAN}"
|
||||
}
|
||||
|
||||
SQLITE_NON_PERSISTENT_PRAGMAS="PRAGMA synchronous=NORMAL; \
|
||||
PRAGMA locking_mode=NORMAL; \
|
||||
PRAGMA busy_timeout=10000;"
|
||||
|
||||
#######################################
|
||||
# HELPERS: (END)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# ACTIONSTART: (START)
|
||||
#######################################
|
||||
|
||||
########################################
|
||||
# Triggered by 'actionstart'
|
||||
# to perform necessary checks
|
||||
# and AbuseIPDB SQLite initialization.
|
||||
#
|
||||
# - Ensures required checks are done.
|
||||
# - Runs in the background with 'nohup'
|
||||
# on initial start to prevent latency.
|
||||
# - Listens for exit codes to control
|
||||
# further 'actionban' events via the
|
||||
# 'LOCK_BAN' mechanism.
|
||||
# - Use 'LOCK_INIT' and 'LOCK_DONE' to
|
||||
# manage concurrent calls on restarts.
|
||||
########################################
|
||||
|
||||
if [[ "$1" == "--actionstart" ]]; then
|
||||
(
|
||||
flock -n 200 || {
|
||||
[[ -f "${LOG_FILE}" ]] && log_message "WARNING: Another initialization is already running. Exiting."
|
||||
exit 0
|
||||
}
|
||||
|
||||
if [[ -f "${LOCK_DONE}" ]]; then
|
||||
log_message "INFO: Initialization already completed. Skipping further checks."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
trap 'if [[ $? -ne 0 ]]; then create_lock; else remove_lock; fi' EXIT
|
||||
|
||||
SQLITE_DIR=$(dirname "${SQLITE_DB}")
|
||||
if [[ ! -d "${SQLITE_DIR}" ]]; then
|
||||
mkdir -p "${SQLITE_DIR}" || exit 1
|
||||
fi
|
||||
|
||||
LOG_DIR=$(dirname "${LOG_FILE}")
|
||||
if [[ ! -d "${LOG_DIR}" ]]; then
|
||||
mkdir -p "${LOG_DIR}" || exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [[ ! -f "${LOG_FILE}" ]]; then
|
||||
touch "${LOG_FILE}" || exit 1
|
||||
fi
|
||||
|
||||
for dep in curl jq sqlite3; do
|
||||
if ! command -v "${dep}" &>/dev/null; then
|
||||
log_message "ERROR: ${dep} is not installed. Please install ${dep}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ ! -f "${SQLITE_DB}" ]]; then
|
||||
log_message "INFO: AbuseIPDB database not found. Initializing..."
|
||||
sqlite3 "${SQLITE_DB}" "
|
||||
PRAGMA journal_mode=WAL;
|
||||
CREATE TABLE IF NOT EXISTS banned_ips (
|
||||
ip TEXT PRIMARY KEY,
|
||||
bantime INTEGER
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_ip ON banned_ips(ip);
|
||||
" &>/dev/null
|
||||
log_message "INFO: AbuseIPDB database is initialized!"
|
||||
fi
|
||||
|
||||
table=$(sqlite3 "${SQLITE_DB}" "SELECT name FROM sqlite_master WHERE type='table' AND name='banned_ips';")
|
||||
if ! [[ -n "${table}" ]]; then
|
||||
log_message "ERROR: AbuseIPDB database initialization failed."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
touch "${LOCK_DONE}" || exit 1
|
||||
log_message "SUCCESS: All (actionstart) checks completed!"
|
||||
exit 0
|
||||
|
||||
) 200>"${LOCK_INIT}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
#######################################
|
||||
# ACTIONSTART: (END)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# ACTIONBAN: (START)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# 1) Fail2Ban restart handling &
|
||||
# duplicate report prevention.
|
||||
#
|
||||
# - If 'BYPASS_FAIL2BAN' is disabled,
|
||||
# Fail2Ban manages reports on restart
|
||||
# and prevents duplicate submissions.
|
||||
# - This setting can be overridden in
|
||||
# 'action.d/abuseipdb.local'.
|
||||
# - If enabled, Fail2Ban is bypassed,
|
||||
# and the script independently
|
||||
# decides which IPs to report based
|
||||
# on the local AbuseIPDB SQLite db,
|
||||
# even after restarts.
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# 2) Prevent 'actionban' if
|
||||
# 'actionstart' fails.
|
||||
#
|
||||
# - If 'actionstart' fails, block
|
||||
# 'actionban' to prevent issues from
|
||||
# missing dependencies or permission
|
||||
# errors.
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# 3) Core argument validation
|
||||
#
|
||||
# - Ensures all required arguments
|
||||
# are provided.
|
||||
# - Expected from Fail2Ban 'jail' or
|
||||
# for manual testing before
|
||||
# production deployment.
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# EARLY CHECKS: (START)
|
||||
#######################################
|
||||
|
||||
if [[ "${BYPASS_FAIL2BAN}" -eq 0 && "${RESTORED}" -eq 1 ]]; then
|
||||
log_message "INFO: (RESTART) IP ${IP} was already reported in the previous Fail2Ban session."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -f "${LOCK_BAN}" ]]; then
|
||||
[[ -f "${LOG_FILE}" ]] && log_message "ERROR: Initialization failed! (actionstart). Reporting for IP ${IP} is blocked."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "${APIKEY}" || -z "${COMMENT}" || -z "${IP}" || -z "${CATEGORIES}" || -z "${BANTIME}" ]]; then
|
||||
log_message "ERROR: Missing core argument(s)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
#######################################
|
||||
# EARLY CHECKS: (END)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# FUNCTIONS: (START)
|
||||
#######################################
|
||||
|
||||
check_ip_in_abuseipdb() {
|
||||
local response http_status body total_reports delimiter="HTTP_STATUS:"
|
||||
if ! response=$(curl -sS -w "${delimiter}%{http_code}" -G "https://api.abuseipdb.com/api/v2/check" \
|
||||
--data-urlencode "ipAddress=${IP}" \
|
||||
-H "Key: ${APIKEY}" \
|
||||
-H "Accept: application/json" 2>&1); then
|
||||
log_message "ERROR: curl failed. Response: ${response}"
|
||||
return 2
|
||||
fi
|
||||
|
||||
http_status="${response##*${delimiter}}"
|
||||
body="${response%"${delimiter}${http_status}"}"
|
||||
|
||||
if [[ ! "${http_status}" =~ ^[0-9]+$ ]]; then
|
||||
log_message "ERROR: Invalid HTTP status in Response: ${response}"
|
||||
return 2
|
||||
fi
|
||||
|
||||
if [[ "${http_status}" -ne 200 ]]; then
|
||||
if [[ "${http_status}" -eq 429 ]]; then
|
||||
log_message "ERROR: Rate limited (HTTP 429). Response: ${body}"
|
||||
else
|
||||
log_message "ERROR: HTTP ${http_status}. Response: ${body}"
|
||||
fi
|
||||
return 2
|
||||
fi
|
||||
|
||||
total_reports=$(jq -r '.data.totalReports // 0' <<< "${body}")
|
||||
if (( total_reports > 0 )); then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
convert_bantime() {
|
||||
local bantime=$1 time_value time_unit
|
||||
if [[ "${bantime}" =~ ^[0-9]+$ ]]; then
|
||||
echo "${bantime}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
time_value="${bantime%"${bantime##*[0-9]}"}"
|
||||
time_unit="${bantime#${time_value}}"
|
||||
|
||||
[[ -z "$time_unit" ]] && time_unit="s"
|
||||
case "$time_unit" in
|
||||
s) echo "$time_value" ;;
|
||||
m) echo "$((time_value * 60))" ;;
|
||||
h) echo "$((time_value * 3600))" ;;
|
||||
d) echo "$((time_value * 86400))" ;;
|
||||
w) echo "$((time_value * 604800))" ;;
|
||||
y) echo "$((time_value * 31536000))" ;;
|
||||
*) echo "${time_value}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
report_ip_to_abuseipdb() {
|
||||
local response http_status body delimiter="HTTP_STATUS:"
|
||||
if ! response=$(curl -sS -w "${delimiter}%{http_code}" "https://api.abuseipdb.com/api/v2/report" \
|
||||
-H 'Accept: application/json' \
|
||||
-H "Key: ${APIKEY}" \
|
||||
--data-urlencode "comment=${COMMENT}" \
|
||||
--data-urlencode "ip=${IP}" \
|
||||
--data "categories=${CATEGORIES}" 2>&1); then
|
||||
log_message "ERROR: curl failed. Response: ${response}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
http_status="${response##*${delimiter}}"
|
||||
body="${response%"${delimiter}${http_status}"}"
|
||||
|
||||
if [[ ! "${http_status}" =~ ^[0-9]+$ ]]; then
|
||||
log_message "ERROR: Invalid HTTP status in response: ${response}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "${http_status}" -ne 200 ]]; then
|
||||
if [[ "${http_status}" -eq 429 ]]; then
|
||||
log_message "ERROR: Rate limited (HTTP 429). Response: ${body}"
|
||||
else
|
||||
log_message "ERROR: HTTP ${http_status}. Response: ${body}"
|
||||
fi
|
||||
return 1
|
||||
fi
|
||||
|
||||
log_message "SUCCESS: Reported IP ${IP} to AbuseIPDB."
|
||||
return 0
|
||||
}
|
||||
|
||||
check_ip_in_db() {
|
||||
local ip=$1 result
|
||||
ip="${ip%"${ip##*[![:space:]]}"}"
|
||||
ip="${ip#"${ip%%[^[:space:]]*}"}"
|
||||
ip="${ip//\'/}"
|
||||
ip="${ip//\"/}"
|
||||
|
||||
sqlite3 "${SQLITE_DB}" "${SQLITE_NON_PERSISTENT_PRAGMAS}" &>/dev/null
|
||||
result=$(sqlite3 "${SQLITE_DB}" "SELECT EXISTS(SELECT 1 FROM banned_ips WHERE ip = '${ip}');")
|
||||
|
||||
if [[ "${result}" -eq 1 ]]; then
|
||||
return 0
|
||||
elif [[ "${result}" -eq 0 ]]; then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
fi
|
||||
}
|
||||
|
||||
insert_ip_to_db() {
|
||||
local ip=$1 bantime=$2
|
||||
bantime=$(convert_bantime "${bantime}")
|
||||
|
||||
bantime="${bantime%"${bantime##*[![:space:]]}"}"
|
||||
bantime="${bantime#"${bantime%%[^[:space:]]*}"}"
|
||||
bantime="${bantime//\'/}"
|
||||
bantime="${bantime//\"/}"
|
||||
|
||||
ip="${ip%"${ip##*[![:space:]]}"}"
|
||||
ip="${ip#"${ip%%[^[:space:]]*}"}"
|
||||
ip="${ip//\'/}"
|
||||
ip="${ip//\"/}"
|
||||
|
||||
sqlite3 "${SQLITE_DB}" "${SQLITE_NON_PERSISTENT_PRAGMAS}" &>/dev/null
|
||||
sqlite3 "${SQLITE_DB}" "
|
||||
BEGIN IMMEDIATE;
|
||||
INSERT INTO banned_ips (ip, bantime)
|
||||
VALUES ('${ip}', ${bantime})
|
||||
ON CONFLICT(ip) DO UPDATE SET bantime=${bantime};
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
# TO-DO: Better handle SQLite INSERT ops. exit statuses
|
||||
# $? -ne 0 | I think not the best approach here.
|
||||
if [[ $? -ne 0 ]]; then
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
delete_ip_from_db() {
|
||||
local ip=$1
|
||||
ip="${ip%"${ip##*[![:space:]]}"}"
|
||||
ip="${ip#"${ip%%[^[:space:]]*}"}"
|
||||
ip="${ip//\'/}"
|
||||
ip="${ip//\"/}"
|
||||
|
||||
sqlite3 "${SQLITE_DB}" "${SQLITE_NON_PERSISTENT_PRAGMAS}" &>/dev/null
|
||||
sqlite3 "${SQLITE_DB}" "
|
||||
BEGIN IMMEDIATE;
|
||||
DELETE FROM banned_ips WHERE ip='${ip}';
|
||||
COMMIT;
|
||||
"
|
||||
|
||||
# TO-DO: Do we need to listen exit status DELETE
|
||||
# I don't think so for now.
|
||||
log_message "INFO: IP ${ip} deleted from the AbuseIPDB SQLite database."
|
||||
}
|
||||
|
||||
#######################################
|
||||
# FUNCTIONS: (END)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# MAIN (START)
|
||||
#######################################
|
||||
|
||||
(
|
||||
is_found_local=0
|
||||
shouldBanIP=1
|
||||
|
||||
if check_ip_in_db $IP; then
|
||||
is_found_local=1
|
||||
if check_ip_in_abuseipdb; then
|
||||
log_message "INFO: IP ${IP} has already been reported and remains on AbuseIPDB."
|
||||
shouldBanIP=0
|
||||
else
|
||||
status=$?
|
||||
if [[ "${status}" -eq 1 ]]; then
|
||||
log_message "INFO: IP ${IP} has already been reported but is no longer listed on AbuseIPDB. Resubmitting..."
|
||||
else
|
||||
log_message "ERROR: Failed to check IP ${IP} in the AbuseIPDB API. Skipping report."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
else
|
||||
status=$?
|
||||
if [[ "${status}" -eq 2 ]]; then
|
||||
log_message "ERROR: Failed to check IP ${IP} in the local database. Skipping report."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${shouldBanIP}" -eq 1 ]]; then
|
||||
if [[ "${is_found_local}" -eq 0 ]]; then
|
||||
if ! insert_ip_to_db $IP $BANTIME; then
|
||||
log_message "ERROR: Failed to insert IP ${IP} into the local database. Skipping report."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! report_ip_to_abuseipdb; then
|
||||
delete_ip_from_db $IP
|
||||
fi
|
||||
fi
|
||||
) >> "${LOG_FILE}" 2>&1 &
|
||||
|
||||
#######################################
|
||||
# MAIN (END)
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# ACTIONBAN: (END)
|
||||
#######################################
|
||||
|
||||
exit 0
|
Loading…
Reference in New Issue