IP Bulk Reporter

Instead of reporting IPs individually, you may compile a CSV of reports. This helps reduce bandwidth on both sides. Note: The abuse confidence score of a IP reported this way is not immediately calculated.

The CSV file must be under 2 MB and less than or equal to 10,000 lines, including the headings.

CSV Format Strict ordering, Strict headings

  1. IP — A valid IPv4 or IPv6 IP address.
  2. Categories — At least one category ID. Comma separated for multiple categories. See: Report Categories
  3. ReportDate — Date and time of the attack or earliest observance of attack. Any format that strtotime() can process is permitted. However, we recommend a timezoned format such ISO 8601 e.g. 2017-09-08T10:00:37-04:00. A time lacking a timezone will assumed to be in our server timezone (EST).
  4. Comment — A description of the attack. Truncated after 1,024 characters (bytes). NOTE: The values of this column are entirely optional. However, you must have the Comment header.

Here is a sample of a valid bulk IP file:

IP,Categories,ReportDate,Comment,"18,22",2018-12-18T10:00:37-04:00,"Failed password for invalid user odoo from port 39121 ssh2","18,22",2018-12-18T11:25:11-04:00,"Did not receive identification string from port 57192","14,15,18,11,10,21",2018-12-18T16:10:58+04:00,"[SMB remote code execution attempt: port tcp/445]
in blocklist.de:'listed [pop3]'
in SpamCop:'listed'
in sorbs:'listed [web], [spam]'
in Unsubscore:'listed'

The Comment must be enclosed in double quotes (") to include commas (,) and new line separators (\n, \r, \r\n). A blacklash (\) is needed to escape the enclosure. It does not escape itself.

Categories must be enclosed if there is more than one.

Max Filesize: 2 MB

Please abide by our reporting policy. Must be signed-in to use bulk reporter.

Collecting the Data

Attacks can easily be harvested from /var/log/secure/ or wherever you store security logs. Take a gander at a sample bash script we provide that can run daily. Run the script with your log file as the first operand and your API key as the second. The -d may be set to perform a dry run, where the generated file will not be uploaded to our server.


$ ./parse-logs.sh secure.log $YOUR_API_KEY

By default, you should receive a JSON response listing which reports were accepted and which were rejected. Pipe the output into jq if you'd like to peruse the response.

$ cat output.json | jq



# By default, this is not a dry run.

# Options, a while loop will allow us to add more options in the future.
while getopts "d" opt; do
	case $opt in
		d) echo "Performing dry run. Results will not submitted to AbuseIPDB"; dryRun=1 ;;
		\?) echo "Invalid option: -$OPTARG" >&2 ;;

# Skip over the processed options.
shift $((OPTIND-1))

# Operand: the file to parse.
# Operand: the API key of the AbuseIPDB user.

# Standard operand checking.
if [ -z $1 ]; then
	echo "Missing input file. Aborting." >&2
	exit 1;
elif [ ! -r $1 ]; then
	echo "File does not exist or is not readable. Aborting." >&2
	exit 1;
elif [ -z $2 ] && [ $dryRun -eq 0 ]; then
	echo "Missing API Key" >&2
	exit 1;

# pcregrep is not preinstalled on many linux distros.
# It's shipped in the "pcre-tools" package for RedHat/Fedora.
if [ ! -x "$(command -v pcregrep)" ]; then
	echo "Command 'pcregrep' required, but is not installed. Aborting." >&2
	exit 1;

# Pick the Unit Separator (non-printing character) to delimit the fields.

# Find the pattern matches for an invalid user.
pcregrep -o1 -o2 -o3 --om-separator="$unit_sep" -e '([a-zA-Z]+ [0-9]+ [0-9]+:[0-9]+:[0-9]+) .* (Invalid user [a-zA-Z0-9]+ from (([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})) port [0-9]+)' $secureLogFile > matches.txt

# Create CSV headers.
echo "IP,Categories,ReportDate,Comment" > report.csv

# Rearrange the order of the fields for our bulk uploader.
# IP & ReportDate generally don't need to be enclosed, but we'll play it safe.
gawk -F "$unit_sep" 'BEGIN {OFS=","} {print "\""$3"\",\"18,22\",\""$1"\",\""$2"\""}' matches.txt >> report.csv

# Clean up. Comment out if you want to peruse the matches.
rm matches.txt

# Check dry run option.
if [ $dryRun -eq 0 ]; then
	# Report to AbuseIPDB.
	curl https://api.abuseipdb.com/api/v2/bulk-report \
        -F [email protected] \
        -H "Key: $key" \
    	-H "Accept: application/json" \
    	> output.json

exit 0;
** This Document Provided By AbuseIPDB **
Source: https://www.abuseipdb.com/bulk-report