diff --git a/docs/11-backup.md b/docs/11-backup.md index 05991b5..c8061a9 100644 --- a/docs/11-backup.md +++ b/docs/11-backup.md @@ -542,8 +542,121 @@ graph LR ``` --- +### 🔧 Шаг 0: Установка XRay (если не установлен) -### 🔧 Шаг 1: Установка Python-реле +**XRay нужен для проксирования запросов в Telegram.** + +**1. Установи зависимости:** + +```bash +apt update && apt install unzip curl iptables -y +``` + +**2. Скачай и установи XRay:** + +```bash +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. Создай конфигурацию:** + +```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 +``` + +**4. Создай systemd-сервис:** + +```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 +``` + +**5. Проверь работу:** + +```bash +systemctl status xray-client + +# Тест соединения +curl -sx socks5://127.0.0.1:1080 \ + https://api.telegram.org/bot7657027552:AAHQ6OGDRbm6wtqh_4GOQr7jd6C0BAQMyF4/getMe +``` + +Должен вернуться JSON с информацией о боте. + +--- + +### 🔧 Шаг 2: Установка Python-реле **1. Создай скрипт реле:** @@ -561,7 +674,6 @@ CHAT_ID = "292909723" PROXY = "socks5://127.0.0.1:1080" def format_duration(seconds): - """Преобразует секунды в читаемый формат""" try: sec = float(seconds) if sec < 60: @@ -578,11 +690,9 @@ def format_duration(seconds): return str(seconds) def get_icon(backup): - """Выбирает эмодзи по имени бэкапа""" return "💻" if backup.startswith('vm-') else "📦" if backup.startswith('ct-') else "🗄️" def send_telegram(text): - """Отправляет текст в Telegram через прокси""" try: cmd = [ 'curl', '-sx', PROXY, '-s', @@ -597,7 +707,6 @@ def send_telegram(text): def handle_client(client_socket, addr): try: - # Читаем запрос частями data = b"" client_socket.settimeout(2) while True: @@ -617,33 +726,35 @@ def handle_client(client_socket, addr): statuses = re.findall(r'"status"\s*:\s*"([^"]+)"', body) values = re.findall(r'value=([\d.]+)', body) - if not backups: - client_socket.send(b"HTTP/1.1 200 OK\r\n\r\nOK") - return - - # Отправляем порциями по 5 (чтобы влезло в лимит Telegram) - 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 backups: + CHUNK = 5 + for i in range(0, len(backups), CHUNK): + chunk_backups = backups[i:i+CHUNK] + text = "🚨 *Backup Alert*\n\n" - # Форматируем время из секунд - if len(values) >= (idx * 2 + 1): - seconds = float(values[idx * 2]) - human_time = format_duration(seconds) - desc = f"Последний бэкап: {human_time} назад" - else: - desc = "Нет данных" + 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" - status_emoji = "🔥" if status == "firing" else "✅" - text += f"{icon} *{backup}*\n⏱ {desc}\nStatus: {status_emoji} *{status}*\n\n" - - send_telegram(text) + 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")