OPNsense Forum

English Forums => Tutorials and FAQs => Topic started by: shanelord on August 04, 2023, 07:05:30 am

Title: [SCRIPT] Webhook notify of internet connectivity loss on specific interface
Post by: shanelord on August 04, 2023, 07:05:30 am
This may (or may not) be of use for others.

I made this for my own requirements (ie monitor backup 5G modem which has a habit of locking up, then telling Home Assistant via webhook automation to turn the smart plug off then back on).

Can be run standalone or in background. Pastebin link here (https://pastebin.com/bpeTHvmX).

I made this to ideally run in the background as a cronjob - and the script will check to ensure no other variants of the script are running and will exit gracefully if it detects the lock file.

For standlone, you can run it with options to specify the desired ping IP address and DNS check address. For example:

Code: [Select]
./internet_monitor.sh -p 1.1.1.1 -d example.com
This will monitor internet connectivity using 1.1.1.1 as the ping IP address and DNS resolution using example.com as the DNS check address. If you don't provide any options, the script will use the default addresses (8.8.8.8 and github.com).

NOTE: Updated to support multiple Webhook URL targets.

Code: [Select]
#!/bin/bash

# Default values for options
PING_IP="8.8.8.8"      # Default ping IP address (Google DNS)
DNS_CHECK_ADDRESS="github.com"  # Default DNS check address
INTERFACE="eth0"      # Replace with your Ethernet interface name (e.g., eth0)
WEBHOOK_URLS="YOUR_WEBHOOK_URL"  # Default webhook URL(s) (comma-separated)
ENABLE_RESTORE_NOTIFICATION=true   # Set this to false if you want to disable the notification when connectivity is restored
LOCK_FILE="/tmp/internet_monitor.lock" # Define the lock file path

# Function to acquire the lock
acquire_lock() {
    if [[ -e "$LOCK_FILE" ]]; then
        echo "Lock file exists. Script is already running or a previous run didn't finish."
        exit 1
    fi
    touch "$LOCK_FILE"
}

# Function to release the lock
release_lock() {
    rm -f "$LOCK_FILE"
}

# Function to send a webhook notification
send_webhook_notification() {
    local message="$1"
    local urls=($(echo "$WEBHOOK_URLS" | tr ',' ' '))  # Convert comma-separated URLs to an array
    for url in "${urls[@]}"; do
        curl -X POST -H "Content-Type: application/json" -d "{\"text\":\"$message\"}" "$url"
    done
}

# Function to check internet connectivity
check_internet_connectivity() {
    local ip_address="$1"
    if ping -I "$INTERFACE" -c 1 "$ip_address" &> /dev/null; then
        return 0  # Internet connectivity is available
    else
        return 1  # Internet connectivity is not available
    fi
}

# Function to check DNS resolution
check_dns_resolution() {
    local dns_address="$1"
    if ping -I "$INTERFACE" -c 1 "$dns_address" &> /dev/null; then
        return 0  # DNS resolution is successful
    else
        return 1  # DNS resolution failed
    fi
}

# Main function to monitor internet connectivity and DNS resolution
main() {
    if ! check_internet_connectivity "$PING_IP"; then
        # Internet connectivity is not available, send webhook notification with a specific payload
        message="Internet connectivity is down on $INTERFACE at $(date)"
        send_webhook_notification "$message" "connectivity_down"
    elif ! check_dns_resolution "$DNS_CHECK_ADDRESS"; then
        # DNS resolution failed, send webhook notification
        message="DNS resolution failed on $INTERFACE at $(date)"
        send_webhook_notification "$message" "dns_failure"
    else
        # Internet connectivity and DNS resolution are both successful
        if $ENABLE_RESTORE_NOTIFICATION; then
            # Internet connectivity is restored, send webhook notification with a specific payload
            message="Internet connectivity restored on $INTERFACE at $(date)"
            send_webhook_notification "$message" "connectivity_restored"
        fi
    fi
}


# Function to display usage information
usage() {
    echo "Usage: $0 [-p ping_ip_address] [-d dns_check_address] [-w webhook_urls]"
    echo "Options:"
    echo "  -p ping_ip_address       Specify the IP address for internet connectivity check (default: 8.8.8.8)"
    echo "  -d dns_check_address     Specify the DNS address for DNS resolution check (default: github.com)"
    echo "  -w webhook_urls          Specify one or multiple webhook URLs as a comma-separated list"
    exit 1
}

# Parse command-line options using getopts
while getopts ":p:d:w:" opt; do
    case "$opt" in
        p) PING_IP=$OPTARG ;;
        d) DNS_CHECK_ADDRESS=$OPTARG ;;
        w) WEBHOOK_URLS=$OPTARG ;;
        \?) echo "Invalid option: -$OPTARG" >&2 ; usage ;;
        :) echo "Option -$OPTARG requires an argument." >&2 ; usage ;;
    esac
done

# Acquire the lock before starting the main loop
acquire_lock

# Run the main loop
while true; do
    main
    sleep 1m  # Adjust the time interval as needed for internet connectivity and DNS resolution checks
done

# Release the lock when the script exits
release_lock



Title: Re: [SCRIPT] Webhook notify of internet connectivity loss on specific interface
Post by: shanelord on August 04, 2023, 12:26:36 pm
Made a V2 I'm testing that support Discord and Home Assistant targets with multiple URLS for each.

Also the options to choose which notifications to send to Discord, and which to send to Home Assistant, as well as the ability to remember last state of the connection.

Fun working on this... hope someone else can use it.

Pastebin Link (https://pastebin.com/wq8gzdjB)