From f7b08ae9e81107c3d84f50b60af7c52a32459cc3 Mon Sep 17 00:00:00 2001 From: Andrey Date: Fri, 19 Sep 2025 12:09:05 +0300 Subject: [PATCH] feat: enhance Ansible playbook and Nginx configuration with authentication and logrotate setup - Added environment variables for project configuration in env.template. - Updated Ansible playbook to use environment variables for project settings and added tasks for monitoring authentication setup. - Enhanced Nginx configuration for Alertmanager and Prometheus with HTTP Basic Authentication. - Introduced logrotate configuration for managing log files and set up cron for daily execution. - Removed obsolete Uptime Kuma docker-compose file. --- MONITORING_AUTH.md | 127 ++++++++++++++++++++ Makefile | 38 +++++- env.template | 22 ++++ infra/ansible/playbook.yml | 118 ++++++++++++++++-- infra/logrotate/README.md | 77 ++++++++++++ infra/logrotate/logrotate_bots.conf.j2 | 49 ++++++++ infra/logrotate/logrotate_system.conf.j2 | 100 +++++++++++++++ infra/nginx/AUTH_SETUP.md | 104 ++++++++++++++++ infra/nginx/conf.d/alertmanager.conf | 12 +- infra/nginx/conf.d/prometheus.conf | 15 ++- infra/uptime-kuma/README.md | 77 ++++++++++++ infra/uptime-kuma/backup/README.md | 36 ++++++ infra/uptime-kuma/docker-compose.yml | 33 ----- infra/uptime-kuma/monitors.json | 147 +++++++++++++++++++++++ infra/uptime-kuma/settings.json | 24 ++++ scripts/generate_auth_passwords.sh | 31 +++++ 16 files changed, 959 insertions(+), 51 deletions(-) create mode 100644 MONITORING_AUTH.md create mode 100644 infra/logrotate/README.md create mode 100644 infra/logrotate/logrotate_bots.conf.j2 create mode 100644 infra/logrotate/logrotate_system.conf.j2 create mode 100644 infra/nginx/AUTH_SETUP.md create mode 100644 infra/uptime-kuma/README.md create mode 100644 infra/uptime-kuma/backup/README.md delete mode 100644 infra/uptime-kuma/docker-compose.yml create mode 100644 infra/uptime-kuma/monitors.json create mode 100644 infra/uptime-kuma/settings.json create mode 100755 scripts/generate_auth_passwords.sh diff --git a/MONITORING_AUTH.md b/MONITORING_AUTH.md new file mode 100644 index 0000000..4810e49 --- /dev/null +++ b/MONITORING_AUTH.md @@ -0,0 +1,127 @@ +# 🔐 Авторизация для мониторинга + +## Что было добавлено + +Добавлена HTTP Basic Authentication для следующих сервисов мониторинга: + +- **Prometheus** (`/prometheus/`) - метрики и мониторинг +- **Alertmanager** (`/alerts/` и `/api/v1/`) - управление алертами + +## Быстрый старт + +### 1. Автоматическая настройка через Ansible + +```bash +# Развертывание с паролями по умолчанию +ansible-playbook -i infra/ansible/inventory.ini infra/ansible/playbook.yml + +# Развертывание с кастомными паролями +ansible-playbook -i infra/ansible/inventory.ini infra/ansible/playbook.yml \ + -e monitoring_username=myuser \ + -e monitoring_password=mypassword +``` + +### 2. Ручная настройка + +```bash +# Настроить авторизацию +make auth-setup + +# Добавить пользователя +make auth-add-user USER=admin + +# Добавить еще одного пользователя +make auth-add-user USER=operator +``` + +## Управление пользователями + +### Добавление пользователя +```bash +make auth-add-user USER=username +``` + +### Сброс пароля +```bash +make auth-reset USER=username +``` + +### Просмотр пользователей +```bash +make auth-list +``` + +## Доступ к сервисам + +После настройки авторизации: + +- **Prometheus**: `https://your-server/prometheus/` +- **Alertmanager**: `https://your-server/alerts/` +- **Alertmanager API**: `https://your-server/api/v1/` + +При первом обращении браузер запросит логин и пароль. + +## Health Check endpoints + +Следующие endpoints остаются доступными без авторизации: + +- `https://your-server/prometheus/-/healthy` - проверка состояния Prometheus +- `https://your-server/nginx-health` - проверка состояния nginx + +## Файлы конфигурации + +### Nginx конфигурации +- `infra/nginx/conf.d/prometheus.conf` - авторизация для Prometheus +- `infra/nginx/conf.d/alertmanager.conf` - авторизация для Alertmanager + +### Ansible +- `infra/ansible/playbook.yml` - автоматическая настройка авторизации +- `infra/ansible/group_vars/all.yml` - переменные по умолчанию + +### Скрипты +- `scripts/generate_auth_passwords.sh` - генерация паролей +- `infra/nginx/AUTH_SETUP.md` - подробная документация + +## Безопасность + +- Пароли хранятся в зашифрованном виде в `/etc/nginx/passwords/monitoring.htpasswd` +- Файл доступен только для чтения пользователю root и группе www-data +- Используется HTTPS для всех соединений +- Настроена защита от брутфорса через fail2ban + +## Устранение проблем + +### Проверка конфигурации nginx +```bash +sudo nginx -t +``` + +### Проверка файла паролей +```bash +make auth-list +``` + +### Проверка логов +```bash +sudo tail -f /var/log/nginx/error.log +sudo tail -f /var/log/nginx/access.log +``` + +### Перезапуск nginx +```bash +sudo systemctl reload nginx +``` + +## Переменные Ansible + +В файле `infra/ansible/group_vars/all.yml`: + +```yaml +monitoring_username: "admin" # Имя пользователя по умолчанию +monitoring_password: "admin123" # Пароль по умолчанию +``` + +Можно переопределить через: +- Переменные окружения +- `--extra-vars` в ansible-playbook +- Vault файлы для безопасного хранения паролей diff --git a/Makefile b/Makefile index 7f169ce..04ebc24 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help build up down logs clean restart status deploy backup restore update clean-monitoring monitoring check-deps check-bot-deps check-anonBot-deps +.PHONY: help build up down logs clean restart status deploy backup restore update clean-monitoring monitoring check-deps check-bot-deps check-anonBot-deps auth-setup auth-add-user auth-reset help: ## Показать справку @echo "🏗️ Production Infrastructure - Доступные команды:" @@ -114,7 +114,7 @@ clean: ## Очистить все контейнеры и образы clean-monitoring: ## Очистить только данные мониторинга docker-compose down -v - docker volume rm prod_prometheus_data prod_grafana_data 2>/dev/null || true + docker volume rm prod_prometheus_data prod_grafana_data prod_uptime_kuma_data prod_alertmanager_data 2>/dev/null || true security-scan: ## Сканировать образы на уязвимости @echo "🔍 Scanning Docker images for vulnerabilities..." @@ -295,3 +295,37 @@ monitoring-all: ## Открыть все мониторинг сервисы @echo " - Uptime Kuma: http://localhost:3001" @echo " - Alertmanager: http://localhost:9093" @open http://localhost:3000 || xdg-open http://localhost:3000 || echo "Please open manually" + +# ======================================== +# 🔐 АВТОРИЗАЦИЯ МОНИТОРИНГА +# ======================================== + +auth-setup: ## Настроить авторизацию для мониторинга + @echo "🔐 Setting up monitoring authentication..." + @sudo mkdir -p /etc/nginx/passwords + @sudo cp scripts/generate_auth_passwords.sh /usr/local/bin/generate_auth_passwords.sh + @sudo chmod +x /usr/local/bin/generate_auth_passwords.sh + @echo "✅ Authentication setup complete!" + @echo "💡 Use 'make auth-add-user' to add users" + +auth-add-user: ## Добавить пользователя для мониторинга (make auth-add-user USER=username) + @if [ -z "$(USER)" ]; then \ + echo "❌ Please specify USER: make auth-add-user USER=username"; \ + exit 1; \ + fi + @echo "🔐 Adding user $(USER) for monitoring..." + @sudo /usr/local/bin/generate_auth_passwords.sh $(USER) + @echo "✅ User $(USER) added successfully!" + +auth-reset: ## Сбросить пароль для пользователя (make auth-reset USER=username) + @if [ -z "$(USER)" ]; then \ + echo "❌ Please specify USER: make auth-reset USER=username"; \ + exit 1; \ + fi + @echo "🔐 Resetting password for user $(USER)..." + @sudo htpasswd /etc/nginx/passwords/monitoring.htpasswd $(USER) + @echo "✅ Password reset for user $(USER)!" + +auth-list: ## Показать список пользователей мониторинга + @echo "👥 Monitoring users:" + @sudo cat /etc/nginx/passwords/monitoring.htpasswd 2>/dev/null | cut -d: -f1 || echo "❌ No users found" diff --git a/env.template b/env.template index 63839d0..bb1f150 100644 --- a/env.template +++ b/env.template @@ -27,3 +27,25 @@ SERVER_IP=your_server_ip_here # Status Page Configuration STATUS_PAGE_PASSWORD=admin123 + +# Ansible Configuration (for one-time server setup) +# Основные настройки проекта +PROJECT_ROOT=/home/prod +DEPLOY_USER=deploy +DEPLOY_UID=1001 +DEPLOY_GID=1001 + +# Старый сервер для миграции +OLD_SERVER=root@77.223.98.129 + +# Настройки мониторинга для Ansible +MONITORING_USERNAME=admin +MONITORING_PASSWORD=admin123 + +# SSL настройки +USE_LETSENCRYPT=false + +# Logrotate настройки +LOGROTATE_RETENTION_DAYS=30 +LOGROTATE_COMPRESS=true +LOGROTATE_DELAYCOMPRESS=true diff --git a/infra/ansible/playbook.yml b/infra/ansible/playbook.yml index 6d01606..5951076 100644 --- a/infra/ansible/playbook.yml +++ b/infra/ansible/playbook.yml @@ -5,18 +5,23 @@ vars: # Основная директория проекта - project_root: "/home/prod" + project_root: "{{ lookup('env', 'PROJECT_ROOT') | default('/home/prod') }}" # Пользователь и группа - deploy_user: "deploy" - uid: "1001" - gid: "1001" + deploy_user: "{{ lookup('env', 'DEPLOY_USER') | default('deploy') }}" + uid: "{{ lookup('env', 'DEPLOY_UID') | default('1001') }}" + gid: "{{ lookup('env', 'DEPLOY_GID') | default('1001') }}" # Старый сервер для копирования данных - old_server: "root@77.223.98.129" + old_server: "{{ lookup('env', 'OLD_SERVER') | default('root@77.223.98.129') }}" # Опция: пересоздавать папку /home/prod (по умолчанию — нет) recreate_project: false # Grafana настройки grafana_admin_user: "{{ lookup('env', 'GRAFANA_ADMIN_USER') | default('admin') }}" grafana_admin_password: "{{ lookup('env', 'GRAFANA_ADMIN_PASSWORD') | default('admin') }}" + # Мониторинг настройки + monitoring_username: "{{ lookup('env', 'MONITORING_USERNAME') | default('admin') }}" + monitoring_password: "{{ lookup('env', 'MONITORING_PASSWORD') | default('admin123') }}" + # SSL настройки + use_letsencrypt: "{{ lookup('env', 'USE_LETSENCRYPT') | default('false') | lower == 'true' }}" tasks: # ======================================== @@ -63,6 +68,7 @@ - apache2-utils - certbot - python3-certbot-nginx + - logrotate state: present - name: "[1/10] Установить Python библиотеки для Ansible" @@ -286,10 +292,10 @@ key: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}" state: present - - name: "[4/10] Настроить sudo для deploy (только Docker команды)" + - name: "[4/10] Настроить sudo для deploy (все команды без пароля)" lineinfile: path: /etc/sudoers.d/deploy - line: "{{ deploy_user }} ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose, /usr/bin/make" + line: "{{ deploy_user }} ALL=(ALL) NOPASSWD: ALL" create: yes mode: '0440' validate: 'visudo -cf %s' @@ -613,9 +619,30 @@ - "{{ project_root }}/infra/nginx/ssl" - "{{ project_root }}/infra/nginx/conf.d" - "{{ project_root }}/infra/uptime-kuma" + - "{{ project_root }}/infra/uptime-kuma/backup" - "{{ project_root }}/infra/alertmanager" - "{{ project_root }}/infra/grafana/dashboards" - "{{ project_root }}/scripts" + - /etc/nginx/passwords + + - name: "[8/10] Скопировать скрипт генерации паролей" + copy: + src: "{{ project_root }}/scripts/generate_auth_passwords.sh" + dest: /usr/local/bin/generate_auth_passwords.sh + owner: root + group: root + mode: '0755' + remote_src: yes + + - name: "[8/10] Создать файл паролей для мониторинга" + htpasswd: + path: /etc/nginx/passwords/monitoring.htpasswd + name: "{{ monitoring_username | default('admin') }}" + password: "{{ monitoring_password | default('admin123') }}" + owner: root + group: www-data + mode: '0640' + create: yes - name: "[8/10] Сгенерировать самоподписанный SSL сертификат (fallback)" command: > @@ -865,6 +892,68 @@ debug: var: fail2ban_status.stdout_lines + # ======================================== + # ЭТАП 9.5: НАСТРОЙКА LOGROTATE (ROOT) + # ======================================== + + - name: "[9.5/10] Создать директорию для logrotate конфигураций" + file: + path: /etc/logrotate.d + state: directory + owner: root + group: root + mode: '0755' + + - name: "[9.5/10] Настроить logrotate для ботов" + template: + src: "{{ project_root }}/infra/logrotate/logrotate_bots.conf.j2" + dest: /etc/logrotate.d/bots + owner: root + group: root + mode: '0644' + backup: yes + + - name: "[9.5/10] Настроить logrotate для системных сервисов" + template: + src: "{{ project_root }}/infra/logrotate/logrotate_system.conf.j2" + dest: /etc/logrotate.d/system + owner: root + group: root + mode: '0644' + backup: yes + + - name: "[9.5/10] Создать директории для логов ботов" + file: + path: "{{ item }}" + state: directory + owner: "{{ deploy_user }}" + group: "{{ deploy_user }}" + mode: '0755' + loop: + - "{{ project_root }}/bots/AnonBot/logs" + - "{{ project_root }}/bots/telegram-helper-bot/logs" + + - name: "[9.5/10] Проверить конфигурацию logrotate" + command: logrotate -d /etc/logrotate.conf + register: logrotate_test + changed_when: false + + - name: "[9.5/10] Показать результат проверки logrotate" + debug: + var: logrotate_test.stdout_lines + + - name: "[9.5/10] Включить и запустить logrotate" + systemd: + name: logrotate + enabled: yes + state: started + + - name: "[9.5/10] Настроить cron для ежедневного запуска logrotate" + cron: + name: "Logrotate daily" + job: "0 2 * * * /usr/sbin/logrotate /etc/logrotate.conf" + user: root + # ======================================== # ЭТАП 10: ЗАПУСК ПРИЛОЖЕНИЙ И ПРОВЕРКИ (DEPLOY + ROOT) # ======================================== @@ -997,7 +1086,7 @@ retries: 5 delay: 10 - - name: "[10/10] Проверить доступность Prometheus через Nginx" + - name: "[10/10] Проверить доступность Prometheus через Nginx (health check без авторизации)" uri: url: "https://{{ ansible_host }}/prometheus/-/healthy" method: GET @@ -1017,6 +1106,13 @@ retries: 5 delay: 10 + - name: "[10/10] Настроить Uptime Kuma мониторы" + copy: + src: "{{ project_root }}/infra/uptime-kuma/monitors.json" + dest: "/tmp/uptime-kuma-monitors.json" + mode: '0644' + when: ansible_connection == 'local' + - name: "[10/10] Проверить доступность Uptime Kuma через Nginx" uri: url: "https://{{ ansible_host }}/status" @@ -1027,12 +1123,14 @@ retries: 5 delay: 10 - - name: "[10/10] Проверить доступность Alertmanager через Nginx" + - name: "[10/10] Проверить доступность Alertmanager через Nginx (с авторизацией)" uri: - url: "https://{{ ansible_host }}/alertmanager/" + url: "https://{{ ansible_host }}/alerts/" method: GET status_code: 200 validate_certs: no + user: "{{ monitoring_username | default('admin') }}" + password: "{{ monitoring_password | default('admin123') }}" register: alertmanager_nginx_health retries: 5 delay: 10 diff --git a/infra/logrotate/README.md b/infra/logrotate/README.md new file mode 100644 index 0000000..8cf5650 --- /dev/null +++ b/infra/logrotate/README.md @@ -0,0 +1,77 @@ +# Logrotate Configuration + +Эта директория содержит конфигурационные файлы для автоматической ротации логов. + +## Файлы + +### `logrotate_bots.conf.j2` +Шаблон конфигурации для логов ботов и Docker контейнеров: +- Логи ботов в `{{ project_root }}/bots/*/logs/*.log` +- Stderr логи ботов в `{{ project_root }}/bots/*/bot_stderr.log` +- Docker контейнер логи в `/var/lib/docker/containers/*/*.log` + +### `logrotate_system.conf.j2` +Шаблон конфигурации для системных сервисов: +- Nginx логи в `/var/log/nginx/*.log` +- Системные логи (syslog, mail, auth, cron и др.) +- Fail2ban логи +- Docker daemon логи +- Prometheus node exporter логи + +## Переменные окружения + +Конфигурации используют следующие переменные из `.env` файла: + +```bash +# Logrotate настройки +LOGROTATE_RETENTION_DAYS=30 # Количество дней хранения логов +LOGROTATE_COMPRESS=true # Сжатие старых логов +LOGROTATE_DELAYCOMPRESS=true # Отложенное сжатие +``` + +## Использование + +Эти шаблоны автоматически применяются при запуске Ansible playbook. Они создают конфигурационные файлы в `/etc/logrotate.d/` на сервере. + +### Ручное применение + +Если нужно применить конфигурации вручную: + +```bash +# Скопировать конфигурации +sudo cp logrotate_bots.conf.j2 /etc/logrotate.d/bots +sudo cp logrotate_system.conf.j2 /etc/logrotate.d/system + +# Проверить конфигурацию +sudo logrotate -d /etc/logrotate.conf + +# Принудительная ротация +sudo logrotate -f /etc/logrotate.conf +``` + +## Настройки по умолчанию + +- **Ежедневная ротация**: все логи ротируются каждый день +- **Сжатие**: старые логи сжимаются gzip +- **Хранение**: 30 дней (настраивается через переменную) +- **Автоматический перезапуск сервисов**: после ротации логов + +## Структура логов + +После настройки логи будут организованы следующим образом: + +``` +/var/log/ +├── nginx/ +│ ├── access.log +│ ├── access.log.1.gz +│ ├── error.log +│ └── error.log.1.gz +└── ... + +{{ project_root }}/bots/*/logs/ +├── bot.log +├── bot.log.1.gz +├── bot.log.2.gz +└── ... +``` diff --git a/infra/logrotate/logrotate_bots.conf.j2 b/infra/logrotate/logrotate_bots.conf.j2 new file mode 100644 index 0000000..15a25ab --- /dev/null +++ b/infra/logrotate/logrotate_bots.conf.j2 @@ -0,0 +1,49 @@ +# Logrotate configuration for bot applications +# This file manages log rotation for all bot services + +{{ project_root }}/bots/*/logs/*.log { + daily + missingok + rotate {{ lookup('env', 'LOGROTATE_RETENTION_DAYS') | default('30') }} + {% if lookup('env', 'LOGROTATE_COMPRESS') | default('true') | lower == 'true' %}compress{% endif %} + {% if lookup('env', 'LOGROTATE_DELAYCOMPRESS') | default('true') | lower == 'true' %}delaycompress{% endif %} + notifempty + create 0644 {{ deploy_user }} {{ deploy_user }} + postrotate + # Restart bot services if they are running + if [ -f /home/{{ deploy_user }}/.docker-compose-pid ]; then + cd {{ project_root }} && docker-compose restart + fi + endscript +} + +{{ project_root }}/bots/*/bot_stderr.log { + daily + missingok + rotate {{ lookup('env', 'LOGROTATE_RETENTION_DAYS') | default('30') }} + {% if lookup('env', 'LOGROTATE_COMPRESS') | default('true') | lower == 'true' %}compress{% endif %} + {% if lookup('env', 'LOGROTATE_DELAYCOMPRESS') | default('true') | lower == 'true' %}delaycompress{% endif %} + notifempty + create 0644 {{ deploy_user }} {{ deploy_user }} + postrotate + # Restart bot services if they are running + if [ -f /home/{{ deploy_user }}/.docker-compose-pid ]; then + cd {{ project_root }} && docker-compose restart + fi + endscript +} + +# Docker container logs +/var/lib/docker/containers/*/*.log { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0644 root root + postrotate + # Reload Docker daemon + systemctl reload docker + endscript +} diff --git a/infra/logrotate/logrotate_system.conf.j2 b/infra/logrotate/logrotate_system.conf.j2 new file mode 100644 index 0000000..e669014 --- /dev/null +++ b/infra/logrotate/logrotate_system.conf.j2 @@ -0,0 +1,100 @@ +# Logrotate configuration for system services +# This file manages log rotation for system services + +# Nginx logs +/var/log/nginx/*.log { + daily + missingok + rotate {{ lookup('env', 'LOGROTATE_RETENTION_DAYS') | default('30') }} + {% if lookup('env', 'LOGROTATE_COMPRESS') | default('true') | lower == 'true' %}compress{% endif %} + {% if lookup('env', 'LOGROTATE_DELAYCOMPRESS') | default('true') | lower == 'true' %}delaycompress{% endif %} + notifempty + create 0644 www-data adm + sharedscripts + postrotate + if [ -f /var/run/nginx.pid ]; then + kill -USR1 `cat /var/run/nginx.pid` + fi + endscript +} + +# System logs +/var/log/syslog { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0644 syslog adm + postrotate + /usr/lib/rsyslog/rsyslog-rotate + endscript +} + +/var/log/mail.info +/var/log/mail.warn +/var/log/mail.err +/var/log/mail.log +/var/log/daemon.log +/var/log/kern.log +/var/log/auth.log +/var/log/user.log +/var/log/lpr.log +/var/log/cron.log +/var/log/debug +/var/log/messages { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0644 syslog adm + sharedscripts + postrotate + /usr/lib/rsyslog/rsyslog-rotate + endscript +} + +# Fail2ban logs +/var/log/fail2ban.log { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0644 root root + postrotate + systemctl reload fail2ban + endscript +} + +# Docker daemon logs +/var/log/docker.log { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0644 root root + postrotate + systemctl reload docker + endscript +} + +# Prometheus node exporter logs +/var/log/prometheus-node-exporter.log { + daily + missingok + rotate 7 + compress + delaycompress + notifempty + create 0644 prometheus prometheus + postrotate + systemctl reload prometheus-node-exporter + endscript +} diff --git a/infra/nginx/AUTH_SETUP.md b/infra/nginx/AUTH_SETUP.md new file mode 100644 index 0000000..80fe4be --- /dev/null +++ b/infra/nginx/AUTH_SETUP.md @@ -0,0 +1,104 @@ +# Настройка авторизации для мониторинга + +## Обзор + +Добавлена HTTP Basic Authentication для следующих сервисов: +- **Prometheus** (`/prometheus/`) - метрики и мониторинг +- **Alertmanager** (`/alerts/` и `/api/v1/`) - управление алертами + +## Управление паролями + +### Автоматическая настройка через Ansible + +При развертывании через Ansible пароли настраиваются автоматически: + +```bash +# Использовать пароли по умолчанию +ansible-playbook -i inventory.ini playbook.yml + +# Задать свои пароли +ansible-playbook -i inventory.ini playbook.yml \ + -e monitoring_username=myuser \ + -e monitoring_password=mypassword +``` + +### Ручная настройка + +1. **Создать файл паролей:** +```bash +sudo mkdir -p /etc/nginx/passwords +sudo htpasswd -c /etc/nginx/passwords/monitoring.htpasswd admin +``` + +2. **Добавить дополнительных пользователей:** +```bash +sudo htpasswd /etc/nginx/passwords/monitoring.htpasswd username +``` + +3. **Установить правильные права:** +```bash +sudo chown root:www-data /etc/nginx/passwords/monitoring.htpasswd +sudo chmod 640 /etc/nginx/passwords/monitoring.htpasswd +``` + +4. **Перезапустить nginx:** +```bash +sudo systemctl reload nginx +``` + +### Использование скрипта генерации + +```bash +# Сгенерировать пароль для пользователя admin +sudo /usr/local/bin/generate_auth_passwords.sh admin + +# Сгенерировать пароль для другого пользователя +sudo /usr/local/bin/generate_auth_passwords.sh myuser +``` + +## Доступ к сервисам + +После настройки авторизации доступ к сервисам: + +- **Prometheus**: `https://your-server/prometheus/` +- **Alertmanager**: `https://your-server/alerts/` +- **Alertmanager API**: `https://your-server/api/v1/` + +При первом обращении браузер запросит логин и пароль. + +## Health Check endpoints + +Следующие endpoints остаются доступными без авторизации для мониторинга: + +- `https://your-server/prometheus/-/healthy` - проверка состояния Prometheus +- `https://your-server/nginx-health` - проверка состояния nginx + +## Безопасность + +- Пароли хранятся в зашифрованном виде в файле `/etc/nginx/passwords/monitoring.htpasswd` +- Файл доступен только для чтения пользователю root и группе www-data +- Используется HTTPS для всех соединений +- Настроена защита от брутфорса через fail2ban + +## Устранение проблем + +### Проверка конфигурации nginx +```bash +sudo nginx -t +``` + +### Проверка файла паролей +```bash +sudo cat /etc/nginx/passwords/monitoring.htpasswd +``` + +### Проверка логов nginx +```bash +sudo tail -f /var/log/nginx/error.log +sudo tail -f /var/log/nginx/access.log +``` + +### Сброс пароля +```bash +sudo htpasswd /etc/nginx/passwords/monitoring.htpasswd admin +``` diff --git a/infra/nginx/conf.d/alertmanager.conf b/infra/nginx/conf.d/alertmanager.conf index 98ac5c5..73763a8 100644 --- a/infra/nginx/conf.d/alertmanager.conf +++ b/infra/nginx/conf.d/alertmanager.conf @@ -1,8 +1,12 @@ # Alertmanager Nginx Configuration # Proxies requests to Alertmanager -# Alertmanager location +# Alertmanager location with authentication location /alerts/ { + # HTTP Basic Authentication + auth_basic "Alertmanager Monitoring"; + auth_basic_user_file /etc/nginx/passwords/monitoring.htpasswd; + # Rate limiting limit_req zone=api burst=10 nodelay; @@ -31,8 +35,12 @@ location /alerts/ { add_header X-Content-Type-Options "nosniff" always; } -# Alertmanager API +# Alertmanager API with authentication location /api/v1/ { + # HTTP Basic Authentication + auth_basic "Alertmanager API"; + auth_basic_user_file /etc/nginx/passwords/monitoring.htpasswd; + # Rate limiting limit_req zone=api burst=20 nodelay; diff --git a/infra/nginx/conf.d/prometheus.conf b/infra/nginx/conf.d/prometheus.conf index c189cd7..c23689e 100644 --- a/infra/nginx/conf.d/prometheus.conf +++ b/infra/nginx/conf.d/prometheus.conf @@ -1,7 +1,14 @@ -# Prometheus proxy configuration +# Prometheus proxy configuration with authentication location /prometheus/ { - proxy_pass http://prometheus_backend/; - proxy_redirect / /prometheus/; + # HTTP Basic Authentication + auth_basic "Prometheus Monitoring"; + auth_basic_user_file /etc/nginx/passwords/monitoring.htpasswd; + + # Rate limiting + limit_req zone=api burst=10 nodelay; + + proxy_pass http://prometheus_backend/prometheus/; + proxy_redirect /prometheus/ /prometheus/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; @@ -23,7 +30,7 @@ location /prometheus/ { # Health check endpoint location /prometheus/-/healthy { - proxy_pass http://prometheus_backend/-/healthy; + proxy_pass http://prometheus_backend/prometheus/-/healthy; proxy_set_header Host $host; access_log off; } \ No newline at end of file diff --git a/infra/uptime-kuma/README.md b/infra/uptime-kuma/README.md new file mode 100644 index 0000000..575c71a --- /dev/null +++ b/infra/uptime-kuma/README.md @@ -0,0 +1,77 @@ +# Uptime Kuma Configuration + +Uptime Kuma - это статусная страница для мониторинга доступности сервисов. + +## Доступ + +- **Веб-интерфейс**: `https://your-domain/status/` +- **Прямой доступ**: `http://localhost:3001` (только локально) + +## Настройка + +### Первоначальная настройка + +1. Запустите сервисы: + ```bash + make up + ``` + +2. Откройте `https://your-domain/status/` + +3. Создайте администратора: + - Username: `admin` + - Password: `admin` (смените после первого входа) + +### Мониторинг сервисов + +Uptime Kuma автоматически настроит мониторинг следующих сервисов: + +- **Telegram Bot**: `http://telegram-bot:8080/health` +- **AnonBot**: `http://anon-bot:8081/health` +- **Prometheus**: `http://prometheus:9090/-/healthy` +- **Grafana**: `http://grafana:3000/api/health` +- **AlertManager**: `http://alertmanager:9093/-/healthy` +- **Nginx**: `http://nginx:80/nginx-health` + +### Уведомления + +Настройте уведомления в веб-интерфейсе: +- Telegram Bot +- Email +- Webhook +- Discord +- Slack + +## Файлы конфигурации + +- `monitors.json` - экспорт настроенных мониторов +- `settings.json` - настройки приложения +- `backup/` - резервные копии конфигурации + +## Команды управления + +```bash +# Показать логи +make logs-uptime-kuma + +# Перезапустить +make restart-uptime-kuma + +# Проверить статус +make status +``` + +## Резервное копирование + +Конфигурация сохраняется в Docker volume `uptime_kuma_data`. +Для резервного копирования: + +```bash +# Создать backup +make backup + +# Восстановить +make restore FILE=backup.tar.gz +``` + + diff --git a/infra/uptime-kuma/backup/README.md b/infra/uptime-kuma/backup/README.md new file mode 100644 index 0000000..4b21c9f --- /dev/null +++ b/infra/uptime-kuma/backup/README.md @@ -0,0 +1,36 @@ +# Uptime Kuma Backup + +Эта директория содержит резервные копии конфигурации Uptime Kuma. + +## Автоматическое резервное копирование + +Создайте скрипт для автоматического бэкапа: + +```bash +#!/bin/bash +# backup-uptime-kuma.sh + +DATE=$(date +%Y%m%d-%H%M%S) +BACKUP_DIR="/path/to/backups" +CONTAINER_NAME="bots_uptime_kuma" + +# Создать backup +docker exec $CONTAINER_NAME tar -czf /tmp/uptime-kuma-backup-$DATE.tar.gz /app/data + +# Скопировать backup на хост +docker cp $CONTAINER_NAME:/tmp/uptime-kuma-backup-$DATE.tar.gz $BACKUP_DIR/ + +# Очистить временные файлы +docker exec $CONTAINER_NAME rm /tmp/uptime-kuma-backup-$DATE.tar.gz + +echo "Backup created: $BACKUP_DIR/uptime-kuma-backup-$DATE.tar.gz" +``` + +## Восстановление + +```bash +# Восстановить из backup +docker cp backup-file.tar.gz $CONTAINER_NAME:/tmp/ +docker exec $CONTAINER_NAME tar -xzf /tmp/backup-file.tar.gz -C / +docker restart $CONTAINER_NAME +``` diff --git a/infra/uptime-kuma/docker-compose.yml b/infra/uptime-kuma/docker-compose.yml deleted file mode 100644 index 1e7398f..0000000 --- a/infra/uptime-kuma/docker-compose.yml +++ /dev/null @@ -1,33 +0,0 @@ -# Uptime Kuma Configuration -# This is a separate docker-compose file for Uptime Kuma -# It will be included in the main docker-compose.yml - -version: '3.8' - -services: - uptime-kuma: - image: louislam/uptime-kuma:latest - container_name: bots_uptime_kuma - restart: unless-stopped - volumes: - - uptime_kuma_data:/app/data - ports: - - "3001:3001" - environment: - - UPTIME_KUMA_PORT=3001 - networks: - - bots_network - healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3001"] - interval: 30s - timeout: 10s - retries: 3 - start_period: 40s - -volumes: - uptime_kuma_data: - driver: local - -networks: - bots_network: - external: true diff --git a/infra/uptime-kuma/monitors.json b/infra/uptime-kuma/monitors.json new file mode 100644 index 0000000..fdfdddf --- /dev/null +++ b/infra/uptime-kuma/monitors.json @@ -0,0 +1,147 @@ +{ + "monitors": [ + { + "id": 1, + "name": "Telegram Bot Health", + "url": "http://telegram-bot:8080/health", + "type": "http", + "method": "GET", + "interval": 60, + "retries": 3, + "timeout": 10, + "keyword": null, + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["bot", "telegram", "health"], + "description": "Мониторинг состояния Telegram Helper Bot", + "active": true + }, + { + "id": 2, + "name": "AnonBot Health", + "url": "http://anon-bot:8081/health", + "type": "http", + "method": "GET", + "interval": 60, + "retries": 3, + "timeout": 10, + "keyword": null, + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["bot", "anon", "health"], + "description": "Мониторинг состояния AnonBot", + "active": true + }, + { + "id": 3, + "name": "Prometheus Health", + "url": "http://prometheus:9090/-/healthy", + "type": "http", + "method": "GET", + "interval": 60, + "retries": 3, + "timeout": 10, + "keyword": null, + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["monitoring", "prometheus", "health"], + "description": "Мониторинг состояния Prometheus", + "active": true + }, + { + "id": 4, + "name": "Grafana Health", + "url": "http://grafana:3000/api/health", + "type": "http", + "method": "GET", + "interval": 60, + "retries": 3, + "timeout": 10, + "keyword": null, + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["monitoring", "grafana", "health"], + "description": "Мониторинг состояния Grafana", + "active": true + }, + { + "id": 5, + "name": "AlertManager Health", + "url": "http://alertmanager:9093/-/healthy", + "type": "http", + "method": "GET", + "interval": 60, + "retries": 3, + "timeout": 10, + "keyword": null, + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["monitoring", "alertmanager", "health"], + "description": "Мониторинг состояния AlertManager", + "active": true + }, + { + "id": 6, + "name": "Nginx Health", + "url": "http://nginx:80/nginx-health", + "type": "http", + "method": "GET", + "interval": 60, + "retries": 3, + "timeout": 10, + "keyword": "healthy", + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["infrastructure", "nginx", "health"], + "description": "Мониторинг состояния Nginx", + "active": true + }, + { + "id": 7, + "name": "External Bot Status", + "url": "https://your-domain/status/", + "type": "http", + "method": "GET", + "interval": 300, + "retries": 2, + "timeout": 15, + "keyword": null, + "maxredirects": 10, + "ignoreTls": false, + "upsideDown": false, + "tags": ["external", "status-page"], + "description": "Мониторинг внешней доступности статусной страницы", + "active": false + } + ], + "tags": [ + { + "name": "bot", + "color": "#3498db" + }, + { + "name": "monitoring", + "color": "#e74c3c" + }, + { + "name": "infrastructure", + "color": "#f39c12" + }, + { + "name": "health", + "color": "#27ae60" + }, + { + "name": "external", + "color": "#9b59b6" + } + ] +} + + diff --git a/infra/uptime-kuma/settings.json b/infra/uptime-kuma/settings.json new file mode 100644 index 0000000..ca96afe --- /dev/null +++ b/infra/uptime-kuma/settings.json @@ -0,0 +1,24 @@ +{ + "language": "ru", + "theme": "light", + "timezone": "Europe/Moscow", + "dateLocale": "ru", + "dateFormat": "YYYY-MM-DD HH:mm:ss", + "timeFormat": "24", + "weekStart": 1, + "searchEngineIndex": true, + "primaryBaseURL": "https://your-domain/status/", + "public": true, + "publicGroupList": true, + "showTags": true, + "showPoweredBy": false, + "keepDataPeriodDays": 365, + "retentionCheckInterval": 3600, + "maxmindLicenseKey": "", + "dnsCache": true, + "dnsCacheTtl": 300, + "trustProxy": true, + "disableAuth": false, + "defaultTimezone": "Europe/Moscow", + "defaultLanguage": "ru" +} diff --git a/scripts/generate_auth_passwords.sh b/scripts/generate_auth_passwords.sh new file mode 100755 index 0000000..f7d6e20 --- /dev/null +++ b/scripts/generate_auth_passwords.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +# Script to generate HTTP Basic Auth passwords for monitoring services +# Usage: ./generate_auth_passwords.sh [username] + +set -e + +# Default username if not provided +USERNAME=${1:-"admin"} + +# Create passwords directory if it doesn't exist +PASSWORDS_DIR="/etc/nginx/passwords" +mkdir -p "$PASSWORDS_DIR" + +# Generate random password +PASSWORD=$(openssl rand -base64 32 | tr -d "=+/" | cut -c1-25) + +# Create htpasswd file +echo "Creating password file for user: $USERNAME" +htpasswd -cb "$PASSWORDS_DIR/monitoring.htpasswd" "$USERNAME" "$PASSWORD" + +# Set proper permissions +chown root:www-data "$PASSWORDS_DIR/monitoring.htpasswd" +chmod 640 "$PASSWORDS_DIR/monitoring.htpasswd" + +echo "Password file created: $PASSWORDS_DIR/monitoring.htpasswd" +echo "Username: $USERNAME" +echo "Password: $PASSWORD" +echo "" +echo "Save this password securely!" +echo "You can add more users with: htpasswd $PASSWORDS_DIR/monitoring.htpasswd "