Update docs
This commit is contained in:
parent
5dd61df087
commit
96c07cdddd
4 changed files with 196 additions and 54 deletions
136
ARCHITECTURE.md
136
ARCHITECTURE.md
|
|
@ -2,12 +2,33 @@
|
|||
|
||||
## Обзор
|
||||
|
||||
API Sync — однопроходная утилита (не демон), запускаемая по cron. При каждом запуске выполняет три последовательных этапа: синхронизацию данных из API в PostgreSQL, очистку устаревших записей и обновление whitelist-файла в Git-репозитории.
|
||||
API Sync — однопроходная утилита (не демон), запускаемая по cron. Поддерживает два режима запуска: основной и проверка дублей по ключу `--cd`.
|
||||
|
||||
---
|
||||
|
||||
## Режимы запуска
|
||||
|
||||
```bash
|
||||
./API_sync # основной запуск
|
||||
./API_sync --cd # только проверка дублирующихся доменов/алиасов
|
||||
```
|
||||
|
||||
Пример cron-конфигурации:
|
||||
|
||||
```
|
||||
# Основной запуск каждые 15 минут
|
||||
*/15 * * * * install cd /home/install && /home/install/API_sync >> /var/log/API_sync.log 2>&1
|
||||
|
||||
# Проверка дублей каждый час
|
||||
0 * * * * install cd /home/install && /home/install/API_sync --cd >> /var/log/API_sync.log 2>&1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Поток выполнения
|
||||
|
||||
### Основной режим
|
||||
|
||||
```
|
||||
main()
|
||||
│
|
||||
|
|
@ -19,33 +40,49 @@ main()
|
|||
│
|
||||
├─ 4. Параллельная обработка SID (worker pool)
|
||||
│ └─ processSID() для каждого SID
|
||||
│ ├─ GET /l7/resource/{sid}/global → whois
|
||||
│ ├─ GET /l7/origin/global?l7ResourceId={sid} → origins
|
||||
│ ├─ GET /l7/alias/global?l7ResourceId={sid} → aliases
|
||||
│ ├─ GET /l7/resource/{sid}/global → whois
|
||||
│ │ └─ ошибка → алерт 🔴 + следующий SID
|
||||
│ ├─ GET /l7/origin/global?l7ResourceId={sid} → origins
|
||||
│ │ └─ ошибка → алерт 🔴 + следующий SID
|
||||
│ ├─ GET /l7/alias/global?l7ResourceId={sid} → aliases
|
||||
│ │ └─ ошибка → алерт 🔴 + следующий SID
|
||||
│ ├─ DNS резолв домена → проверка AntiDDOS
|
||||
│ └─ upsertAPIInfo() → сравнение + запись в API_info + алерты
|
||||
│
|
||||
├─ 5. Очистка устаревших SID из API_info (cleanupRemovedSIDs)
|
||||
│
|
||||
└─ 6. Обновление WAF whitelist (updateWAFWhitelist)
|
||||
├─ 6. Проверка дублирующихся доменов/алиасов (если CHECK_DUPLICATES=true)
|
||||
│ └─ checkDuplicateDomains() → алерт 🔴 если найдены дубли
|
||||
│
|
||||
└─ 7. Обновление WAF whitelist (updateWAFWhitelist)
|
||||
├─ git pull
|
||||
├─ Загрузка IP из API_info (auto)
|
||||
├─ Загрузка IP из manual_info (ручные)
|
||||
├─ Загрузка IP из API_info (auto-ресурсы)
|
||||
├─ Загрузка IP из manual_info (ручные ресурсы)
|
||||
├─ Объединение и дедупликация IP
|
||||
├─ Фильтрация WAF-сетей (таблица ips)
|
||||
├─ Сравнение с текущим whitelist-файлом
|
||||
├─ Запись файла + git commit + git push
|
||||
└─ Отправка алерта об изменениях
|
||||
```
|
||||
|
||||
### Режим --cd
|
||||
|
||||
```
|
||||
main() --cd
|
||||
│
|
||||
├─ 1. Подключение к PostgreSQL
|
||||
└─ 2. checkDuplicateDomains() → алерт 🔴 если найдены дубли
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Модули
|
||||
|
||||
### main.go — точка входа и worker pool
|
||||
|
||||
Инициализирует подключение к БД, собирает все SID для обработки и запускает пул горутин. Количество воркеров задаётся через `MAX_CONCURRENT_WORKERS` (по умолчанию 5). SID передаются воркерам через буферизированный канал.
|
||||
При запуске с ключом `--cd` выполняет только проверку дублей и завершается. В основном режиме инициализирует подключение к БД, собирает все SID и запускает пул горутин. Количество воркеров задаётся через `MAX_CONCURRENT_WORKERS` (по умолчанию 5). SID передаются воркерам через буферизированный канал. Все воркеры работают параллельно — DNS-резолв, запросы к API и запись в БД выполняются одновременно для разных SID.
|
||||
|
||||
После завершения всех воркеров последовательно запускаются очистка устаревших записей и обновление whitelist.
|
||||
После завершения всех воркеров последовательно запускаются: очистка устаревших записей, проверка дублей (если не отключена через `CHECK_DUPLICATES=false`) и обновление whitelist.
|
||||
|
||||
### config.go — конфигурация
|
||||
|
||||
|
|
@ -53,7 +90,7 @@ main()
|
|||
|
||||
### api.go — HTTP-клиент и структуры API
|
||||
|
||||
Содержит единственный HTTP-клиент с таймаутом 20 секунд и функцию `apiGet()`, которая выполняет GET-запрос к API API с Bearer-авторизацией и десериализует JSON-ответ в переданную структуру.
|
||||
Содержит единственный HTTP-клиент с таймаутом 20 секунд и функцию `apiGet()`, которая выполняет GET-запрос к API ServicePipe с Bearer-авторизацией и десериализует JSON-ответ в переданную структуру.
|
||||
|
||||
Определены структуры ответов API: `originItem`, `aliasItem`, `whoisReAPIonse`, `apiList`.
|
||||
|
||||
|
|
@ -63,25 +100,31 @@ main()
|
|||
|
||||
**`loadL7IDs()`** — загружает SID из `apps_settings` для конкретного клиента с `mode = 'auto'`.
|
||||
|
||||
**`processSID()`** — оркестрирует обработку одного SID: делает три запроса к API, резолвит домен для проверки AntiDDOS, вызывает `upsertAPIInfo()`.
|
||||
**`processSID()`** — оркестрирует обработку одного SID: делает три запроса к API, резолвит домен для проверки AntiDDOS, вызывает `upsertAPIInfo()`. При ошибке любого API-запроса отправляет алерт через `sendAPIErrorAlert()` с указанием SID, endpoint и текста ошибки.
|
||||
|
||||
**`upsertAPIInfo()`** — сравнивает новые данные со старыми из БД и при наличии изменений формирует алерты:
|
||||
- изменение домена → алерт + флаг необходимости обновления PT AF
|
||||
- изменение origins (IP, mode, weight) — через `compareOrigins()`
|
||||
- изменение aliases — через `compareAliases()`
|
||||
**`sendAPIErrorAlert()`** — формирует и отправляет алерт 🔴 при ошибке запроса к API ServicePipe. Указывает SID, endpoint (`whois`, `origins`, `aliases`) и текст ошибки.
|
||||
|
||||
**`upsertAPIInfo()`** — в начале подтягивает из БД `client_title` (из `apps_settings`) и `waf_provider` (из `client_info`) для использования в алертах. Затем сравнивает новые данные со старыми и при наличии изменений формирует алерты:
|
||||
- изменение домена → строка `Домен изменён: old -> new` + флаг необходимости обновления WAF
|
||||
- изменение origins — через `compareOrigins()`
|
||||
- изменение aliases — через `compareAliases()` + флаг обновления WAF
|
||||
- изменение WAF-настроек (vendor, instance, enabled) — отдельный алерт
|
||||
|
||||
Сохранение выполняется через `INSERT ... ON CONFLICT DO UPDATE` (upsert по `sid`).
|
||||
|
||||
**`cleanupRemovedSIDs()`** — сравнивает все SID в `API_info` с актуальным списком активных SID. Записи, которых нет в активном списке (ресурс удалён из `apps_settings` или сменил `mode`), удаляются из `API_info`. По каждому удалённому ресурсу отправляется алерт с указанием WAF-вендора (берётся из `apps_settings` через LEFT JOIN).
|
||||
|
||||
**`wafVendorWarning()`** — формирует строку предупреждения в зависимости от вендора: `ptaf` → PT AF, `sw` → SW, `wmx` → WMX.
|
||||
**`checkDuplicateDomains()`** — загружает все `domain_name` и `aliases` из `API_info` в единую карту. Если одно и то же значение встречается у двух и более разных SID в любой комбинации полей — считается дублем. При наличии дублей отправляется алерт 🔴 с перечислением всех совпадений и их SID. В основном режиме управляется флагом `CHECK_DUPLICATES`, при запуске с `--cd` выполняется всегда.
|
||||
|
||||
**`wafVendorName()`** — возвращает читаемое название вендора: `ptaf` → `PT AF`, `sw` → `SW`, `wmx` → `WMX`.
|
||||
|
||||
**`wafVendorWarning()`** — возвращает строку предупреждения для алерта об удалении ресурса с указанием конкретного WAF-вендора.
|
||||
|
||||
### compare.go — функции сравнения
|
||||
|
||||
**`compareOrigins()`** — сравнивает два списка origins по IP-адресу. Определяет добавленные, удалённые и изменённые (mode/weight) записи. Возвращает отформатированную строку для алерта с текущим состоянием origins.
|
||||
**`compareOrigins()`** — сравнивает два списка origins по IP-адресу. Определяет добавленные, удалённые и изменённые (mode/weight) записи. Возвращает отформатированную строку с изменениями и текущим состоянием origins.
|
||||
|
||||
**`compareAliases()`** — сравнивает два отсортированных списка доменов. Возвращает строку с изменениями и булев флаг наличия изменений.
|
||||
**`compareAliases()`** — сравнивает два отсортированных списка доменов. Добавленные aliases оформляются как HTML-ссылки. Возвращает строку с изменениями и булев флаг наличия изменений.
|
||||
|
||||
### dns.go — DNS-резолвер
|
||||
|
||||
|
|
@ -100,7 +143,7 @@ main()
|
|||
|
||||
**Mattermost** — POST на `/api/v4/posts` с Bearer-токеном. HTML-теги Telegram конвертируются в Markdown через `htmlToMarkdown()`. Отправляется только если заполнены все три переменные: `MATTERMOST_URL`, `MATTERMOST_BOT_TOKEN`, `MATTERMOST_CHANNEL_ID`.
|
||||
|
||||
**Email** — через стандартный `net/smtp`. Поддерживает несколько адресов получателей через запятую в `EMAIL_TO`. Авторизация опциональна — если `EMAIL_SMTP_USER` пуст, отправка идёт без аутентификации (relay). HTML-теги Telegram удаляются через `stripHTMLTags()`. Отправляется только если заполнены `EMAIL_SMTP_HOST`, `EMAIL_FROM`, `EMAIL_TO`.
|
||||
**Email** — через стандартный `net/smtp`. Поддерживает несколько адресов получателей через запятую в `EMAIL_TO`. При `EMAIL_SKIP_TLS_VERIFY=true` использует STARTTLS с отключённой проверкой сертификата. Механизм аутентификации выбирается автоматически по возможностям сервера: если сервер поддерживает `LOGIN` — используется он, иначе `PLAIN`. Реализован собственный `loginAuth` для совместимости с корпоративными SMTP (Exchange, Outlook). Отправляется только если заполнены `EMAIL_SMTP_HOST`, `EMAIL_FROM`, `EMAIL_TO`.
|
||||
|
||||
### git.go — Git-операции
|
||||
|
||||
|
|
@ -118,6 +161,8 @@ main()
|
|||
5. Сравнивает с текущим содержимым файла (`compareWhitelists`)
|
||||
6. При наличии изменений — перезаписывает файл, коммитит и пушит, отправляет алерт
|
||||
|
||||
**`loadAllOrigins()`** — загружает все origin IP из `API_info` (auto-ресурсы).
|
||||
|
||||
**`loadManualOrigins()`** — загружает все записи из `manual_info` как есть, без дополнительных условий. Таблица заполняется администратором вручную и программой не изменяется.
|
||||
|
||||
**`filterNonWAFOrigins()`** — исключает из списка IP-адреса, которые принадлежат WAF-сетям из таблицы `ips`. Такие адреса являются узлами самого WAF и не должны попадать в whitelist.
|
||||
|
|
@ -128,14 +173,50 @@ main()
|
|||
|
||||
Все алерты отправляются через единую функцию `sendAlert()`. Типы алертов:
|
||||
|
||||
| Событие | Содержание |
|
||||
|---|---|
|
||||
| Изменение origins | Добавленные/удалённые/изменённые backend IP + текущее состояние |
|
||||
| Изменение aliases | Добавленные/удалённые домены |
|
||||
| Изменение домена | Старое и новое значение + предупреждение об обновлении WAF |
|
||||
| Изменение WAF-настроек | Изменения waf_enabled, waf_vendor, waf_instance |
|
||||
| Удаление ресурса | SID, домен, предупреждение с указанием конкретного WAF-вендора |
|
||||
| Обновление whitelist | Добавленные/удалённые IP с привязкой к SID и домену, итоговое количество |
|
||||
| Событие | Эмодзи | Содержание |
|
||||
|---|---|---|
|
||||
| Изменение origins/aliases/домена | 🟡 | SID, домен, TENANT, WAF provider, детали изменений, предупреждение об обновлении WAF, время |
|
||||
| Изменение WAF-настроек инстанса | ⚪ | SID, домен, TENANT, изменения waf_enabled/vendor/instance в формате `было -> стало`, время |
|
||||
| Удаление ресурса из мониторинга | 🗑 | SID, домен, предупреждение с указанием конкретного WAF-вендора |
|
||||
| Ошибка запроса к API ServicePipe | 🔴 | SID, endpoint, текст ошибки, время |
|
||||
| Дублирующиеся домены/алиасы | 🔴 | Список дублей с указанием SID, время проверки |
|
||||
| Обновление whitelist | 🔄 | Добавленные/удалённые IP с привязкой к SID и домену, итоговое количество |
|
||||
|
||||
Предупреждение об обновлении WAF формируется динамически в зависимости от вендора: `ptaf` → PT AF, `sw` → SW, `wmx` → WMX.
|
||||
|
||||
---
|
||||
|
||||
## Переменные окружения
|
||||
|
||||
| Переменная | По умолчанию | Описание |
|
||||
|---|---|---|
|
||||
| `BEARER_TOKEN` | — | Токен авторизации API ServicePipe |
|
||||
| `DB_HOST` | localhost | Хост PostgreSQL |
|
||||
| `DB_PORT` | 5432 | Порт PostgreSQL |
|
||||
| `DB_USER` | — | Пользователь БД |
|
||||
| `DB_PASSWORD` | — | Пароль БД |
|
||||
| `DB_NAME` | waf_info | Имя БД |
|
||||
| `TELEGRAM_BOT_TOKEN` | — | Токен Telegram-бота |
|
||||
| `TELEGRAM_CHAT_ID` | — | ID чата для алертов |
|
||||
| `TELEGRAM_HTTP_PROXY` | — | HTTP-прокси для Telegram |
|
||||
| `TELEGRAM_SOCKS5_PROXY` | — | SOCKS5-прокси для Telegram |
|
||||
| `TELEGRAM_SOCKS5_USER` | — | Логин SOCKS5-прокси |
|
||||
| `TELEGRAM_SOCKS5_PASSWORD` | — | Пароль SOCKS5-прокси |
|
||||
| `MATTERMOST_URL` | — | URL Mattermost-сервера |
|
||||
| `MATTERMOST_BOT_TOKEN` | — | Токен Mattermost-бота |
|
||||
| `MATTERMOST_CHANNEL_ID` | — | ID канала Mattermost |
|
||||
| `EMAIL_SMTP_HOST` | — | SMTP-сервер |
|
||||
| `EMAIL_SMTP_PORT` | 587 | SMTP-порт |
|
||||
| `EMAIL_SMTP_USER` | — | Логин SMTP |
|
||||
| `EMAIL_SMTP_PASSWORD` | — | Пароль SMTP |
|
||||
| `EMAIL_FROM` | — | Адрес отправителя |
|
||||
| `EMAIL_TO` | — | Адреса получателей (через запятую) |
|
||||
| `EMAIL_SKIP_TLS_VERIFY` | false | Отключить проверку TLS-сертификата SMTP |
|
||||
| `GIT_REPO_URL` | — | URL Git-репозитория whitelist |
|
||||
| `GIT_REPO_PATH` | — | Локальный путь к репозиторию |
|
||||
| `WHITELIST_FILE` | whitelist_ptaf.txt | Имя файла whitelist |
|
||||
| `MAX_CONCURRENT_WORKERS` | 5 | Количество параллельных воркеров |
|
||||
| `CHECK_DUPLICATES` | true | Включить проверку дублей в основном режиме |
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -147,3 +228,4 @@ main()
|
|||
| `github.com/joho/godotenv` | Загрузка `.env` файла |
|
||||
| `golang.org/x/net` | SOCKS5 прокси для Telegram |
|
||||
| `net/smtp` | Отправка email (стандартная библиотека) |
|
||||
| `crypto/tls` | TLS для SMTP с отключённой проверкой сертификата |
|
||||
71
README.md
71
README.md
|
|
@ -5,7 +5,7 @@
|
|||
## Структура проекта
|
||||
|
||||
```
|
||||
├── main.go # Точка входа, worker pool
|
||||
├── main.go # Точка входа, worker pool, режим --cd
|
||||
├── config.go # Конфигурация и переменные окружения
|
||||
├── api.go # HTTP клиент и API структуры
|
||||
├── database.go # Работа с PostgreSQL
|
||||
|
|
@ -37,8 +37,6 @@ go build -o API_sync
|
|||
go build -ldflags="-s -w" -o API_sync
|
||||
```
|
||||
|
||||
Go автоматически найдёт все `.go` файлы в директории и скомпилирует их в один бинарник.
|
||||
|
||||
## Конфигурация
|
||||
|
||||
### Шаг 1: Создать файл конфигурации
|
||||
|
|
@ -83,14 +81,16 @@ EMAIL_SMTP_USER=user@example.com
|
|||
EMAIL_SMTP_PASSWORD=your_password
|
||||
EMAIL_FROM=API_sync@example.com
|
||||
EMAIL_TO=admin@example.com,team@example.com
|
||||
EMAIL_SKIP_TLS_VERIFY=false
|
||||
|
||||
# Git репозиторий whitelist
|
||||
GIT_REPO_URL=https://token@svc-git.test.ru/wmx/waf_whitelist.git
|
||||
GIT_REPO_URL=https://token@svc-git.cirex.ru/wmx/waf_whitelist.git
|
||||
GIT_REPO_PATH=/home/install/waf_whitelist
|
||||
WHITELIST_FILE=whitelist_ptaf.txt
|
||||
|
||||
# Параллельность
|
||||
# Параллельность и функции
|
||||
MAX_CONCURRENT_WORKERS=5
|
||||
CHECK_DUPLICATES=true
|
||||
```
|
||||
|
||||
### Шаг 3: Защитить файл конфигурации
|
||||
|
|
@ -104,14 +104,23 @@ chmod 600 API_sync.env
|
|||
### Запуск вручную
|
||||
|
||||
```bash
|
||||
# Основной запуск
|
||||
./API_sync
|
||||
|
||||
# Только проверка дублирующихся доменов/алиасов
|
||||
./API_sync --cd
|
||||
```
|
||||
|
||||
### Запуск через cron
|
||||
|
||||
```bash
|
||||
# /etc/cron.d/API_sync
|
||||
|
||||
# Основной запуск каждые 15 минут
|
||||
*/15 * * * * install cd /home/install && /home/install/API_sync >> /var/log/API_sync.log 2>&1
|
||||
|
||||
# Проверка дублей каждый час
|
||||
0 * * * * install cd /home/install && /home/install/API_sync --cd >> /var/log/API_sync.log 2>&1
|
||||
```
|
||||
|
||||
## Возможности
|
||||
|
|
@ -132,6 +141,10 @@ chmod 600 API_sync.env
|
|||
|
||||
✅ **Очистка устаревших данных** — автоматическое удаление из API_info ресурсов, пропавших из apps_settings
|
||||
|
||||
✅ **Алерты об ошибках API** — уведомление при недоступности API API для конкретного SID
|
||||
|
||||
✅ **Проверка дублей** — поиск совпадающих доменов/алиасов между разными SID, запускается в основном режиме (управляется `CHECK_DUPLICATES`) или отдельно через `--cd`
|
||||
|
||||
✅ **Режим auto/manual** — только ресурсы с `mode = 'auto'` синхронизируются через API; ресурсы из manual_info используются как дополнительный источник IP для whitelist
|
||||
|
||||
## База данных
|
||||
|
|
@ -173,32 +186,34 @@ CREATE TABLE manual_info (
|
|||
origins JSONB
|
||||
);
|
||||
|
||||
-- Добавить столбец mode в apps_settings (если ещё не добавлен)
|
||||
-- Добавить столбцы в apps_settings (если ещё не добавлены)
|
||||
ALTER TABLE apps_settings ADD COLUMN mode VARCHAR(10) DEFAULT 'auto';
|
||||
|
||||
-- Добавить столбец waf_vendor в apps_settings (если ещё не добавлен)
|
||||
ALTER TABLE apps_settings ADD COLUMN waf_vendor VARCHAR(50);
|
||||
|
||||
-- Добавить столбец в client_info (если ещё не добавлен)
|
||||
ALTER TABLE client_info ADD COLUMN waf_provider VARCHAR(50);
|
||||
```
|
||||
|
||||
## Логи
|
||||
|
||||
Программа выводит детальные логи:
|
||||
|
||||
```
|
||||
2025/12/26 10:00:00 Start sync API_info
|
||||
2025/12/26 10:00:00 Total SIDs to process: 25
|
||||
2025/12/26 10:00:00 Using 5 concurrent workers
|
||||
2025/12/26 10:00:01 [Worker 0] Processing SID 10307
|
||||
2025/12/26 10:00:01 [WAF Info] SID: 10307, WAF Enabled: 1, Vendor: ptaf, Instance: PTAFd_02_03
|
||||
2025/12/26 10:00:01 [AntiDDOS Check] ✅ AntiDDOS is ENABLED for nationallottery.ru
|
||||
2025/12/26 10:00:01 [Telegram] Using SOCKS5 proxy: proxy.example.com:1080
|
||||
2025/12/26 10:00:15 Finish sync API_info
|
||||
2025/12/26 10:00:15 Start cleanup of removed SIDs
|
||||
2025/12/26 10:00:15 [Cleanup] No stale SIDs found in API_info
|
||||
2025/12/26 10:00:15 Finish cleanup of removed SIDs
|
||||
2025/12/26 10:00:15 Start WAF whitelist update
|
||||
2025/12/26 10:00:16 [WAF Whitelist] No changes needed
|
||||
2025/12/26 10:00:16 Finish WAF whitelist update
|
||||
2026/06/10 10:00:00 Start sync API_info
|
||||
2026/06/10 10:00:00 Total SIDs to process: 25
|
||||
2026/06/10 10:00:00 Using 5 concurrent workers
|
||||
2026/06/10 10:00:01 [Worker 0] Processing SID 10307
|
||||
2026/06/10 10:00:01 [WAF Info] SID: 10307, WAF Enabled: 1, Vendor: ptaf, Instance: PTAFd_02_03
|
||||
2026/06/10 10:00:01 [AntiDDOS Check] ✅ AntiDDOS is ENABLED for nationallottery.ru
|
||||
2026/06/10 10:00:01 [Telegram] Using SOCKS5 proxy: proxy.example.com:1080
|
||||
2026/06/10 10:00:15 Finish sync API_info
|
||||
2026/06/10 10:00:15 Start cleanup of removed SIDs
|
||||
2026/06/10 10:00:15 [Cleanup] No stale SIDs found in API_info
|
||||
2026/06/10 10:00:15 Finish cleanup of removed SIDs
|
||||
2026/06/10 10:00:15 Start duplicate domain/alias check
|
||||
2026/06/10 10:00:15 [Duplicate Check] No duplicates found
|
||||
2026/06/10 10:00:15 Finish duplicate domain/alias check
|
||||
2026/06/10 10:00:15 Start WAF whitelist update
|
||||
2026/06/10 10:00:16 [WAF Whitelist] No changes needed
|
||||
2026/06/10 10:00:16 Finish WAF whitelist update
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
|
@ -228,3 +243,11 @@ MAX_CONCURRENT_WORKERS=10
|
|||
### Telegram не доступен напрямую
|
||||
|
||||
Заполните переменные прокси в конфигурации. Утилита автоматически попробует HTTP-прокси, затем SOCKS5, и только если оба недоступны — прямое подключение.
|
||||
|
||||
### Ошибка TLS при отправке email
|
||||
|
||||
Если сертификат SMTP-сервера просрочен или невалиден:
|
||||
|
||||
```env
|
||||
EMAIL_SKIP_TLS_VERIFY=true
|
||||
```
|
||||
27
database.go
27
database.go
|
|
@ -63,18 +63,21 @@ func processSID(db *sql.DB, sid int64) error {
|
|||
// WHOIS
|
||||
var whois whoisResponse
|
||||
if err := apiGet(whoisURL+fmt.Sprint(sid)+"/global", &whois); err != nil {
|
||||
sendAPIErrorAlert(sid, "whois", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ORIGINS
|
||||
var originsResp apiList[originItem]
|
||||
if err := apiGet(originURL+fmt.Sprint(sid), &originsResp); err != nil {
|
||||
sendAPIErrorAlert(sid, "origins", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// ALIASES
|
||||
var aliasResp apiList[aliasItem]
|
||||
if err := apiGet(aliasURL+fmt.Sprint(sid), &aliasResp); err != nil {
|
||||
sendAPIErrorAlert(sid, "aliases", err)
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -331,7 +334,7 @@ func upsertSPInfo(
|
|||
wafProviderClient,
|
||||
strings.Join(changeDetails, "\n"),
|
||||
ptafWarning,
|
||||
now.Format("2006-01-02 15:04:05 UTC+3"),
|
||||
now.Format("2006-01-02 15:04:05")+" UTC+3",
|
||||
)
|
||||
|
||||
if err := sendAlert(message); err != nil {
|
||||
|
|
@ -353,7 +356,7 @@ func upsertSPInfo(
|
|||
domain,
|
||||
clientTitle,
|
||||
strings.Join(wafChangeDetails, "\n"),
|
||||
now.Format("2006-01-02 15:04:05 UTC+3"),
|
||||
now.Format("2006-01-02 15:04:05")+" UTC+3",
|
||||
)
|
||||
|
||||
if err := sendAlert(wafMessage); err != nil {
|
||||
|
|
@ -366,6 +369,24 @@ func upsertSPInfo(
|
|||
return nil
|
||||
}
|
||||
|
||||
func sendAPIErrorAlert(sid int64, endpoint string, err error) {
|
||||
now := time.Now().In(time.FixedZone("UTC+3", 3*60*60))
|
||||
message := fmt.Sprintf(
|
||||
"🔴 <b>Ошибка запроса к API ServicePipe</b>\n\n"+
|
||||
"<b>SID:</b> %d\n"+
|
||||
"<b>Endpoint:</b> %s\n"+
|
||||
"<b>Ошибка:</b> %s\n\n"+
|
||||
"<b>Время:</b> %s",
|
||||
sid,
|
||||
endpoint,
|
||||
err.Error(),
|
||||
now.Format("2006-01-02 15:04:05")+" UTC+3",
|
||||
)
|
||||
if alertErr := sendAlert(message); alertErr != nil {
|
||||
log.Printf("[API Error Alert] Failed to send alert for SID %d: %v", sid, alertErr)
|
||||
}
|
||||
}
|
||||
|
||||
func wafVendorName(vendor string) string {
|
||||
switch strings.ToLower(vendor) {
|
||||
case "ptaf":
|
||||
|
|
@ -559,7 +580,7 @@ func checkDuplicateDomains(db *sql.DB) error {
|
|||
}
|
||||
|
||||
now := time.Now().In(time.FixedZone("UTC+3", 3*60*60))
|
||||
msg.WriteString(fmt.Sprintf("\n<b>Время проверки:</b> %s", now.Format("2006-01-02 15:04:05 UTC+3")))
|
||||
msg.WriteString(fmt.Sprintf("\n<b>Время проверки:</b> %s", now.Format("2006-01-02 15:04:05")+" UTC+3"))
|
||||
|
||||
if err := sendAlert(msg.String()); err != nil {
|
||||
log.Printf("[Duplicate Check] Failed to send alert: %v", err)
|
||||
|
|
|
|||
16
main.go
16
main.go
|
|
@ -2,12 +2,28 @@ package main
|
|||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"sync"
|
||||
|
||||
_ "github.com/lib/pq" // PostgreSQL driver
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Режим --cd: только проверка дублей
|
||||
if len(os.Args) > 1 && os.Args[1] == "--cd" {
|
||||
log.Println("Running duplicate domain/alias check only")
|
||||
|
||||
db, err := dbConnect()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
if err := checkDuplicateDomains(db); err != nil {
|
||||
log.Printf("Duplicate check error: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
log.Println("Start sync sp_info")
|
||||
|
||||
db, err := dbConnect()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue