Docs/docs/11-backup.md
2026-04-12 00:10:59 +05:00

729 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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) |
### 📊 Архитектура
```mermaid
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**:
```text
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**:
```text
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**:
```text
https://192.168.1.199:8007
→ Datastore → olimpbkp → Content
```
**Через Proxmox VE**:
```text
https://192.168.1.220:8006
→ Datacenter → Storage → olimpbkp → Content
```
**Через CLI**:
```bash
# Список бэкапов
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
```
### Ручной запуск бэкапа
**Один контейнер/ВМ**:
```bash
vzdump 201 --storage olimpbkp --mode snapshot --compress zstd
```
**Все бэкапируемые системы**:
```bash
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**:
1. Datacenter → Storage → olimpbkp → Content
2. Выбрать бэкап → Restore
3. Указать:
- **Storage**: целевое хранилище (local-lvm, vmsystem)
- **VMID**: новый ID (или существующий для перезаписи)
4. Start
**Через CLI**:
```bash
# 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**:
1. PBS веб-интерфейс → Datastore → Content
2. Выбрать бэкап → **File Restore**
3. Смонтировать бэкап
4. Скачать нужные файлы
5. Unmount
**Через CLI**:
```bash
# Смонтировать бэкап
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
```
---
## Мониторинг и обслуживание
### Проверка статуса бэкапов
**Ежедневная проверка**:
```bash
# Последние задачи
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 ежедневно. Вручную:
```bash
# На PBS сервере
proxmox-backup-manager garbage-collection start olimpbkp
# Проверка статуса
proxmox-backup-manager garbage-collection status olimpbkp
```
### Prune (удаление старых бэкапов)
Автоматически по retention политике. Вручную:
```bash
proxmox-backup-manager prune-job run <job-id>
```
### Проверка целостности (Verify)
```bash
# Проверить все бэкапы
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, без изменений на гипервизоре.
### 📋 Предварительные требования
- PBS сервер (192.168.1.199) с доступом в интернет через прокси
- Telegram бот: токен и chat_id
- Прокси: VLESS+Reality на `2.27.50.20:2054`
### 🔧 Настройка прокси (XRay + Redsocks + iptables)
**1. Установка XRay клиента**
```bash
# Установка зависимостей
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**
```bash
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 как сервис**
```bash
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**
```bash
# Установка
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**
```bash
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. Проверка соединения**
```bash
curl -s "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getMe"
```
*Ожидаемый результат*: JSON с информацией о боте.
### 🔧 Скрипт уведомлений
**7. Создание скрипта**
```bash
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 минут)**
```bash
echo "*/5 * * * * root /usr/local/bin/pbs-backup-notify.sh" >> /etc/cron.d/pbs-notify
```
**9. Инициализация и тест**
```bash
# Сброс состояния для теста
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 задача |
---
## Миграция со старого PBS
### История
**Март 2026**: PBS был развёрнут в LXC контейнере (CT 220) на том же хосте Olimp
- Хранилище: ZFS dataset `rpool/pbs-backups` (187 GB)
- Datastore: `ssd-backups`
**Апрель 2026**: Развёрнут отдельный физический сервер PBS (Olimpbs)
- Хранилище: 1 TB LVM
- Datastore: `olimpbkp`
### Перенос старых бэкапов (опционально)
```bash
# На новом PBS
mkdir -p /mnt/old-pbs
sshfs root@192.168.1.220:/rpool/pbs-backups /mnt/old-pbs
# Копирование
rsync -avh /mnt/old-pbs/data/ /var/lib/proxmox-backup/olimpbkp/
# Исправление прав
chown -R backup:backup /var/lib/proxmox-backup/olimpbkp
# Перезапуск
systemctl restart proxmox-backup-proxy
```
### Удаление старого PBS
После подтверждения что новые бэкапы работают:
```bash
# На Proxmox VE (Olimp)
pvesm remove pbs-ssd
# Удалить dataset
zfs destroy rpool/pbs-backups
# Удалить LXC контейнер (опционально)
pct stop 220
pct destroy 220
```
---
## Безопасность
### Аутентификация
- **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 месяца)
- [x] Настроить **уведомления** (Telegram) о статусе бэкапов
- [ ] Включить **2FA** для доступа к PBS
- [ ] Настроить **репликацию** в облако (Backblaze B2 / Wasabi)
- [ ] Провести **тестовое восстановление** всех критичных ВМ
### 🔵 Долгосрочные (3-6 месяцев)
- [ ] Добавить **второй PBS** для репликации
- [ ] Настроить **оффсайт-копии** (внешний диск + облако)
- [ ] Внедрить **шифрование** бэкапов на стороне клиента
- [ ] Автоматизировать **тестирование восстановления**
---
## Troubleshooting
### Бэкап не запускается
```bash
# Проверить хранилище
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
```bash
# Проверить занятое место
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
```bash
# Сгенерировать новый токен
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
```bash
# Список хранилищ
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
```bash
# Список 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
```
---
## Метрики и отчётность
### Ежедневная проверка
```bash
# Размер бэкапов за сегодня
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
```
### Еженедельный отчёт
```bash
# Дедупликация
proxmox-backup-client datastore stats olimpbkp | grep "Deduplication"
# Прирост за неделю
# Сравнить размер datastore с прошлой неделей
```
---
**Связанные разделы:**
- [Гипервизор Proxmox](02-hypervisor.md)
- [Виртуальные машины и LXC](03-vms-lxcs.md)
- [Безопасность](10-security.md)
- [Мониторинг и логирование](08-monitoring.md)