From 3e42a507cf75142e0ef3bc39298701f3423dacf8 Mon Sep 17 00:00:00 2001 From: Administrator Date: Wed, 1 Apr 2026 15:16:42 +0500 Subject: [PATCH] Update file 10-security.md --- docs/10-security.md | 156 +++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/docs/10-security.md b/docs/10-security.md index 4b4f1ff..09e4979 100644 --- a/docs/10-security.md +++ b/docs/10-security.md @@ -4,8 +4,8 @@ В этом разделе собраны текущие проблемы безопасности инфраструктуры и план их устранения. Документ основан на результатах аудита, проведённого в марте 2026 года. -> **Последнее обновление**: 24 марта 2026 -> **Применено на хостах**: `torrent` (192.168.1.211) +> **Последнее обновление**: 1 апреля 2026 +> **Применено на хостах**: `torrent` (192.168.1.211), `Olimp` (Proxmox VE) > **В процессе**: применение на остальных хостах --- @@ -26,7 +26,7 @@ | Docker-образы | 🟡 | Используется тег `latest` на части сервисов | | Обновления систем | 🟡 | Требуют периодического применения | | Мониторинг | ✅ | Node Exporter, Promtail, VictoriaMetrics настроены | -| Резервное копирование | 🔴 | Не настроено (будет описано в разделе 11) | +| Резервное копирование | ✅ | **Proxmox Backup Server настроен и протестирован** | --- @@ -42,15 +42,9 @@ - Применено через Ansible на хосте `torrent` - **Проверка**: ```bash -# Проверка подключения под zailon -ssh zailon@192.168.1.211 # ✅ Работает - -# Проверка запрета root -ssh root@192.168.1.211 # ❌ Permission denied (publickey) - -# Проверка конфигурации SSH +ssh zailon@192.168.1.211 +ssh root@192.168.1.211 grep PermitRootLogin /etc/ssh/sshd_config -# Ожидаемый вывод: PermitRootLogin no ``` - **Статус**: ✅ Применено на `torrent`, готовится применение на остальных хостах @@ -63,34 +57,30 @@ grep PermitRootLogin /etc/ssh/sshd_config - В `all.yml` остались только публичные переменные - **Список зашифрованных переменных**: ```yaml -# vault.yml (зашифрован) -vault_zailon_password: "..." # Пароль администратора -vault_grafana_admin_password: "..." # Grafana -vault_gitlab_root_password: "..." # GitLab -vault_bitwarden_admin_token: "..." # Bitwarden -vault_bitwarden_smtp_password: "..." # Bitwarden SMTP -vault_mealie_db_password: "..." # Mealie DB -vault_flibusta_db_password: "..." # Flibusta DB -vault_immich_db_password: "..." # Immich DB -vault_mumble_server_password: "..." # Mumble -vault_mumble_superuser_password: "..." # Mumble superuser -vault_matrix_postgres_password: "..." # Matrix/Synapse -vault_matrix_synapse_secret: "..." # Matrix secrets +vault_zailon_password: "..." +vault_grafana_admin_password: "..." +vault_gitlab_root_password: "..." +vault_bitwarden_admin_token: "..." +vault_bitwarden_smtp_password: "..." +vault_mealie_db_password: "..." +vault_flibusta_db_password: "..." +vault_immich_db_password: "..." +vault_mumble_server_password: "..." +vault_mumble_superuser_password: "..." +vault_matrix_postgres_password: "..." +vault_matrix_synapse_secret: "..." vault_matrix_macaroon_secret: "..." vault_matrix_form_secret: "..." vault_matrix_admin_password: "..." -vault_snikket_admin_password: "..." # Snikket XMPP +vault_snikket_admin_password: "..." vault_snikket_invite_token: "..." -vault_smb_olimp_password: "..." # SMB shares +vault_smb_olimp_password: "..." vault_samba_password_qb: "..." -vault_pve_exporter_token: "..." # Proxmox exporter +vault_pve_exporter_token: "..." ``` - **Запуск playbook с vault**: ```bash -# Интерактивный ввод пароля ansible-playbook -i inventories/hosts olimp-deploy.yml --ask-vault-pass - -# Или через файл с паролем echo "your_vault_password" > ~/.vault_pass chmod 600 ~/.vault_pass ansible-playbook -i inventories/hosts olimp-deploy.yml --vault-password-file ~/.vault_pass @@ -104,12 +94,53 @@ ansible-playbook -i inventories/hosts olimp-deploy.yml --vault-password-file ~/. - В `/etc/samba/smb.conf` на хосте `media` изменено: ```ini [global] - server min protocol = smb2 # было: NT1 - smb encrypt = desired # оставлено для совместимости с клиентами + server min protocol = smb2 + smb encrypt = desired ``` - Проверена работа клиентов (Windows, Android, Docker) - **Статус**: ✅ Завершено на `media` +### 4. Резервное копирование не было настроено — ИСПРАВЛЕНО + +- **Описание**: Отсутствовала автоматическая система резервного копирования конфигураций, баз данных и пользовательских данных. +- **Что сделано** (апрель 2026): + - **Установлен Proxmox Backup Server** (PBS) в LXC контейнере (CT 220) + - **Создано хранилище** на ZFS dataset `rpool/pbs-backups` (187 GB, SSD mirror) + - **Настроено хранилище** `ssd-backups` с дедупликацией и компрессией ZSTD + - **PBS подключён** к Proxmox VE как `pbs-ssd` + - **Настроены бэкапы** для критичных систем: + - LXC контейнеры: 201-211 (gateway, data, media, photo, talk, games, manage, git, ansible, torrent) + - VM: 205 (Nextcloud), 213 (VPN) + - **Расписание**: ежедневно в 02:30 и 22:30 + - **Retention политика**: Keep Last 7, Keep Daily 7, Keep Weekly 2 + - **Режим**: Snapshot (без остановки сервисов) + - **Исключены** большие диски (16TB RAID6 массив) + - **Восстановление протестировано**: CT 201 → CT 216 (успешно) +- **Архитектура**: +``` +Proxmox VE Host (Olimp) +├─ ZFS Pool: rpool (2x240GB SSD mirror) +│ └─ Dataset: rpool/pbs-backups (187 GB) +│ └─ Mounted to: /rpool/pbs-backups +│ +└─ LXC Container (CT 220) - Proxmox Backup Server + └─ Mount: /mnt/backups → /rpool/pbs-backups + └─ Datastore: ssd-backups +``` +- **Команды управления**: +```bash +zfs list rpool/pbs-backups +zpool list rpool +pct exec 220 -- proxmox-backup-client datastore stats ssd-backups +``` +- **Восстановление**: +```bash +pct restore pbs-ssd:backup/ct// +qm restore pbs-ssd:backup/vm// +``` +- **Статус**: ✅ Работает, требует мониторинга места +- **Примечание**: PBS развёрнут на том же хосте что и Proxmox VE (временное решение до появления отдельного сервера). Рекомендуется настроить репликацию на внешний носитель или облако. + --- ## 🔴 Критические проблемы (требуют внимания) @@ -119,7 +150,6 @@ ansible-playbook -i inventories/hosts olimp-deploy.yml --vault-password-file ~/. - **Описание**: UFW отключён на всех LXC-контейнерах. Сервисы доступны из всей локальной сети без ограничений. - **Решение**: Включить UFW на каждом хосте с минимально необходимыми правилами: ```yaml -# Пример роли ufw_setup/tasks/main.yml - name: Enable UFW with default deny ufw: state: enabled @@ -134,8 +164,8 @@ ansible-playbook -i inventories/hosts olimp-deploy.yml --vault-password-file ~/. proto: tcp from: "{{ item }}" loop: - - "192.168.1.0/24" # LAN - - "192.168.45.0/24" # OpenVPN + - "192.168.1.0/24" + - "192.168.45.0/24" become: yes - name: Allow Samba from trusted subnets @@ -143,14 +173,10 @@ ansible-playbook -i inventories/hosts olimp-deploy.yml --vault-password-file ~/. rule: allow port: "{{ item }}" proto: tcp - from: "{{ from_item }}" + from: "192.168.1.0/24" loop: - 139 - 445 - loop_control: - loop_var: port - vars: - from_item: "192.168.1.0/24" become: yes - name: Allow HTTP/HTTPS for NPM @@ -171,7 +197,6 @@ ansible-playbook -i inventories/hosts olimp-deploy.yml --vault-password-file ~/. - **Описание**: Для публичных прокси не настроены заголовки безопасности: HSTS, X-Content-Type-Options, X-Frame-Options. - **Решение**: Через веб-интерфейс NPM → Proxy Hosts → Edit → Advanced → Custom locations добавить: ```nginx -# Security headers add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; @@ -182,12 +207,6 @@ add_header Content-Security-Policy "default-src 'self'" always; - **Применить ко всем публичным доменам**: `*.zailon.ru` - **Срок**: В течение недели -### 3. Резервное копирование не настроено - -- **Описание**: Нет автоматического бэкапа конфигураций, баз данных и пользовательских данных. -- **Решение**: Описано в разделе [11. Резервное копирование](11-backup.md) -- **Срок**: В течение 2 недель - --- ## 🟠 Проблемы высокого приоритета @@ -197,15 +216,9 @@ add_header Content-Security-Policy "default-src 'self'" always; - **Описание**: Образы обновляются неконтролируемо, что может привести к несовместимости. - **Решение**: Зафиксировать версии в `docker-compose.yml`: ```yaml -# Было: services: npm: - image: jc21/nginx-proxy-manager:latest - -# Стало: -services: - npm: - image: jc21/nginx-proxy-manager:2.12.3 # Зафиксированная версия + image: jc21/nginx-proxy-manager:2.12.3 ``` - **План**: Пройтись по всем `docker-compose.yml` и зафиксировать версии - **Срок**: В течение месяца @@ -214,10 +227,9 @@ services: - **Описание**: На хостах накапливаются обновления пакетов. - **Решение**: - - Регулярно запускать `apt update && apt upgrade` через Ansible (уже реализовано в роли `base_setup`) + - Регулярно запускать `apt update && apt upgrade` через Ansible - Настроить `unattended-upgrades` для автоматических обновлений безопасности ```yaml -# Пример задачи для unattended-upgrades - name: Install unattended-upgrades apt: name: unattended-upgrades @@ -233,8 +245,6 @@ services: }; Unattended-Upgrade::Automatic-Reboot "false"; dest: /etc/apt/apt.conf.d/50unattended-upgrades - owner: root - mode: '0644' become: yes ``` - **Статус**: 🟡 В процессе @@ -258,11 +268,8 @@ services: - **Описание**: Нет правил для оповещения при ошибках в логах. - **Решение**: Настроить правила в Grafana → Alerting на основе Loki: ```logql -# Пример: алерт на ошибки в логах SSH {job="promtail", filename="/var/log/auth.log"} |= "Failed password" | rate() > 5 - -# Пример: алерт на ошибки в логах NPM -{job="promtail", container="nginx-proxy-manager"} |= "error" | level="error" +{job="promtail", container="nginx-proxy-manager"} |= "error" ``` - **Статус**: 🟡 В планах @@ -283,6 +290,7 @@ services: | Мониторинг роутера | Сбор SNMP-метрик с TP-Link | 🟢 | | Двухфакторная аутентификация | Включить 2FA в Grafana, GitLab, Bitwarden | 🟢 | | Регулярный аудит | Запускать Lynis/OpenVAS раз в 3 месяца | 🟢 | +| Оффсайт-бэкапы | Настроить репликацию PBS в облако (Backblaze B2/Wasabi) | 🟢 | --- @@ -293,10 +301,10 @@ services: | Применить настройку SSH (root+zailon) на всех хостах | 🔴 | 1 день | 🔄 В процессе | | Включить UFW на всех хостах | 🔴 | 1 неделя | ⏳ Ожидает | | Добавить заголовки безопасности в NPM | 🔴 | 1 неделя | ⏳ Ожидает | -| Настроить резервное копирование | 🔴 | 2 недели | ⏳ Ожидает | | Зафиксировать версии Docker-образов | 🟠 | 1 месяц | ⏳ Ожидает | | Настроить unattended-upgrades | 🟢 | 1 месяц | ⏳ Ожидает | | Настроить алерты на логи | 🟡 | По необходимости | ⏳ Ожидает | +| Настроить репликацию PBS (оффсайт) | 🟢 | 2 месяца | ⏳ Ожидает | --- @@ -305,22 +313,11 @@ services: Перед запуском playbook на всех хостах: ```bash -# 1. Проверка прав на SSH-ключ Ansible chmod 600 /root/.ssh/id_rsa - -# 2. Проверка vault ansible-vault view vault.yml --ask-vault-pass | grep zailon - -# 3. Dry-run на одном хосте ansible-playbook -i inventories/hosts olimp-deploy.yml -l torrent --check --diff --ask-vault-pass - -# 4. Применение на одном хосте ansible-playbook -i inventories/hosts olimp-deploy.yml -l torrent --ask-vault-pass - -# 5. Тест подключения под zailon (в НОВОМ окне!) ssh zailon@192.168.1.211 - -# 6. Если всё ок — применяем на всех ansible-playbook -i inventories/hosts olimp-deploy.yml --ask-vault-pass ``` @@ -328,6 +325,17 @@ ansible-playbook -i inventories/hosts olimp-deploy.yml --ask-vault-pass --- +## 📊 Мониторинг безопасности + +```bash +zfs list rpool/pbs-backups +zpool list rpool +pct exec 220 -- proxmox-backup-client datastore stats ssd-backups +pct exec 220 -- df -h /mnt/backups +``` + +--- + **Связанные разделы**: - [05. Samba – файловые шары](05-samba.md) - [07. Проксирование и SSL (NPM)](07-proxy-ssl.md)