Мониторинг на динамично външно IP с Telegram известяване в Proxmox среда
Практическо ръководство за откриване на скриптове в Proxmox LXC среда и създаване на Bash скрипт за мониторинг на външно IP с Telegram известия.
Зависимости
curliproute2awk Употреба
bash /root/ip_monitor.sh При управлението на голям брой сървъри, виртуални машини и контейнери често се сблъскваме с два основни казуса:
- Оперативна автоматизация: Нуждата да знаем веднага, когато публичният IP адрес на даден обект се промени.
- Административна криминалистика: Ситуацията, в която дадена автоматизация работи (изпраща известия), но никой не помни на коя точно машина от всички 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
Как работи това?
pct listизвежда списък с всички контейнери.awk '$2=="running"'филтрира само тези, които са в състояние running (работещи).pct exec $id --влиза във всеки контейнер и изпълняваgrepза търсената фраза.- При намерено съвпадение командата отпечатва точния ID на контейнера и реда от файла.
2. Влизане в контейнера
След като откриете ID-то (напр. 110), влизането в него става незабавно:
pct enter 110
Вече сте вътре в контейнера като root потребител и имате пряк достъп до файла (в нашия случай /root/ip_monitor.sh).
Част 2: Написване на оптимален IP Monitor скрипт
След като намерихме скрипта, е време да го подобрим. Оригиналният скрипт имаше нужда от две важни корекции:
- Проверка на активния WAN / Доставик: Изпълнението на
ip routeвътре в LXC контейнер показва виртуалната мрежа на контейнера (eth0), а не името на доставчика. Затова използваме външно API (ipinfo.io), за да извлечем името на интернет доставчика (ISP). - Коректно 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?
За да уверите, че известията пристигат правилно оформени:
-
Симулация на първо стартиране:
rm -f /tmp/current_ip.txt bash /root/ip_monitor.shТрябва да получите зелено известие
🟢 IP Монитор стартиранс Вашето IP и името на доставчика. -
Симулация на промяна в 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, постигнахме две основни цели: лесно откриване на критична автоматизация в сложна среда и надежден мониторинг на мрежовата свързаност.