Назад към каталога
Илюстрация на автоматизация: терминал, зъбчати колела и конвейер от задачи
Автоматизация ⭐ Препоръчан v1.0.0 • 27.09.2026 г. • 🐚 bash

Мониторинг на динамично външно IP с Telegram известяване в Proxmox среда

Практическо ръководство за откриване на скриптове в Proxmox LXC среда и създаване на Bash скрипт за мониторинг на външно IP с Telegram известия.

Зависимости

curliproute2awk

Употреба

bash /root/ip_monitor.sh
bashproxmoxtelegram-botnetworkingautomationlxc

При управлението на голям брой сървъри, виртуални машини и контейнери често се сблъскваме с два основни казуса:

  1. Оперативна автоматизация: Нуждата да знаем веднага, когато публичният IP адрес на даден обект се промени.
  2. Административна криминалистика: Ситуацията, в която дадена автоматизация работи (изпраща известия), но никой не помни на коя точно машина от всички 25+ сървъра е инсталиран скриптът.

В това ръководство ще разгледаме как бързо да открием “изгубен” скрипт в Proxmox VE среда с десетки LXC контейнери, както и как да напишем качествен Bash скрипт за мониторинг на IP адреса с известия в Telegram.


Част 1: Как да открием скрипта, ако не знаем на кой сървър се намира?

Когато получите известие в Telegram (например за сменено IP), първата стъпка е да анализирате съдържанието на съобщението:

  • Ако е на английски език и съдържа Fetch заявки: Твърде вероятно е да се изпълнява директно в мрежовия рутер (напр. MikroTik RouterOS през System -> Scripts или DHCP Client Lease Script).
  • Ако съдържа кирилица, форматиран HTML/Markdown и емоджита (🔄): Почти сигурно се изпълнява от Linux машина (Bash/Python) с помощта на cron или безкраен while цикъл.

Ако управлявате Proxmox VE с множество LXC контейнери, не е нужно да влизате през SSH във всеки един от тях поотделно. Proxmox предоставя инструмента pct exec, с който можем да изпълняваме команди във всички работещи контейнери наведнъж.

1. Търсене в работещите LXC контейнери

Отворете Shell-а на Proxmox хоста (или влезте през SSH в самия Proxmox) и изпълнете следния скрипт за обхождане:

for id in $(pct list | awk '$2=="running" {print $1}'); do
    res=$(pct exec $id -- grep -Hn "IP СМЕНЕНО" /root/ip_monitor.sh 2>/dev/null)
    if [ -n "$res" ]; then
        echo "=== НАМЕРЕН В КОНТЕЙНЕР ID: $id ==="
        echo "$res"
    fi
done

Как работи това?

  1. pct list извежда списък с всички контейнери.
  2. awk '$2=="running"' филтрира само тези, които са в състояние running (работещи).
  3. pct exec $id -- влиза във всеки контейнер и изпълнява grep за търсената фраза.
  4. При намерено съвпадение командата отпечатва точния ID на контейнера и реда от файла.

2. Влизане в контейнера

След като откриете ID-то (напр. 110), влизането в него става незабавно:

pct enter 110

Вече сте вътре в контейнера като root потребител и имате пряк достъп до файла (в нашия случай /root/ip_monitor.sh).


Част 2: Написване на оптимален IP Monitor скрипт

След като намерихме скрипта, е време да го подобрим. Оригиналният скрипт имаше нужда от две важни корекции:

  1. Проверка на активния WAN / Доставик: Изпълнението на ip route вътре в LXC контейнер показва виртуалната мрежа на контейнера (eth0), а не името на доставчика. Затова използваме външно API (ipinfo.io), за да извлечем името на интернет доставчика (ISP).
  2. Коректно Telegram форматиране: При изпращане на POST заявка с curl -d, символи като %0A не се разпознават като нов ред. Ползването на --data-urlencode решава този проблем чисто и безопасно.

Пълен изходен код (/root/ip_monitor.sh)

#!/bin/bash

# ==========================================
# === КОНФИГУРАЦИЯ                       ===
# ==========================================
BOT_TOKEN="ВАШИЯТ_TELEGRAM_BOT_TOKEN"
CHAT_ID="ВАШИЯТ_TELEGRAM_CHAT_ID"
CHECK_INTERVAL=300  # Интервал на проверка в секунди (300 сек = 5 мин)
IP_FILE="/tmp/current_ip.txt"
LOG_FILE="/var/log/ip_monitor.log"

# ==========================================
# === ФУНКЦИИ                            ===
# ==========================================

# Изпращане на съобщение към Telegram Bot API с HTML поддръжка
send_telegram() {
    local message="$1"
    curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
         --data-urlencode "chat_id=$CHAT_ID" \
         --data-urlencode "text=$message" \
         -d parse_mode="HTML" > /dev/null
}

# Определяне на активния доставчик (ISP / WAN)
get_active_wan() {
    local isp
    # Извличаме името на организацията/доставчика
    isp=$(curl -s https://ipinfo.io/org | cut -d' ' -f2-)
    
    # Резервен вариант, ако външната услуга не отговори
    if [[ -z "$isp" ]]; then
        isp=$(ip route | grep default | awk '{print $5}' | head -n 1)
    fi
    echo "$isp"
}

# ==========================================
# === ОСНОВЕН ЦИКЪЛ                      ===
# ==========================================

echo "$(date): IP мониторът е стартиран успешно." >> "$LOG_FILE"

while true; do
    # 1. Взимане на текущото външно IP адрес с резервни услуги
    CURRENT_IP=$(curl -s https://ifconfig.me || curl -s https://api.ipify.org || echo "unknown")

    # Ако има мрежов проблем и IP-то не може да се вземе — пропускаме цикъла
    if [[ "$CURRENT_IP" == "unknown" || -z "$CURRENT_IP" ]]; then
        echo "$(date): Грешка при вземане на публично IP. Нов опит след $CHECK_INTERVAL сек." >> "$LOG_FILE"
        sleep "$CHECK_INTERVAL"
        continue
    fi

    # 2. Определяне на активния доставчик
    ACTIVE_WAN=$(get_active_wan)
    [[ -z "$ACTIVE_WAN" ]] && ACTIVE_WAN="unknown"

    # 3. Първоначално стартиране (ако няма записан файл с IP)
    if [ ! -f "$IP_FILE" ]; then
        echo "$CURRENT_IP" > "$IP_FILE"
        
        MESSAGE="🟢 <b>IP Монитор стартиран</b>
Текущо IP: <code>$CURRENT_IP</code>
Активен WAN: <b>$ACTIVE_WAN</b>"
        
        send_telegram "$MESSAGE"
        echo "$(date): Първоначално записване на IP: $CURRENT_IP (WAN: $ACTIVE_WAN)" >> "$LOG_FILE"
        sleep "$CHECK_INTERVAL"
        continue
    fi

    # 4. Проверка за промяна спрямо предишното известно IP
    OLD_IP=$(cat "$IP_FILE")

    if [ "$CURRENT_IP" != "$OLD_IP" ]; then
        MESSAGE="🔄 <b>IP СМЕНЕНО!</b>
Старо: <code>$OLD_IP</code>
Ново:  <code>$CURRENT_IP</code>
Активен WAN: <b>$ACTIVE_WAN</b>
Време: $(date '+%Y-%m-%d %H:%M:%S')"

        send_telegram "$MESSAGE"

        # Обновяваме локалния файл и лога
        echo "$CURRENT_IP" > "$IP_FILE"
        echo "$(date): Детектирана промяна: $OLD_IP -> $CURRENT_IP (WAN: $ACTIVE_WAN)" >> "$LOG_FILE"
    fi

    # Изчакваме зададения интервал преди следващата проверка
    sleep "$CHECK_INTERVAL"
done

Част 3: Тестване и въвеждане в експлоатация

1. Как да тестваме бързо без да чакаме сменяне на IP?

За да уверите, че известията пристигат правилно оформени:

  1. Симулация на първо стартиране:

    rm -f /tmp/current_ip.txt
    bash /root/ip_monitor.sh

    Трябва да получите зелено известие 🟢 IP Монитор стартиран с Вашето IP и името на доставчика.

  2. Симулация на промяна в IP адреса:

    echo "1.1.1.1" > /tmp/current_ip.txt
    bash /root/ip_monitor.sh

    Трябва да получите известие 🔄 IP СМЕНЕНО!, показващо промяната от 1.1.1.1 към реалния Ви адрес.

2. Фоново изпълнение (Background Process)

За да работи скриптът постоянно във фонов режим, можете да го стартирате с nohup:

# Спираме стари копия на скрипта, ако има такива
pkill -f ip_monitor.sh

# Стартираме скрипта във фонов режим
nohup /root/ip_monitor.sh >/dev/null 2>&1 &

Алтернативно, скриптът може да се организира и като systemd услуга (ip_monitor.service) за автоматично стартиране при рестарт на контейнера.


Заключение

Чрез съчетаването на мощните инструменти за управление на Proxmox (pct exec) и гъвкавостта на Bash и Telegram API, постигнахме две основни цели: лесно откриване на критична автоматизация в сложна среда и надежден мониторинг на мрежовата свързаност.