TechSomething

Check if your public ip is soiled, also with desktop notifications

Why: #

In the era of remote connections, Smart Working, Work From Home and Work From Anywhere, your Public IP might change often and you might end up with a "soiled" IP, an IP that has been used to spam, brute-force or other unpleasant behaviours you don't want to be associated with.

So I felt the need to check the rating of my public ip, since it might change from time to time and some cloud services might check your ip rating and raise a red flag in case you are connecting from one of those unwelcome ips.

I've written a modular script in bash so it can be implemented to generate a notification on Windows or your favourite flavour of Linux.

The script has been updated to support WSL, Linux and MacOsX out of the box,
and has been tested on WSL (v1) and Ubuntu 20.04 Desktop.

Prerequisites: #

to run the script you'll need:

only on Windows you'll need:

Retrieve your ip: #

I'll use a service I love which is ifconfig.co,
it's a no-nonsense what-is-my-ip, and perfectly queryable with many tools like curl,
so if

curl http://ifconfig.co/ip

you just have your ip, ready to be used in a variable.

APIs to check ips blacklist: #

I've used abusedipdb.com:
on https://www.abuseipdb.com/ register an account and on https://www.abuseipdb.com/account/api request a new API key

For the free tier account you have 1000 checks/day (https://www.abuseipdb.com/pricing),
that translates to about to being able to do a check every 1.5minutes on a single ip,
which is way more than I need since I'll be checking every 15min for 12 hours = 48 checks/day.

So I'll be able to use the same API key with the same script on different machines,
or, way better, I can create different API keys for every script, in the end the limit of my free account is common for all my API keys.

Bash script: #

(in WSL or Linux) I've put my script in my home,
so: /home/myuser/iptest.sh

#!/bin/bash

#VARIABLES:
ip_current=$(curl ifconfig.co/ip)
#ip_current="INSERT_BAD_IP" #this is for testing purposes, if you want to test your script with a known bad ip you can insert it here, decomment this line and comment the other ip_current. you can find a bad ip on the site https://www.abuseipdb.com/ in homepage under "Recently Reported IPs:"
ip_status="NULL"
notification="!!WARNING!!_Your_IP_is_SOILED!_"
api_key="INSERT_YOUR_API_KEY"
wsl_applogo=" -Applogo C:/Location/Of/Your/Image.png "
linux_logo=" -i /usr/share/icons/gnome/32x32/emblems/emblem-important.png "
platform='unknown'

#PLATFORM CHECK, to verify which platform the script is running on:
unamestr=$(uname -a)
if [[ "$unamestr" == *"Microsoft"* ]]; then
platform='wsl'
elif [[ "$unamestr" == *"FreeBSD"* ]]; then
platform='freebsd'
elif [[ "$unamestr" == *"Darwin"* ]]; then
platform='macosx'
elif [[ "$unamestr" == *"Linux"* ]]; then
platform='linux'
fi
#DEBUGGING (platform):
# echo $platform"


#PRECHECKS, checking if the needed software is installed:
if [[ "$platform" == "wsl" ]]; then
echo "platform is unknown, exiting"
exit
fi
if [[ "$platform" == "linux" ]] || [[ "$platform" == "wsl" ]] || [[ "$platform" == "macosx" ]]; then
if ! command -v jq &> /dev/null
then
echo "jq not found, install jq"
exit
fi
if ! command -v curl &> /dev/null
then
echo "curl not found, install curl"
exit
fi
fi
if [[ "$platform" == "wsl" ]]; then
if ! [[ $(/mnt/c/windows/System32/WindowsPowerShell/v1.0/powershell.exe Get-Module -ListAvailable -Name BurntToast) == *"BurntToast"* ]]; then
echo "BurntToast not found, install BurntToast"
exit
fi
fi


#Retrieve ip status
ip_status=$(curl -s -G https://api.abuseipdb.com/api/v2/check --data-urlencode "ipAddress=$ip_current" -d maxAgeInDays=30 -H "Key: $api_key" -H "Accept: application/json")

#Check if the output of curl is ok:
if [ "$ip_status" == "NULL" ]; then
echo "curl failed";
exit;
fi

#Extract the data we need from the json answer:
ip_reports=$(echo $ip_status | jq -c '.[] | .totalReports')
ip_users=$(echo $ip_status | jq -c '.[] | .numDistinctUsers')
ip_whitelist=$(echo $ip_status | jq -c '.[] | .isWhitelisted')
ip_score=$(echo $ip_status | jq -c '.[] | .abuseConfidenceScore')

#DEBUGGING (uncomment as you like):
#echo $ip_status
#echo $ip_status_clean
#echo $ip_reports
#echo $ip_users
#echo $ip_whitelist
#echo $ip_score

#Write last execution time to file (that's also debugging):
echo "updated on $(date +%Y%m%d-%H%M)" > /tmp/iptest.last

#Check the ip parameters and generate notification if over threshold:
if [ "$ip_reports" -ge "20" ] || [ "$ip_users" -ge "5" ] || [ "ip_whitelist" = "false" ] || [ "$ip_score" -ge "50" ]
then
case $platform in
wsl)
/mnt/c/windows/System32/WindowsPowerShell/v1.0//powershell.exe -command New-BurntToastNotification $wsl_applogo -Text "$notification""$ip_current"
;;
linux)
notify-send -u critical $linux_logo -t 300000 "$notification""$ip_current"
;;
macosx)
osascript -e 'display notification "It is better to change your IP" with title "YO!" subtitle "$notification""$ip_current"'
;;
esac
fi

NB:
you (might) need to change:

variable outputs: #

these are examples of the debugging variables output in case of:

an ip that's ok:

an ip that is soiled:

the thresholds I set (for a period of 30days):

any violation of these thresholds triggers the warning.

these thresholds are a work in progress.

Windows: #

I use WSL: Windows Subsystem for Linux version 1,
since I am not using WSL2 this guide is not tested with WSL2.

Install BurntToast for notifications on windows: #

install BurntToast for notifications:

Install-Module -Name BurntToast

if needed set the execution policy as required:

#Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser

then import the module and test a notification:

Import-Module BurntToast
New-BurntToastNotification -Text hello

source: https://github.com/microsoft/WSL/issues/2466

Notification image support #

if you want to add personality to your warnings you can add an image like:

description

New-BurntToastNotification -Applogo C:\Location\Of\Your\Image.png -Text notification_with_image

NB: the image path must be from the Windows system point of view, not WSL, hence C:...

the result will be:

description

auto-run Cron on WSL on Win: #

we need to enable cron so our script can run unattended,
so edit your sudoers file with

sudo visudo

and add this line:

%sudo ALL=NOPASSWD: /etc/init.d/cron start

then on Win run this command in cmd-run:

explorer.exe shell:startup

and create a new shortcut with this location:

C:\Windows\System32\wsl.exe sudo /etc/init.d/cron start

and choose a name (I choose WSL_Start_Cron)

then doubleclick your newly created shortcut to run it

if you execute

ps -ef | grep cron

now you'll see that cron is running,
I've tested rebooting and after the system comes up everything works fine.

source: https://www.linkedin.com/pulse/wsl-linux-daemons-including-cron-john-west?articleId=6730365747916365824

##configure cron to run the script:

on your shell edit your crontab:

crontab -e

add this line at the end of the file (changing "myuser" with your actual user):

*/15 8-19       * * 1-5 /home/myuser/iptest.sh

how's the schedule:
you can use the good old Crontab Guru to fiddle with it fi you are not very keen with crontab: https://crontab.guru/#/15_8-19__*_1-5

tl;dr: MON-FRI from 8 to 19 every 15min = slighlty extended work hours.

director's cut:

Notification result on Windows: #

(the ip shown in the notifications is not mine, I took one from the blacklist)

description

description