36 KiB
11. Резервное копирование
Обзор
Резервное копирование критически важно для защиты данных и возможности восстановления после сбоев, ошибок или атак.
Текущий статус (апрель 2026): ✅ Настроена полнофункциональная система резервного копирования на базе Proxmox Backup Server
- Отдельный физический сервер PBS (192.168.1.199)
- Хранилище 1 TB с дедупликацией и компрессией
- Автоматические бэкапы всех критичных систем
- Протестированное восстановление
- ✅ Настроены уведомления в Telegram о статусе задач
Текущее состояние
✅ Настроено и работает
| Компонент | Статус | Описание |
|---|---|---|
| Proxmox Backup Server | ✅ | Отдельный сервер (Olimpbs, 192.168.1.199) |
| Хранилище | ✅ | 1 TB (LVM), datastore olimpbkp |
| Бэкапы ВМ/LXC | ✅ | Автоматические, по расписанию |
| Дедупликация | ✅ | Встроена в PBS |
| Компрессия | ✅ | ZSTD (fast and good) |
| Расписание | ✅ | 2 раза в день (02:30 и 22:30) |
| Retention | ✅ | 14 последних, 7 ежедневных, 4 недельных, 4 месячных |
| Режим | ✅ | Snapshot (без остановки сервисов) |
| Уведомления | ✅ | Telegram-бот через прокси (XRay + Redsocks) |
📊 Архитектура
graph TD
A["Proxmox VE Host<br/>Olimp 192.168.1.200"] --> B["LXC Containers<br/>201-211"]
A --> C["Virtual Machines<br/>205, 213"]
A -->|Network| D["Proxmox Backup Server<br/>Olimpbs 192.168.1.199"]
D --> E["Datastore: olimpbkp<br/>1 TB LVM"]
E --> F["/var/lib/proxmox-backup/olimpbkp"]
D -->|HTTPS via proxy| G["Telegram API<br/>api.telegram.org"]
Что бэкапится
LXC Контейнеры (10 шт.)
| ID | Имя | Тип данных | Примерный размер |
|---|---|---|---|
| 201 | gateway | Конфигурации, прокси | ~5 GB |
| 202 | data | Базы данных (BookStack, Mealie) | ~10 GB |
| 203 | media | Конфигурации Jellyfin, метаданные | ~60 GB* |
| 204 | photo | Immich конфиги | ~20 GB |
| 206 | talk | Matrix, XMPP конфиги | ~10 GB |
| 207 | games | Конфигурации игровых серверов | ~20 GB |
| 208 | manage | Grafana, Loki, мониторинг | ~15 GB |
| 209 | git | GitLab репозитории | ~30 GB |
| 210 | ansible | Ansible конфиги, vault | ~5 GB |
| 211 | torrent | qBittorrent настройки | ~5 GB |
*Без медиафайлов (исключены из бэкапа)
Виртуальные машины (2 шт.)
| ID | Имя | Тип данных | Примерный размер |
|---|---|---|---|
| 205 | Nextcloud | Файлы, БД PostgreSQL | ~10 GB |
| 213 | VPN | OpenVPN/WireGuard конфиги | ~12 GB |
Исключено из бэкапа
- Большие диски (16 TB RAID6): медиафайлы, игры, загрузки
- Причина: занимают слишком много места, можно восстановить из источников
- Что включено: только конфигурации и метаданные (через
backup=1)
Расписание бэкапов
Автоматическое расписание
Два раза в день:
- 02:30 — ночной бэкап
- 22:30 — вечерний бэкап
Proxmox Backup Server автоматически определяет:
- Первый бэкап — полный
- Последующие — инкрементальные (только изменения)
- Периодически — полный для целостности данных
Retention политика
| Тип хранения | Количество | Фактический срок |
|---|---|---|
| Keep Last | 14 | Минимум 14 последних бэкапов |
| Keep Daily | 7 | 7 ежедневных копий |
| Keep Weekly | 4 | 4 недельных копии |
| Keep Monthly | 4 | 4 месячных копии |
Итого: ~1-2 месяца истории бэкапов
Текущая конфигурация
На Proxmox VE (Olimp)
Хранилище подключено:
- ID:
olimpbkp - Тип: Proxmox Backup Server
- Server: 192.168.1.199:8007
- Datastore:
olimpbkp - Content: Backup
- Status: ✅ Enabled
Backup Job:
Node: Olimp
Storage: olimpbkp
Schedule: 02:30, 22:30 (daily)
Mode: Snapshot
Compression: ZSTD
VM/CT: 201-211, 205, 213
Retention: keep-last=14, keep-daily=7, keep-weekly=4, keep-monthly=4
На PBS (Olimpbs)
Datastore:
Name: olimpbkp
Path: /var/lib/proxmox-backup/olimpbkp
Size: 1 TB (912 GB available)
GC Schedule: daily
Prune Schedule: daily
Пользователи:
root@pam— администратор (веб-интерфейс)pve@pbs— для Proxmox VE (API токен)
Управление бэкапами
Просмотр бэкапов
Через веб-интерфейс PBS:
https://192.168.1.199:8007
→ Datastore → olimpbkp → Content
Через Proxmox VE:
https://192.168.1.220:8006
→ Datacenter → Storage → olimpbkp → Content
Через CLI:
# Список бэкапов
proxmox-backup-client list --repository root@pam@192.168.1.199:8007:olimpbkp
# Детальная информация
proxmox-backup-client show-backup --repository root@pam@192.168.1.199:8007:olimpbkp ct/201
# Статистика datastore
proxmox-backup-client datastore stats olimpbkp
Ручной запуск бэкапа
Один контейнер/ВМ:
vzdump 201 --storage olimpbkp --mode snapshot --compress zstd
Все бэкапируемые системы:
for id in 201 202 203 204 205 206 207 208 209 210 211 213; do
vzdump $id --storage olimpbkp --mode snapshot --compress zstd &
done
wait
Восстановление из бэкапа
Через веб-интерфейс Proxmox VE:
- Datacenter → Storage → olimpbkp → Content
- Выбрать бэкап → Restore
- Указать:
- Storage: целевое хранилище (local-lvm, vmsystem)
- VMID: новый ID (или существующий для перезаписи)
- Start
Через CLI:
# LXC контейнер
pct restore 216 olimpbkp:backup/ct/201/2026-04-11T13:19:03Z --storage local-lvm
# Виртуальная машина
qm restore 216 olimpbkp:backup/vm/205/2026-04-11T13:19:03Z --storage vmsystem
Восстановление отдельных файлов
Через File Restore:
- PBS веб-интерфейс → Datastore → Content
- Выбрать бэкап → File Restore
- Смонтировать бэкап
- Скачать нужные файлы
- Unmount
Через CLI:
# Смонтировать бэкап
mkdir -p /mnt/restore
proxmox-backup-client mount ct/201/2026-04-11T13:19:03Z /mnt/restore \
--repository root@pam@192.168.1.199:8007:olimpbkp
# Скопировать файлы
cp /mnt/restore/root.pxar/etc/config/file.conf /tmp/
# Размонтировать
proxmox-backup-client unmount /mnt/restore
Мониторинг и обслуживание
Проверка статуса бэкапов
Ежедневная проверка:
# Последние задачи
pvesm status olimpbkp
# Логи бэкапов
tail -f /var/log/pve/tasks/*
# Проверка места на PBS
ssh root@192.168.1.199 "df -h /var/lib/proxmox-backup/olimpbkp"
Garbage Collection (очистка)
PBS автоматически запускает GC ежедневно. Вручную:
# На PBS сервере
proxmox-backup-manager garbage-collection start olimpbkp
# Проверка статуса
proxmox-backup-manager garbage-collection status olimpbkp
Prune (удаление старых бэкапов)
Автоматически по retention политике. Вручную:
proxmox-backup-manager prune-job run <job-id>
Проверка целостности (Verify)
# Проверить все бэкапы
proxmox-backup-manager verify olimpbkp
# Проверить конкретный бэкап
proxmox-backup-client verify ct/201/2026-04-11T13:19:03Z \
--repository root@pam@192.168.1.199:8007:olimpbkp
📦 Уведомления в Telegram
🎯 Цель
Получать уведомления в Telegram об успешных/неудачных бэкапах с Proxmox Backup Server, без изменений на гипервизоре. В системе настроено два независимых канала уведомлений в Telegram:
| Тип | Источник | Сервер | Порт реле | Что уведомляет |
|---|---|---|---|---|
| PBS Backup Notifications | Proxmox Backup Server | 192.168.1.199 | 8085 | ✅ Успешные/❌ неудачные бэкапы |
| Grafana Alerts | VictoriaMetrics + Grafana | 192.168.1.208 | 8085 | ⚠️ Бэкапы старше 24 часов |
📋 Предварительные требования
- PBS сервер (192.168.1.199) с доступом в интернет через прокси
- Telegram бот: токен и chat_id
- Прокси: VLESS+Reality на
2.27.50.20:2054
🔧 Настройка прокси (XRay + Redsocks + iptables)
1. Установка XRay клиента
# Установка зависимостей
apt update && apt install unzip curl iptables -y
# Скачиваем XRay
cd /tmp
curl -L -o xray.zip https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-64.zip
unzip xray.zip
chmod +x xray
mv xray geoip.dat geosite.dat /usr/local/bin/
# Проверка
xray version
2. Конфигурация XRay
mkdir -p /usr/local/etc/xray
cat > /usr/local/etc/xray/config.json << 'EOF'
{
"log": {"loglevel": "warning"},
"inbounds": [{"port": 1080, "listen": "127.0.0.1", "protocol": "socks", "settings": {"auth": "noauth", "udp": true}}],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [{
"address": "2.27.50.20",
"port": 2054,
"users": [{"id": "68f44a38-396d-48da-b832-79b5dc5716ab", "encryption": "none", "level": 8}]
}]
},
"streamSettings": {
"network": "xhttp",
"security": "reality",
"realitySettings": {
"serverName": "cloud.zailon.ru",
"publicKey": "TOyddQCTdSpycmO20uiLOqMABuKabpwVhw57tWmvJws",
"shortId": "174fc0",
"spiderX": "/"
},
"xhttpSettings": {
"host": "",
"path": "/remote.php/dav/upload",
"mode": "stream-one"
}
},
"tag": "proxy"
},
{"protocol": "freedom", "tag": "direct"}
],
"routing": {
"rules": [
{"type": "field", "ip": ["geoip:private"], "outboundTag": "direct"},
{"type": "field", "domain": ["api.telegram.org"], "outboundTag": "proxy"}
]
}
}
EOF
3. Запуск XRay как сервис
cat > /etc/systemd/system/xray-client.service << 'EOF'
[Unit]
Description=XRay Client
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/config.json
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now xray-client
systemctl status xray-client
4. Установка и настройка Redsocks
# Установка
apt install redsocks -y
# Конфигурация
cat > /etc/redsocks.conf << 'EOF'
base {
log_debug = off;
log_info = off;
log = stderr;
daemon = on;
redirector = iptables;
}
redsocks {
bind = "0.0.0.0:12345";
relay = "127.0.0.1:1080";
type = socks5;
autoproxy = 0;
timeout = 10;
}
EOF
# Запуск
systemctl enable --now redsocks
5. Настройка iptables для Telegram
cat > /usr/local/bin/telegram-proxy.sh << 'EOF'
#!/bin/bash
iptables -t nat -F TELEGRAM_PROXY 2>/dev/null
iptables -t nat -X TELEGRAM_PROXY 2>/dev/null
iptables -t nat -N TELEGRAM_PROXY
# Telegram IP ranges
iptables -t nat -A TELEGRAM_PROXY -p tcp -d 149.154.160.0/20 -j REDIRECT --to-ports 12345
iptables -t nat -A TELEGRAM_PROXY -p tcp -d 91.108.4.0/22 -j REDIRECT --to-ports 12345
iptables -t nat -A OUTPUT -p tcp --dport 443 -j TELEGRAM_PROXY
EOF
chmod +x /usr/local/bin/telegram-proxy.sh
/usr/local/bin/telegram-proxy.sh
6. Проверка соединения
curl -s "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getMe"
Ожидаемый результат: JSON с информацией о боте.
🔧 Скрипт уведомлений
7. Создание скрипта
cat > /usr/local/bin/pbs-backup-notify.sh << 'EOF'
#!/bin/bash
TOKEN="YOUR_BOT_TOKEN"
CHAT="YOUR_CHAT_ID"
ARCHIVE="/var/log/proxmox-backup/tasks/archive"
STATE="/var/run/pbs-notify-lastline"
# Получаем последнюю обработанную строку
LAST_LINE=$(cat $STATE 2>/dev/null || echo 0)
CURR_LINE=$(wc -l < $ARCHIVE)
# Если файл уменьшился - начинаем сначала
if [ "$CURR_LINE" -lt "$LAST_LINE" ]; then
LAST_LINE=0
fi
# Читаем новые строки
if [ "$CURR_LINE" -gt "$LAST_LINE" ]; then
tail -n +$((LAST_LINE + 1)) $ARCHIVE | while IFS= read -r line; do
# Только backup задачи
if echo "$line" | grep -q ":backup:"; then
# Извлекаем имя бэкапа (конвертируем \x3a в :)
BACKUP=$(echo "$line" | grep -oP 'backup:\K[^:]+' | sed 's/\\x3a/:/g')
STATUS=$(echo "$line" | grep -oP 'OK|FAILED|ERROR')
TIME=$(date '+%Y-%m-%d %H:%M:%S')
if [ "$STATUS" = "OK" ]; then
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
-H "Content-Type: application/json" \
-d "{\"chat_id\":\"$CHAT\",\"text\":\"✅ *Backup Success*\\n📦 $BACKUP\\n⏰ $TIME\",\"parse_mode\":\"Markdown\"}" > /dev/null
else
curl -s -X POST "https://api.telegram.org/bot$TOKEN/sendMessage" \
-H "Content-Type: application/json" \
-d "{\"chat_id\":\"$CHAT\",\"text\":\"❌ *Backup Failed*\\n📦 $BACKUP\\n⏰ $TIME\\n📝 Status: $STATUS\",\"parse_mode\":\"Markdown\"}" > /dev/null
fi
fi
done
fi
# Сохраняем позицию
echo $CURR_LINE > $STATE
EOF
chmod +x /usr/local/bin/pbs-backup-notify.sh
8. Настройка Cron (каждые 5 минут)
echo "*/5 * * * * root /usr/local/bin/pbs-backup-notify.sh" >> /etc/cron.d/pbs-notify
9. Инициализация и тест
# Сброс состояния для теста
echo "0" > /var/run/pbs-notify-lastline
# Запуск вручную
/usr/local/bin/pbs-backup-notify.sh
# Проверка состояния
cat /var/run/pbs-notify-lastline
wc -l < /var/log/proxmox-backup/tasks/archive
📝 Переменные для замены
| Переменная | Описание | Пример |
|---|---|---|
YOUR_BOT_TOKEN |
Токен Telegram бота | 7657027552:AAHQ6OGDRbm6wtqh_4GOQr7jd6C0BAQMyF4 |
YOUR_CHAT_ID |
ID чата для уведомлений | 292909723 |
address |
Адрес прокси-сервера | 2.27.50.20 |
port |
Порт прокси | 2054 |
id |
UUID пользователя VLESS | 68f44a38-396d-48da-b832-79b5dc5716ab |
publicKey |
Публичный ключ Reality | TOyddQCTdSpycmO20uiLOqMABuKabpwVhw57tWmvJws |
serverName |
Домен для Reality | cloud.zailon.ru |
📁 Файлы конфигурации
| Файл | Назначение |
|---|---|
/usr/local/etc/xray/config.json |
Конфиг XRay прокси |
/etc/redsocks.conf |
Конфиг Redsocks |
/usr/local/bin/telegram-proxy.sh |
Правила iptables для Telegram |
/usr/local/bin/pbs-backup-notify.sh |
Скрипт уведомлений |
/var/run/pbs-notify-lastline |
Позиция последнего прочитанного лога |
/etc/cron.d/pbs-notify |
Cron задача |
📦 Настройка уведомлений из Grafana в Telegram
🎯 Цель
Настроить отправку алертов из Grafana в Telegram с красивым форматированием, эмодзи и автоматическим преобразованием времени.
📋 Архитектура
graph LR
A["Grafana<br/>192.168.1.208"] -->|HTTP POST| B["Python Relay<br/>localhost:8085"]
B -->|SOCKS5| C["XRay Client<br/>127.0.0.1:1080"]
C -->|HTTPS| D["Telegram API<br/>api.telegram.org"]
🔧 Шаг 0: Установка XRay (если не установлен)
XRay нужен для проксирования запросов в Telegram.
1. Установи зависимости:
apt update && apt install unzip curl iptables -y
2. Скачай и установи XRay:
cd /tmp
curl -L -o xray.zip https://github.com/XTLS/Xray-core/releases/latest/download/Xray-linux-64.zip
unzip xray.zip
chmod +x xray
mv xray geoip.dat geosite.dat /usr/local/bin/
# Проверка
xray version
3. Создай конфигурацию:
mkdir -p /usr/local/etc/xray
cat > /usr/local/etc/xray/config.json << 'EOF'
{
"log": {"loglevel": "warning"},
"inbounds": [
{
"port": 1080,
"listen": "127.0.0.1",
"protocol": "socks",
"settings": {"auth": "noauth", "udp": true}
}
],
"outbounds": [
{
"protocol": "vless",
"settings": {
"vnext": [{
"address": "2.27.50.20",
"port": 2054,
"users": [{"id": "68f44a38-396d-48da-b832-79b5dc5716ab", "encryption": "none", "level": 8}]
}]
},
"streamSettings": {
"network": "xhttp",
"security": "reality",
"realitySettings": {
"serverName": "cloud.zailon.ru",
"publicKey": "TOyddQCTdSpycmO20uiLOqMABuKabpwVhw57tWmvJws",
"shortId": "174fc0",
"spiderX": "/"
},
"xhttpSettings": {
"host": "",
"path": "/remote.php/dav/upload",
"mode": "stream-one"
}
},
"tag": "proxy"
},
{"protocol": "freedom", "tag": "direct"}
],
"routing": {
"rules": [
{"type": "field", "ip": ["geoip:private"], "outboundTag": "direct"},
{"type": "field", "domain": ["api.telegram.org"], "outboundTag": "proxy"}
]
}
}
EOF
4. Создай systemd-сервис:
cat > /etc/systemd/system/xray-client.service << 'EOF'
[Unit]
Description=XRay Client
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/xray run -config /usr/local/etc/xray/config.json
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now xray-client
5. Проверь работу:
systemctl status xray-client
# Тест соединения
curl -sx socks5://127.0.0.1:1080 \
https://api.telegram.org/bot7657027552:AAHQ6OGDRbm6wtqh_4GOQr7jd6C0BAQMyF4/getMe
Должен вернуться JSON с информацией о боте.
🔧 Шаг 2: Установка Python-реле
1. Создай скрипт реле:
cat > /usr/local/bin/telegram-relay.py << 'EOF'
#!/usr/bin/env python3
import socket
import subprocess
import sys
import re
PORT = 8085
BOT_TOKEN = "7657027552:AAHQ6OGDRbm6wtqh_4GOQr7jd6C0BAQMyF4"
CHAT_ID = "292909723"
PROXY = "socks5://127.0.0.1:1080"
def format_duration(seconds):
try:
sec = float(seconds)
if sec < 60:
return f"{int(sec)} сек"
elif sec < 3600:
return f"{int(sec // 60)} мин"
elif sec < 86400:
hours = int(sec // 3600)
mins = int((sec % 3600) // 60)
return f"{hours} ч {mins} мин" if mins > 0 else f"{hours} ч"
else:
return f"{int(sec // 86400)} дн"
except:
return str(seconds)
def get_icon(backup):
return "💻" if backup.startswith('vm-') else "📦" if backup.startswith('ct-') else "🗄️"
def send_telegram(text):
try:
cmd = [
'curl', '-sx', PROXY, '-s',
f'https://api.telegram.org/bot{BOT_TOKEN}/sendMessage',
'-H', 'Content-Type: application/json',
'-d', f'{{"chat_id":"{CHAT_ID}","text":"{text}","parse_mode":"Markdown"}}'
]
subprocess.run(cmd, timeout=10, capture_output=True)
return True
except:
return False
def handle_client(client_socket, addr):
try:
data = b""
client_socket.settimeout(2)
while True:
try:
chunk = client_socket.recv(4096)
if not chunk:
break
data += chunk
except socket.timeout:
break
data = data.decode('utf-8', errors='ignore')
body = data.split('\r\n\r\n', 1)[1] if '\r\n\r\n' in data else data
# Парсим JSON от Grafana
backups = re.findall(r'"backup"\s*:\s*"([^"]+)"', body)
statuses = re.findall(r'"status"\s*:\s*"([^"]+)"', body)
values = re.findall(r'value=([\d.]+)', body)
# Если нашли бэкапы — форматируем как алерт
if backups:
CHUNK = 5
for i in range(0, len(backups), CHUNK):
chunk_backups = backups[i:i+CHUNK]
text = "🚨 *Backup Alert*\n\n"
for j, backup in enumerate(chunk_backups):
idx = i + j
status = statuses[idx] if idx < len(statuses) else "unknown"
icon = get_icon(backup)
if len(values) >= (idx * 2 + 1):
seconds = float(values[idx * 2])
human_time = format_duration(seconds)
desc = f"Последний бэкап: {human_time} назад"
else:
desc = "Нет данных"
status_emoji = "🔥" if status == "firing" else "✅"
text += f"{icon} *{backup}*\n⏱ {desc}\nStatus: {status_emoji} *{status}*\n\n"
send_telegram(text)
else:
# Если не JSON от Grafana — отправляем как есть (для тестов)
# Очищаем от служебных символов
clean_text = body.strip().replace('\r', '').replace('\n', ' ')
if clean_text and len(clean_text) < 4000:
send_telegram(clean_text)
client_socket.send(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\nConnection: close\r\n\r\nOK")
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
try:
client_socket.send(b"HTTP/1.1 500 Error\r\n\r\n")
except:
pass
finally:
try:
client_socket.close()
except:
pass
# Запуск сервера
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('0.0.0.0', PORT))
server.listen(10)
print(f"▶ Telegram Relay on {PORT}", file=sys.stderr)
while True:
client, addr = server.accept()
print(f"← {addr}", file=sys.stderr)
handle_client(client, addr)
EOF
chmod +x /usr/local/bin/telegram-relay.py
2. Создай systemd-сервис:
cat > /etc/systemd/system/telegram-relay.service << 'EOF'
[Unit]
Description=Telegram Relay via Xray (Python+curl)
After=network.target xray-client.service
Requires=xray-client.service
[Service]
Type=simple
ExecStart=/usr/bin/python3 /usr/local/bin/telegram-relay.py
Restart=always
RestartSec=3
User=root
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable --now telegram-relay
3. Проверь работу:
# Проверка статуса
systemctl status telegram-relay
# Проверка порта
ss -tlnp | grep 8085
# Тест
curl -X POST http://127.0.0.1:8085 -d "🎉 Test message"
Должно прийти сообщение в Telegram!
🔧 Шаг 2: Настройка Contact Point в Grafana
1. Открой Grafana:
- Перейди: Alerting → Contact points
- Нажми + Add contact point
2. Заполни поля:
| Поле | Значение |
|---|---|
| Name | Telegram Relay |
| Integration | Webhook |
| URL | http://127.0.0.1:8085 |
| HTTP Method | POST |
| Max Alerts | 0 (без лимита) |
3. Сообщение (Message):
{{ range .Alerts }}
📦 {{ .Labels.backup }}
⏱ {{ .Annotations.description }}
Status: {{ if eq .Status "firing" }}🔥{{ else }}✅{{ end }} {{ .Status }}
---
{{ end }}
4. Сохрани:
- Нажми Save contact point
- Нажми Test — должно прийти сообщение
🔧 Шаг 3: Создание Alert Rule
1. Перейди: Alerting → Alert rules → + New alert rule
2. Query и условие:
| Поле | Значение |
|---|---|
| Query | time() - last_over_time(pbs_backup_timestamp[1h])/1000 |
| Alert condition | A is above 86400 |
| Evaluation group | Backup alerts (создать новый) |
| Evaluation interval | 1m |
| Pending period | 1m |
3. Annotations → Description:
{{ .Value }}
(Python-скрипт сам превратит секунды в "11 ч 35 мин")
4. Notifications:
- Выбери Contact Point:
Telegram Relay
5. Сохрани правило
🔧 Шаг 4: Проверка
1. Проверка реле:
# Логи реле
journalctl -u telegram-relay -f
# Тестовый запрос
curl -X POST http://127.0.0.1:8085 \
-H "Content-Type: application/json" \
-d '{"text":"✅ Grafana relay test"}'
2. Проверка XRay:
# Статус XRay
systemctl status xray-client
# Тест соединения с Telegram
curl -sx socks5://127.0.0.1:1080 \
https://api.telegram.org/bot7657027552:AAHQ6OGDRbm6wtqh_4GOQr7jd6C0BAQMyF4/getMe
3. Тест алерта:
- В Grafana: Contact Point → Test
- Должно прийти сообщение в Telegram
📝 Переменные для замены
| Переменная | Описание | Значение |
|---|---|---|
BOT_TOKEN |
Токен Telegram бота | 7657027552:AAHQ6OGDRbm6wtqh_4GOQr7jd6C0BAQMyF4 |
CHAT_ID |
ID чата для уведомлений | 292909723 |
PROXY |
SOCKS5 прокси | socks5://127.0.0.1:1080 |
PORT |
Порт реле | 8085 |
📁 Файлы конфигурации
| Файл | Назначение |
|---|---|
/usr/local/bin/telegram-relay.py |
Python-скрипт реле |
/etc/systemd/system/telegram-relay.service |
systemd-юнит |
/etc/grafana/provisioning/alerting/ |
Конфиги алертов Grafana |
🔍 Troubleshooting
| Проблема | Решение |
|---|---|
| Не приходит сообщение | journalctl -u telegram-relay -n 20 |
| Ошибка 400 от Telegram | Убери parse_mode или экранируй спецсимволы |
| Реле не слушает порт | systemctl restart telegram-relay |
| XRay не подключается | systemctl status xray-client |
| Сообщение обрезается | Скрипт разбивает на части по 5 бэкапов — это норма |
| Grafana не шлёт | Проверь что Alert Rule в состоянии "Firing" |
🎨 Пример уведомления
🚨 Backup Alert
📦 ct-201
⏱ Последний бэкап: 11 ч 35 мин назад
Status: 🔥 firing
📦 ct-202
⏱ Последний бэкап: 11 ч 34 мин назад
Status: 🔥 firing
💻 vm-205
⏱ Последний бэкап: 11 ч 30 мин назад
Status: ✅ resolved
Эмодзи:
- 💻 — виртуальные машины (vm-*)
- 📦 — LXC контейнеры (ct-*)
- 🔥 — статус firing (проблема)
- ✅ — статус resolved (всё ок)
🔄 Обновление скрипта
# Останови сервис
systemctl stop telegram-relay
# Отредактируй скрипт
nano /usr/local/bin/telegram-relay.py
# Запусти снова
systemctl start telegram-relay
# Проверь статус
systemctl status telegram-relay
Безопасность
Аутентификация
- PBS пользователи:
root@pam,pve@pbs - API токены: для автоматизации (без паролей)
- Fingerprint: SHA-256 отпечаток сертификата
Сетевая безопасность
- Порт: 8007 (TCP)
- Шифрование: TLS 1.3
- Доступ: только из локальной сети (192.168.1.0/24)
Рекомендации
- ✅ Включить 2FA для
root@pam - ✅ Создать отдельного пользователя для бэкапов (не root)
- ✅ Настроить firewall на PBS сервере
- ✅ Регулярно обновлять систему (unattended-upgrades)
Планы на будущее
🔵 Краткосрочные (1-2 месяца)
- Настроить уведомления (Telegram) о статусе бэкапов
- Включить 2FA для доступа к PBS
- Настроить репликацию в облако (Backblaze B2 / Wasabi)
- Провести тестовое восстановление всех критичных ВМ
🔵 Долгосрочные (3-6 месяцев)
- Добавить второй PBS для репликации
- Настроить оффсайт-копии (внешний диск + облако)
- Внедрить шифрование бэкапов на стороне клиента
- Автоматизировать тестирование восстановления
Troubleshooting
Бэкап не запускается
# Проверить хранилище
pvesm status | grep olimpbkp
# Проверить подключение к PBS
ping 192.168.1.199
nc -zv 192.168.1.199 8007
# Переподключить хранилище
pvesm remove olimpbkp
pvesm add proxmox-backup olimpbkp \
--server 192.168.1.199 \
--datastore olimpbkp \
--username pve@pbs
Закончилось место на PBS
# Проверить занятое место
proxmox-backup-client datastore stats olimpbkp
# Запустить GC
proxmox-backup-manager garbage-collection start olimpbkp
# Удалить старые бэкапы вручную
proxmox-backup-client prune \
--repository root@pam@192.168.1.199:8007:olimpbkp \
--max-daily 7 --max-weekly 2
Ошибка аутентификации PBS
# Сгенерировать новый токен
proxmox-backup-manager user generate-token pve@pbs backup-token
# Обновить в Proxmox VE
pvesm update olimpbkp --password <новый_токен>
Проблемы с уведомлениями в Telegram
| Проблема | Решение |
|---|---|
| Не приходят уведомления | Проверить curl -s https://api.telegram.org/bot<TOKEN>/getMe |
| Ошибка iptables | Перезапустить /usr/local/bin/telegram-proxy.sh |
| XRay не запускается | journalctl -u xray-client -n 20 --no-pager |
| Дубликат уведомлений | Удалить /var/run/pbs-notify-lastline и пересоздать |
Полезные команды
На Proxmox VE
# Список хранилищ
pvesm list
# Статус бэкап хранилища
pvesm status olimpbkp
# Запустить бэкап
vzdump <vmid> --storage olimpbkp --mode snapshot
# Восстановить
pct restore <new-vmid> olimpbkp:backup/ct/<ctid>/<timestamp>
qm restore <new-vmid> olimpbkp:backup/vm/<vmid>/<timestamp>
На PBS
# Список datastore
proxmox-backup-manager datastore list
# Статистика
proxmox-backup-client datastore stats olimpbkp
# Список бэкапов
proxmox-backup-client list --repository root@pam@192.168.1.199:8007:olimpbkp
# Информация о бэкапе
proxmox-backup-client show-backup ct/201 --repository root@pam@192.168.1.199:8007:olimpbkp
# Проверка целостности
proxmox-backup-manager verify olimpbkp
# Garbage collection
proxmox-backup-manager garbage-collection start olimpbkp
Метрики и отчётность
Ежедневная проверка
# Размер бэкапов за сегодня
du -sh /var/lib/proxmox-backup/olimpbkp/data/*
# Количество бэкапов
proxmox-backup-client list --repository root@pam@192.168.1.199:8007:olimpbkp | wc -l
# Свободное место
df -h /var/lib/proxmox-backup/olimpbkp
Еженедельный отчёт
# Дедупликация
proxmox-backup-client datastore stats olimpbkp | grep "Deduplication"
# Прирост за неделю
# Сравнить размер datastore с прошлой неделей
Связанные разделы: