IP Quality Detection & Automatic Monitoring System

📋 Functional Overview

This project consists of two core scripts designed to implement IP Quality Detection and Automatic IP Change Monitoring & Notification:

🔍 ip.sh - IP Quality Check Script

A powerful IP quality detection tool that can:

  • Comprehensive IP Quality Check: Queries 10+ databases to obtain IP geolocation, ASN, risk scores, and more.
  • Streaming Service Unlock Detection: Tests access to services like Netflix, Disney+, YouTube Premium, TikTok, Amazon Prime Video, etc.
  • AI Service Detection: Checks availability for services like ChatGPT, Reddit, and more.
  • Email Blacklist Detection: Checks if the IP is listed in 50+ email blacklist databases.
  • Port 25 Detection: Tests mail server connectivity.
  • Risk Scoring: Provides a comprehensive IP risk level based on multiple databases.
  • PNG Image Report: Automatically converts color terminal output to an image for easy sharing.
  • Multi-language Support: Supports multiple languages including Chinese, English, and Japanese.
  • Automatic Dependency Installation: Automatically detects and installs required dependencies (jq, curl, bc, ansilove, etc.).

You can find it on its Official GitHub Repository. Based on it, I have made some modifications, primarily to support saving test results as PNG images in the current directory, making it convenient to upload results directly to a Telegram Bot.

🎨 Key Modification 1: PNG Image Output

New global variables (Lines 36-38):

declare ADLines
+declare -a all_reports=()      # New: Used to collect all test reports
+declare PNG_OUTPUT_DIR="/root" # New: PNG output directory

Modified report collection logic (Lines 2696-2700). In the check_IP() function, reports are collected after each test:

# Original code
[[ mode_json -eq 0 ]]&&echo -ne "\r$ip_report\n"
[[ mode_json -eq 0 && mode_privacy -eq 0 && $report_link == *"https://Report.Check.Place/"* ]]&&echo -ne "\r${stail[link]}$report_link$Font_Suffix\n"
[[ mode_json -eq 1 ]]&&echo -ne "\r$ipjson\n"
echo -ne "\r\n"

# Modified (4 new lines)
[[ mode_json -eq 0 ]]&&echo -ne "\r$ip_report\n"
[[ mode_json -eq 0 && mode_privacy -eq 0 && $report_link == *"https://Report.Check.Place/"* ]]&&echo -ne "\r${stail[link]}$report_link$Font_Suffix\n"
[[ mode_json -eq 1 ]]&&echo -ne "\r$ipjson\n"
echo -ne "\r\n"
+# New: Collect reports for PNG output
+local full_report="$ip_report"
+[[ mode_json -eq 0 && mode_privacy -eq 0 && $report_link == *"https://Report.Check.Place/"* ]]&&full_report+="\n${stail[link]}$report_link$Font_Suffix"
+all_reports+=("$full_report")
echo

New generate_png() function (Lines 2711-2735):

generate_png(){
    if [[ ${#all_reports[@]} -eq 0 ]];then
        return
    fi
    
    if ! command -v ansilove >/dev/null 2>&1;then
        echo -e "${Font_Yellow}WARNING: ansilove not found, skipping PNG generation.${Font_Suffix}" 1>&2
        return
    fi
    
    mkdir -p "$PNG_OUTPUT_DIR" 2>/dev/null
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local tmp_ansi=$(mktemp /tmp/ipcheck_XXXXXX.ans)
    
    # Merge all reports into a temporary ANSI file
    for report in "${all_reports[@]}";do
        echo -e "$report" >>"$tmp_ansi"
        echo "" >>"$tmp_ansi"
    done
    
    local png_file="${PNG_OUTPUT_DIR}/ip_quality_${timestamp}.png"
    ansilove -o "$png_file" "$tmp_ansi" >/dev/null 2>&1
    
    if [[ $? -eq 0 && -f "$png_file" ]];then
        echo -e "${Font_Green}${Font_B}PNG report saved: ${png_file}${Font_Suffix}" 1>&2
    else
        echo -e "${Font_Yellow}WARNING: PNG generation failed. ANSI file kept at: ${tmp_ansi}${Font_Suffix}" 1>&2
        return
    fi
    
    rm -f "$tmp_ansi"
}

PNG generation called in the main flow (Line 2755):

# Original code
clear
show_ad
[[ $IPV4work -ne 0 && $IPV4check -ne 0 ]]&&check_IP "$IPV4" 4
[[ $IPV6work -ne 0 && $IPV6check -ne 0 ]]&&check_IP "$IPV6" 6

# Modified (1 new line)
clear
show_ad
[[ $IPV4work -ne 0 && $IPV4check -ne 0 ]]&&check_IP "$IPV4" 4
[[ $IPV6work -ne 0 && $IPV6check -ne 0 ]]&&check_IP "$IPV6" 6
+generate_png  # New: Generate PNG after all tests are completed

🎨 Key Modification 2: Enhanced Dependency Detection and Auto-installation

Improved install_dependencies() function (Lines 403-455). Original version: Only basic dependency detection, all-or-nothing.

install_dependencies(){
    +local need_basic=0
    +local need_ansilove=0
    
    +# Detect basic tools individually
    if ! jq --version >/dev/null 2>&1||! curl --version >/dev/null 2>&1||...; then
        +need_basic=1
    fi
    
    +# Detect ansilove
    +if ! ansilove -v >/dev/null 2>&1;then
    +    need_ansilove=1
    +fi
    
    +# Only install when there are missing dependencies
    +if [[ $need_basic -eq 1 || $need_ansilove -eq 1 ]];then
        echo "Detecting operating system..."
        # Install corresponding packages as needed
    +fi
}

Improved install_packages() function (Lines 457-540), added parameters: receives need_basic and need_ansilove flags.

install_packages(){
    local package_manager=$1
    local install_command=$2
    local no_sudo=$3
    +local need_basic=$4      # New
    +local need_ansilove=$5   # New
    
    +# Dynamically build dependency list
    +local dep_list=""
    +[[ $need_basic -eq 1 ]]&&dep_list+="jq curl bc netcat dnsutils iproute "
    +[[ $need_ansilove -eq 1 ]]&&dep_list+="ansilove "
    
    echo "Using package manager: $package_manager"
    -echo -e "...jq curl bc netcat dnsutils iproute..."  # Original: Fixed text
    +echo -e "...${dep_list}..."  # Modified: Dynamic text

New install_ansilove_from_source() function (Lines 542-579). A completely new function for compiling ansilove from source:

install_ansilove_from_source(){
    echo "ansilove not available in package manager, installing from source..."
    local usesudo=""
    [ $(id -u) -ne 0 ]&&usesudo="sudo"
    local tmpdir=$(mktemp -d)
    
    # Install build dependencies
    if command -v apt-get >/dev/null 2>&1;then
        $usesudo apt-get install -y cmake make gcc git libansilove-dev 2>/dev/null||
        $usesudo apt-get install -y cmake make gcc git libgd-dev 2>/dev/null
    elif command -v dnf >/dev/null 2>&1;then
        $usesudo dnf install -y cmake make gcc git gd-devel 2>/dev/null
    elif command -v yum >/dev/null 2>&1;then
        $usesudo yum install -y cmake make gcc git gd-devel 2>/dev/null
    fi
    
    cd "$tmpdir"
    
    # Compile libansilove
    git clone https://github.com/ansilove/libansilove.git 2>/dev/null
    if [ -d libansilove ];then
        cd libansilove
        mkdir build&&cd build
        cmake ..
        make
        $usesudo make install
        cd "$tmpdir"
    fi
    
    # Compile ansilove
    git clone https://github.com/ansilove/ansilove.git 2>/dev/null
    if [ -d ansilove ];then
        cd ansilove
        mkdir build&&cd build
        cmake ..
        make
        $usesudo make install
        $usesudo ldconfig 2>/dev/null
    fi
    
    cd /
    rm -rf "$tmpdir"
}

📡 monitor_ip.sh - IP Change Monitoring & Telegram Notification Script

An intelligent IP monitoring script that can:

  • Automatic IP Change Detection: Checks your public IPv4 address every 5 minutes.
  • Multi-API Failover: Uses 6 fallback APIs to ensure IP retrieval even when the network is unstable.
  • Automatic Detection Trigger: Automatically runs ip.sh for a comprehensive check when the IP changes.
  • Telegram Push: Sends the PNG report of the detection results to a Telegram Bot.
  • Intelligent Waiting: Dynamically waits for PNG generation (up to 120 seconds).
  • Automatic Cleanup: Automatically deletes PNG files after successful sending to avoid accumulation.
  • Detailed Logging: Records all operations in a log file for easy troubleshooting.

🚀 Quick Start

1️⃣ Download Scripts

# Create directory on the server
mkdir -p /root/ip-monitor
cd /root/ip-monitor

# Download scripts (or upload manually)
# Place ip.sh and monitor_ip.sh in the same directory

2️⃣ Configure monitor_ip.sh

Edit monitor_ip.sh and modify the following configuration:

# Telegram Bot Configuration
TG_BOT_TOKEN="YOUR_BOT_TOKEN"     # Replace with your Bot Token
TG_CHAT_ID="YOUR_CHAT_ID"         # Replace with your Chat ID

How to get Telegram Bot Token and Chat ID?

  1. Create Bot: Search for @BotFather on Telegram, send /newbot to create a Bot and get the Token.
  2. Get Chat ID:
    • Search for your created Bot and send any message.
    • Visit https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates.
    • Find "chat":{"id":123456789} in the returned JSON.

3️⃣ Grant Execution Permissions

chmod +x /root/ip-monitor/ip.sh
chmod +x /root/ip-monitor/monitor_ip.sh

4️⃣ Initial Run (Install Dependencies)

# Run ip.sh manually once to install dependencies automatically
/root/ip-monitor/ip.sh -4 -E -y

Parameter description:

  • -4: Detect IPv4 only.
  • -E: Use English output.
  • -y: Install dependencies automatically without prompting.

5️⃣ Set Up Cron Job

# Edit crontab
crontab -e

# Add the following line (to check every 5 minutes)
*/5 * * * * /root/ip-monitor/monitor_ip.sh >/dev/null 2>&1

6️⃣ Test Run

# Delete IP log file to force a detection trigger
rm -f /root/.current_ip_log

# Run manually once
/root/ip-monitor/monitor_ip.sh

# View logs
tail -f /var/log/ip_monitor.log

📚 Detailed Documentation

I. How ip.sh Works

1.1 Core Functional Modules

ip.sh is a comprehensive IP quality detection tool, mainly consisting of the following modules:

Start Script

Detect and Install Dependencies

Get IPv4/IPv6 Address

Query IP Databases

Detect Streaming Service Unlocking

Detect Email Blacklists

Generate Report

Convert to PNG

Output Results

1.2 Dependency Detection and Auto-installation

The script automatically detects the following dependencies:

Dependency ToolPurposeInstallation Method
jqJSON ParsingPackage Manager
curlHTTP RequestsPackage Manager
bcMathematical CalculationsPackage Manager
netcatPort DetectionPackage Manager
digDNS QueriesPackage Manager
ansiloveANSI → PNG ConversionPackage Manager or Source Compilation

Key Code Snippet:

install_dependencies(){
    local need_basic=0
    local need_ansilove=0
    
    # Detect basic tools
    if ! jq --version >/dev/null 2>&1||! curl --version >/dev/null 2>&1; then
        need_basic=1
    fi
    
    # Detect ansilove
    if ! ansilove -v >/dev/null 2>&1; then
        need_ansilove=1
    fi
    
    # Choose package manager based on OS
    # Supports: apt, dnf, yum, pacman, apk, brew, zypper, xbps
}

1.3 IP Database Query

The script queries the following databases to retrieve IP information:

DatabaseInformation ProvidedAPI Address
MaxmindASN, Geolocation, Timezoneipinfo.check.place
IPinfoIP Type (ISP/Hosting/Business)ipinfo.io
ScamalyticsRisk Scorescamalytics.com
IP2LocationProxy/Tor/VPN Detectionip2location.io
AbuseIPDBAbuse Scoreabuseipdb.com
IPQSFraud Scoreipqualityscore.com
DB-IPGeolocation Validationdb-ip.com

1.4 PNG Image Generation

After completing all tests, the script automatically converts the ANSI-colored report into a PNG image:

generate_png(){
    # Check if ansilove is available
    if ! command -v ansilove >/dev/null 2>&1; then
        return
    fi
    
    # Generate timestamped filename
    local timestamp=$(date +"%Y%m%d_%H%M%S")
    local tmp_ansi=$(mktemp /tmp/ipcheck_XXXXXX.ans)
    
    # Merge all reports into temporary ANSI file
    for report in "${all_reports[@]}"; do
        echo -e "$report" >>"$tmp_ansi"
    done
    
    # Convert to PNG
    local png_file="${PNG_OUTPUT_DIR}/ip_quality_${timestamp}.png"
    ansilove -o "$png_file" "$tmp_ansi" >/dev/null 2>&1
}

Workflow:

Run ip.sh → Execute Detection (30-60s) → Collect Reports → 
Generate PNG → Save to /root/ip_quality_timestamp.png

1.5 Main Parameters

ParameterDescriptionExample
-4Detect IPv4 only./ip.sh -4
-6Detect IPv6 only./ip.sh -6
-EEnglish output./ip.sh -E
-l cnSpecify language./ip.sh -l en
-yInstall dependencies automatically./ip.sh -y
-fShow full IP./ip.sh -f
-pPrivacy mode./ip.sh -p
-jJSON output./ip.sh -j

II. How monitor_ip.sh Works

2.1 Complete Code

#!/bin/bash

# --- Configuration Area ---
# Telegram Bot Configuration
TG_BOT_TOKEN="YOUR_BOT_TOKEN_HERE"
TG_CHAT_ID="YOUR_CHAT_ID_HERE"

# Dynamically get script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# File path configuration
IP_LOG_FILE="/root/.current_ip_log"
TARGET_SCRIPT="$SCRIPT_DIR/ip.sh"
IMAGE_DIR="/root"
LOG_FILE="/var/log/ip_monitor.log"

# 1. Get current public IPv4 address (using multiple fallback services)
IP_APIS=(
    "ip.sb"
    "icanhazip.com"
    "ifconfig.me"
    "api.ipify.org"
    "ipinfo.io/ip"
    "ident.me"
)

CURRENT_IP=""
for api in "${IP_APIS[@]}"; do
    ip=$(curl -s --connect-timeout 5 --max-time 10 -4 "$api" 2>&1)
    
    # IPv4 format validation
    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        CURRENT_IP="$ip"
        break
    fi
done

# 2. Read last recorded IP
if [ -f "$IP_LOG_FILE" ]; then
    LAST_IP=$(cat "$IP_LOG_FILE")
else
    LAST_IP=""
fi

# 3. Compare if IP has changed
if [ "$CURRENT_IP" != "$LAST_IP" ]; then
    # Update log file
    echo "$CURRENT_IP" > "$IP_LOG_FILE"

    # 4. Run ip.sh
    "$TARGET_SCRIPT" -4 -E 2>&1 | tee -a "$LOG_FILE"
    
    # 5. Wait for PNG generation
    TIMEOUT=120
    ELAPSED=0
    
    while [ $ELAPSED -lt $TIMEOUT ]; do
        AFTER_COUNT=$(ls -1 "$IMAGE_DIR"/*.png 2>/dev/null | wc -l)
        if [ "$AFTER_COUNT" -gt "$BEFORE_COUNT" ]; then
            break
        fi
        sleep 2
        ELAPSED=$((ELAPSED + 2))
    done

    # 6. Send to Telegram
    LATEST_PNG=$(ls -tp "$IMAGE_DIR"/*.png 2>/dev/null | head -1)
    
    RESPONSE=$(curl -s -X POST \
        "https://api.telegram.org/bot$TG_BOT_TOKEN/sendPhoto" \
        -F chat_id="$TG_CHAT_ID" \
        -F caption="🚨 IP Address Changed
New IP: \`$CURRENT_IP\`
Old IP: \`$LAST_IP\`" \
        -F parse_mode="Markdown" \
        -F photo="@$LATEST_PNG")
    
    # 7. Cleanup PNG
    if echo "$RESPONSE" | grep -q '"ok":true'; then
        rm -f "$IMAGE_DIR"/*.png
    fi
fi

2.2 Workflow

Start → Get IP → Compare Change → Execute Detection → 
Wait for PNG → Send to Telegram → Cleanup Files

2.3 Core Mechanisms

Multi-API Failover:

  • 6 backup APIs tried in order.
  • 5s connection timeout, 10s total timeout.
  • IPv4 format validation.

Intelligent Waiting:

  • Records PNG count before execution.
  • Checks for new files every 2 seconds.
  • Waits up to 120 seconds.

Automatic Cleanup:

  • Deleted only after successful sending.
  • Retained upon failure for troubleshooting.

⚙️ Advanced Configuration

Modify Detection Interval

# Every 1 minute
* * * * * /root/ip-monitor/monitor_ip.sh >/dev/null 2>&1

# Every 10 minutes
*/10 * * * * /root/ip-monitor/monitor_ip.sh >/dev/null 2>&1

Custom Telegram Message

Edit the caption part in monitor_ip.sh:

-F caption="🚨 **[Production Server] IP Changed**
Server: \`production-01\`
New IP: \`$CURRENT_IP\`
Old IP: \`$LAST_IP\`" \

📊 Log Management

# Real-time view
tail -f /var/log/ip_monitor.log

# View today's logs
grep "$(date '+%Y-%m-%d')" /var/log/ip_monitor.log

# Clear logs
> /var/log/ip_monitor.log

🔧 Troubleshooting

Unable to Retrieve IP

# Test API
curl -4 ip.sb
curl -4 icanhazip.com

PNG Generation Failed

# Install ansilove
sudo apt-get install ansilove
# OR
./ip.sh -y

Telegram Sending Failed

# Test Bot
curl "https://api.telegram.org/bot<YOUR_TOKEN>/getMe"

📁 File Structure

/root/ip-monitor/
├── ip.sh
├── monitor_ip.sh
└── README.md

/root/
└── .current_ip_log

/var/log/
└── ip_monitor.log

🎯 Usage Scenarios

  1. Dynamic IP Monitoring: Automatic notification of home broadband IP changes.
  2. VPS Quality Check: Detecting IP quality after purchasing a VPS.
  3. Multi-server Management: Unified notifications pushed to Telegram.

🔒 Security Recommendations

  1. Protect Bot Token: chmod 700 monitor_ip.sh
  2. Do not share logs publicly (containing real IPs)
  3. Rotate Tokens periodically
  4. Limit Bot permissions

Dynamic IP Monitor

Author

Shayne Wong

Publish Date

02 - 13 - 2026

Last Modified

02 - 13 - 2026

License

Shayne Wong

Avatar
Shayne Wong

All time is no time when it is past.

Friend Links
Blog Statistics

Total Posts

35

Category

5

Tag

20

Total Words

35,307

Reading Time

180 mins