commit 9a872d0617c28c46fe9c1787285b7c365e39a5b9 Author: Andrii Syrovatko Date: Wed Apr 8 13:32:04 2026 +0300 Initial release: Whois infrastructure automation diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2aa9401 --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Build and Release Folders +bin-debug/ +bin-release/ +[Oo]bj/ +[Bb]in/ + +# Other files and folders +.settings/ +logs/ +.logs/ +sps_logs/* +.sps_logs/* + +# Executables +*.conf +*.swf +*.air +*.ipa +*.apk +*.log +*.tmp +*.log* +*.html* +*tmp_* +*variables* + +# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` +# should NOT be excluded as they contain compiler settings and other important +# information for Eclipse / Flash Builder. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..674992d --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Whois Infrastructure Automator (for ISPs) + +### 🚀 The Problem +In large ISP infrastructures, keeping the `whois` description of IP addresses synchronized with the actual network topology is a manual nightmare. When a switch is renamed or replaced, hundreds of IP records can become outdated. + +### 🛠 The Solution +This script automates the synchronization between a **PostgreSQL billing database** and a **local Whois server**. + +### Key Features: +* ● **Auto-Discovery:** Fetches all IP addresses associated with a renamed switch from the DB. +* ● **Context-Aware Update:** Intelligently parses current Whois data and replaces only the relevant switch names. +* ● **Email Integration:** Automatically generates and sends update requests to the RIPE-like Whois mail robots. +* ● **Logging:** Full traceability of all actions and errors. + +### 📖 Usage +1. Configure your credentials in `whois.conf`. +2. Run the script with the new switch name as an argument: + ```bash + ./whois_upd.sh "NEW_SWITCH_HOSTNAME" + ``` + +### Use at your own risk! The author is not responsible for any data loss! diff --git a/whois_updater.conf.example b/whois_updater.conf.example new file mode 100644 index 0000000..a58269a --- /dev/null +++ b/whois_updater.conf.example @@ -0,0 +1,12 @@ +# Database Settings +PSQL_USER="psql_user" +PSQL_DB="psql_db" + +# Whois Settings +WHOIS_SERVER="whois.domain.com" +WHOIS_PASS="YOUR_SECRET_PASSWORD" +CHANGED_EMAIL="whois_user@domain.com" +MAIL_RECIPIENT="auto-dbm@whois.domain.com" + +# Paths +LOG_DIR="/var/log/scripts/whois_updater" \ No newline at end of file diff --git a/whois_updater.sh b/whois_updater.sh new file mode 100644 index 0000000..dd1449d --- /dev/null +++ b/whois_updater.sh @@ -0,0 +1,122 @@ +#!/usr/bin/env bash +# ============================================================================= +# Script Name : whois_updater.sh +# Description : Sync Whois "descr" field with Billing DB switch names. +# Usage : ./whois_updater.sh +# Author : syr4ok (Andrii) +# Version : 1.0.1r +# ============================================================================= + +# --- Configuration Loader --- +CONFIG_FILE="$(dirname "$0")/whois_updater.conf" +if [ -f "$CONFIG_FILE" ]; then + source "$CONFIG_FILE" +else + echo "Error: Configuration file not found. Create whois_updater.conf from example." + exit 1 +fi + +# --- Environment & Tools --- +DATE_NOW=$(date +%Y%m%d) +PSQL_PATH=$(which psql) +MAIL_PATH=$(which mail) +WHOIS_PATH=$(which whois) + +# Ensure target switch name is provided +RENAMED_SWITCH_NAME=$1 +if [ -z "$RENAMED_SWITCH_NAME" ]; then + echo "Usage: $0 " + exit 1 +fi + +# Logging setup +LOG_FILE="${LOG_DIR}/whois_updater.${DATE_NOW}.log" +LOG_SEP="=========================================================" +mkdir -p "$LOG_DIR" + +log_message() { + local level="$1" + local msg="$2" + echo "$(date '+%Y-%m-%d %H:%M:%S') [${level}] ${msg}" >> "${LOG_FILE}" +} + +# --- Dependencies Check --- +for tool in "$PSQL_PATH" "$MAIL_PATH" "$WHOIS_PATH"; do + if [ -z "$tool" ]; then + log_message "ERROR" "Missing dependency. Check if psql, mail, and whois are installed." + exit 1 + fi +done + +log_message "INFO" "Script STARTED for switch: ${RENAMED_SWITCH_NAME}" + +# --- Data Acquisition --- +log_message "INFO" "Querying IP list from PostgreSQL..." +IP_LIST=$($PSQL_PATH -t -U "$PSQL_USER" -d "$PSQL_DB" -c \ +"SELECT ip FROM equipment_ports WHERE equipment_id = (SELECT id FROM equipment WHERE name='${RENAMED_SWITCH_NAME}') AND ip <> ''" 2>>"${LOG_FILE}") + +if [ -z "$IP_LIST" ]; then + log_message "WARN" "No IP addresses found for switch ${RENAMED_SWITCH_NAME}. Exiting." + exit 0 +fi + +# --- Processing Cycle --- +for ip in $IP_LIST; do + ip=$(echo "$ip" | tr -d '[:space:]') + log_message "INFO" "Processing IP: ${ip}" + + # Fetch current Whois record + CURRENT_DATA=$($WHOIS_PATH -r -h "$WHOIS_SERVER" "$ip" 2>>"${LOG_FILE}") + if [ -z "$CURRENT_DATA" ]; then + log_message "ERROR" "Empty Whois response for ${ip}. Skipping." + continue + fi + + # Parse 'descr' field + OLD_DESCR_LINE=$(printf "%s\n" "$CURRENT_DATA" | awk 'BEGIN{IGNORECASE=1} /^descr:/ {print; exit}') + if [ -z "$OLD_DESCR_LINE" ]; then + log_message "WARN" "No 'descr' field found for ${ip}. Skipping." + continue + fi + + # Extract switch name from current description + DESCR_VALUE=$(printf "%s" "${OLD_DESCR_LINE#*:}" | sed 's/^[[:space:]]*//') + OLD_SWITCH_NAME=$(printf "%s\n" "$DESCR_VALUE" | grep -oE '(des[0-9][A-Za-z0-9-]*|dgs[A-Za-z0-9-]*|dlink[A-Za-z0-9-]*|cat[A-Za-z0-9-]*|zte[A-Za-z0-9-]*|dir[A-Za-z0-9-]*|ubi[A-Za-z0-9-]*)' | tail -1) + + if [ -z "$OLD_SWITCH_NAME" ]; then + log_message "WARN" "Could not identify old switch pattern in: $DESCR_VALUE. Skipping." + continue + fi + + # Generate new description using Perl for safe regex handling + NEW_DESCR=$(o="$OLD_SWITCH_NAME" n="$RENAMED_SWITCH_NAME" perl -pe 'BEGIN{$o=$ENV{o};$n=$ENV{n}} s/\Q$o\E/$n/g' <<<"$DESCR_VALUE") + log_message "INFO" "Updating: [${OLD_SWITCH_NAME}] -> [${RENAMED_SWITCH_NAME}]" + + # --- Email Construction --- + # Using 'grep -m 1' for efficiency + MAIL_BODY=$(cat <> "$LOG_FILE" +exit 0