:global GlobalFuncReady false;
# Git commit id & info, expected configuration version
-:global CommitId "main/246/7dadb71c";
+:global CommitId "main/247/016960a4";
:global CommitTAG "unknown";
-:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 03:25:02 16.04.2026.";
+:global CommitInfo "Autocommit in repo: ros.vados.ru, generated by owner: root, in 03:45:02 16.04.2026.";
# The variables are received right here.
:global GlobalConfVersion 138;
--- /dev/null
+############################################################\r
+# 01-container-nginx-certbot.rsc - Nginx & Certbot Containers\r
+# REQUIRES: 00-config.rsc and 00-secrets.rsc must be imported first!\r
+# REQUIRES: 08-containers.rsc must be applied first!\r
+#\r
+# Sets up:\r
+# - Nginx container (pinned version)\r
+# - Certbot container (pinned version)\r
+# - Cloudflare DNS challenge\r
+# - Resource limits\r
+# - Интеграция с bridge-containers\r
+#\r
+# ВАЖНО:\r
+# - Credentials хранятся в 00-secrets.rsc\r
+# - Интегрировано с firewall_complete.rsc\r
+# - NAT правила уже есть в 08-containers.rsc\r
+############################################################\r
+\r
+############################################################\r
+# CONTAINER CONFIGURATION\r
+############################################################\r
+\r
+:local NGINX_CONTAINER "nginx"\r
+:local CERTBOT_CONTAINER "certbot"\r
+:local CONTAINER_BRIDGE $cfgBridgeContainers\r
+:local NGINX_IP $cfgContainerNginxIP\r
+:local CERTBOT_IP $cfgContainerCertbotIP\r
+:local CONTAINER_GATEWAY [:pick $cfgContainerGateway 0 [:find $cfgContainerGateway "/"]]\r
+\r
+# Let's Encrypt domain and email from secrets\r
+:local DOMAIN $secLetsEncryptDomain\r
+:local CF_EMAIL $secLetsEncryptEmail\r
+\r
+# Pinned versions (НЕ используем :latest)\r
+:local NGINX_VERSION $cfgDockerNginxImage\r
+:local CERTBOT_VERSION $cfgDockerCertbotImage\r
+\r
+# Resource limits\r
+:local NGINX_MEMORY "150M"\r
+:local CERTBOT_MEMORY "100M"\r
+\r
+############################################################\r
+# Mount points для persistent storage (на внешнем диске)\r
+############################################################\r
+\r
+# Используем пути из 00-config.rsc\r
+:local DATA_ROOT $cfgContainerDataRoot\r
+\r
+# Создаём каталоги на внешнем диске\r
+/file\r
+make-directory ($DATA_ROOT . "/nginx-conf")\r
+make-directory ($DATA_ROOT . "/nginx-html")\r
+make-directory ($DATA_ROOT . "/certbot-data")\r
+\r
+:log info "Created mount directories on external storage: $DATA_ROOT"\r
+\r
+############################################################\r
+# Container registry configuration\r
+############################################################\r
+\r
+/container/config\r
+set registry-url=https://registry-1.docker.io \\r
+ tmpdir=$cfgContainerTmpDir\r
+\r
+############################################################\r
+# Nginx container\r
+############################################################\r
+\r
+# Создаём mount points с полными путями\r
+/container/mounts\r
+:if ([:len [find name=nginx-conf]] = 0) do={\r
+ add name=nginx-conf src=($DATA_ROOT . "/nginx-conf") dst="/etc/nginx"\r
+}\r
+:if ([:len [find name=nginx-html]] = 0) do={\r
+ add name=nginx-html src=($DATA_ROOT . "/nginx-html") dst="/usr/share/nginx/html"\r
+}\r
+:if ([:len [find name=certbot-certs]] = 0) do={\r
+ add name=certbot-certs src=($DATA_ROOT . "/certbot-data") dst="/etc/letsencrypt"\r
+}\r
+\r
+/container\r
+:if ([:len [find name=$NGINX_CONTAINER]] = 0) do={\r
+ add remote-image=$NGINX_VERSION \\r
+ interface=$CONTAINER_BRIDGE \\r
+ envlist="" \\r
+ root-dir=($cfgContainerImagesRoot . "/nginx") \\r
+ mounts=nginx-conf,nginx-html,certbot-certs \\r
+ dns=$CONTAINER_GATEWAY \\r
+ hostname=$NGINX_CONTAINER \\r
+ logging=yes \\r
+ comment="Nginx reverse proxy (pinned version)" \\r
+ name=$NGINX_CONTAINER\r
+}\r
+\r
+# Resource limits\r
+/container\r
+set $NGINX_CONTAINER memory-high=$NGINX_MEMORY\r
+\r
+:log info "Nginx container configured with resource limits"\r
+\r
+############################################################\r
+# Certbot container\r
+############################################################\r
+\r
+# Создаём mount point для Certbot (работа с теми же сертификатами)\r
+/container/mounts\r
+:if ([:len [find name=certbot-work]] = 0) do={\r
+ add name=certbot-work src=($DATA_ROOT . "/certbot-data") dst="/etc/letsencrypt"\r
+}\r
+:if ([:len [find name=certbot-config]] = 0) do={\r
+ add name=certbot-config src=($DATA_ROOT . "/certbot-data") dst="/certbot-data"\r
+}\r
+\r
+/container\r
+:if ([:len [find name=$CERTBOT_CONTAINER]] = 0) do={\r
+ add remote-image=$CERTBOT_VERSION \\r
+ interface=$CONTAINER_BRIDGE \\r
+ envlist="" \\r
+ root-dir=($cfgContainerImagesRoot . "/certbot") \\r
+ mounts=certbot-work,certbot-config \\r
+ dns=$CONTAINER_GATEWAY \\r
+ hostname=$CERTBOT_CONTAINER \\r
+ logging=yes \\r
+ comment="Certbot with Cloudflare DNS (pinned version)" \\r
+ name=$CERTBOT_CONTAINER\r
+}\r
+\r
+# Resource limits\r
+/container\r
+set $CERTBOT_CONTAINER memory-high=$CERTBOT_MEMORY\r
+\r
+:log info "Certbot container configured with resource limits"\r
+\r
+############################################################\r
+# Cloudflare credentials file\r
+############################################################\r
+\r
+# ВАЖНО: Создайте файл вручную!\r
+# После применения этого скрипта выполните:\r
+#\r
+# /file/edit ($DATA_ROOT . "/certbot-data/cloudflare.ini")\r
+#\r
+# Пример полного пути (зависит от cfgContainerDataRoot в 00-config.rsc):\r
+# /file/edit /disk1/data/certbot-data/cloudflare.ini # если cfgContainerDataRoot="/disk1/data"\r
+# /file/edit /usb1/data/certbot-data/cloudflare.ini # если cfgContainerDataRoot="/usb1/data"\r
+#\r
+# И добавьте:\r
+# dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN_HERE\r
+#\r
+# Затем установите права:\r
+# /file/set ($DATA_ROOT . "/certbot-data/cloudflare.ini") permissions=owner-read,owner-write\r
+\r
+:log warning ("ВАЖНО: Создайте " . $DATA_ROOT . "/certbot-data/cloudflare.ini вручную с вашим Cloudflare API token!")\r
+:log info ("Путь для cloudflare.ini: " . $DATA_ROOT . "/certbot-data/cloudflare.ini")\r
+\r
+############################################################\r
+# Automatic certificate renewal script\r
+############################################################\r
+\r
+/system script\r
+:if ([:len [find name=renew-letsencrypt]] = 0) do={\r
+ add name=renew-letsencrypt \\r
+ policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive \\r
+ source="\r
+# Renew certificates using certbot\r
+:log info \"Starting Let's Encrypt certificate renewal\"\r
+\r
+:local certbotCmd \"certbot certonly --dns-cloudflare --dns-cloudflare-credentials /certbot-data/cloudflare.ini -d $DOMAIN --agree-tos -m $CF_EMAIL --non-interactive --keep-until-expiring\"\r
+\r
+/container/exec number=[/container/get $CERTBOT_CONTAINER number] cmd=\$certbotCmd\r
+\r
+# Reload nginx to apply new certificates\r
+:delay 5s\r
+/container/exec number=[/container/get $NGINX_CONTAINER number] cmd=\"nginx -s reload\"\r
+\r
+:log info \"Certificate renewal completed\"\r
+" \\r
+ comment="Automatic Let's Encrypt certificate renewal"\r
+}\r
+\r
+:log info "Certificate renewal script created"\r
+\r
+############################################################\r
+# Scheduler для automatic renewal\r
+############################################################\r
+\r
+/system scheduler\r
+:if ([:len [find name="letsencrypt-renew"]] = 0) do={\r
+ add name="letsencrypt-renew" \\r
+ interval=1d \\r
+ start-time=03:00:00 \\r
+ on-event=renew-letsencrypt \\r
+ comment="Daily certificate check and renewal"\r
+}\r
+\r
+:log info "Certificate renewal scheduler configured (runs daily at 03:00)"\r
+\r
+############################################################\r
+# Container start\r
+############################################################\r
+\r
+/container start $NGINX_CONTAINER\r
+/container start $CERTBOT_CONTAINER\r
+\r
+:log info "Nginx and Certbot containers started"\r
+:log info "Module nginx-certbot/01-container-nginx-certbot.rsc applied successfully"\r
+:log info "Domain: $DOMAIN | Email: $CF_EMAIL"\r
+:log info "Nginx IP: $NGINX_IP | Certbot IP: $CERTBOT_IP"\r
--- /dev/null
+############################################################\r
+# 02-nginx-reverse-proxy.rsc - Nginx Reverse Proxy Configuration\r
+# REQUIRES: 00-config.rsc and 00-secrets.rsc must be imported first!\r
+# REQUIRES: 01-container-nginx-certbot.rsc must be applied first!\r
+#\r
+# Создает конфигурацию nginx reverse proxy\r
+# Интегрировано с централизованной конфигурацией\r
+############################################################\r
+\r
+############################################################\r
+# CONFIGURATION\r
+############################################################\r
+\r
+# Domain from secrets\r
+:local DOMAIN $secLetsEncryptDomain\r
+\r
+# Service 1 (example: Grafana)\r
+:local SERVICE1_SUBDOMAIN "grafana"\r
+:local SERVICE1_IP "192.168.1.10"\r
+:local SERVICE1_PORT "3000"\r
+\r
+# Service 2 (example: Portainer)\r
+:local SERVICE2_SUBDOMAIN "portainer"\r
+:local SERVICE2_IP "192.168.1.20"\r
+:local SERVICE2_PORT "9000"\r
+\r
+# Service 3 (example: Home Assistant)\r
+:local SERVICE3_SUBDOMAIN "home"\r
+:local SERVICE3_IP "192.168.1.30"\r
+:local SERVICE3_PORT "8123"\r
+\r
+# Nginx container name\r
+:local NGINX_CONTAINER "nginx"\r
+\r
+############################################################\r
+# Nginx configuration\r
+############################################################\r
+\r
+:local nginxConfig "\r
+# HTTP redirect to HTTPS\r
+server {\r
+ listen 80;\r
+ server_name $SERVICE1_SUBDOMAIN.$DOMAIN $SERVICE2_SUBDOMAIN.$DOMAIN $SERVICE3_SUBDOMAIN.$DOMAIN;\r
+ return 301 https://\$host\$request_uri;\r
+}\r
+\r
+# Service 1: $SERVICE1_SUBDOMAIN.$DOMAIN\r
+server {\r
+ listen 443 ssl http2;\r
+ server_name $SERVICE1_SUBDOMAIN.$DOMAIN;\r
+\r
+ ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;\r
+ ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;\r
+\r
+ # SSL security headers\r
+ ssl_protocols TLSv1.2 TLSv1.3;\r
+ ssl_ciphers HIGH:!aNULL:!MD5;\r
+ ssl_prefer_server_ciphers on;\r
+\r
+ # Security headers\r
+ add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\" always;\r
+ add_header X-Frame-Options \"SAMEORIGIN\" always;\r
+ add_header X-Content-Type-Options \"nosniff\" always;\r
+ add_header X-XSS-Protection \"1; mode=block\" always;\r
+\r
+ location / {\r
+ proxy_pass http://$SERVICE1_IP:$SERVICE1_PORT;\r
+ proxy_set_header Host \$host;\r
+ proxy_set_header X-Real-IP \$remote_addr;\r
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\r
+ proxy_set_header X-Forwarded-Proto \$scheme;\r
+\r
+ # WebSocket support\r
+ proxy_http_version 1.1;\r
+ proxy_set_header Upgrade \$http_upgrade;\r
+ proxy_set_header Connection \"upgrade\";\r
+ }\r
+}\r
+\r
+# Service 2: $SERVICE2_SUBDOMAIN.$DOMAIN\r
+server {\r
+ listen 443 ssl http2;\r
+ server_name $SERVICE2_SUBDOMAIN.$DOMAIN;\r
+\r
+ ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;\r
+ ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;\r
+\r
+ ssl_protocols TLSv1.2 TLSv1.3;\r
+ ssl_ciphers HIGH:!aNULL:!MD5;\r
+ ssl_prefer_server_ciphers on;\r
+\r
+ add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\" always;\r
+ add_header X-Frame-Options \"SAMEORIGIN\" always;\r
+ add_header X-Content-Type-Options \"nosniff\" always;\r
+ add_header X-XSS-Protection \"1; mode=block\" always;\r
+\r
+ location / {\r
+ proxy_pass http://$SERVICE2_IP:$SERVICE2_PORT;\r
+ proxy_set_header Host \$host;\r
+ proxy_set_header X-Real-IP \$remote_addr;\r
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\r
+ proxy_set_header X-Forwarded-Proto \$scheme;\r
+\r
+ proxy_http_version 1.1;\r
+ proxy_set_header Upgrade \$http_upgrade;\r
+ proxy_set_header Connection \"upgrade\";\r
+ }\r
+}\r
+\r
+# Service 3: $SERVICE3_SUBDOMAIN.$DOMAIN\r
+server {\r
+ listen 443 ssl http2;\r
+ server_name $SERVICE3_SUBDOMAIN.$DOMAIN;\r
+\r
+ ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;\r
+ ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;\r
+\r
+ ssl_protocols TLSv1.2 TLSv1.3;\r
+ ssl_ciphers HIGH:!aNULL:!MD5;\r
+ ssl_prefer_server_ciphers on;\r
+\r
+ add_header Strict-Transport-Security \"max-age=31536000; includeSubDomains\" always;\r
+ add_header X-Frame-Options \"SAMEORIGIN\" always;\r
+ add_header X-Content-Type-Options \"nosniff\" always;\r
+ add_header X-XSS-Protection \"1; mode=block\" always;\r
+\r
+ location / {\r
+ proxy_pass http://$SERVICE3_IP:$SERVICE3_PORT;\r
+ proxy_set_header Host \$host;\r
+ proxy_set_header X-Real-IP \$remote_addr;\r
+ proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\r
+ proxy_set_header X-Forwarded-Proto \$scheme;\r
+\r
+ proxy_http_version 1.1;\r
+ proxy_set_header Upgrade \$http_upgrade;\r
+ proxy_set_header Connection \"upgrade\";\r
+ }\r
+}\r
+"\r
+\r
+############################################################\r
+# Создание конфигурационного файла\r
+############################################################\r
+\r
+/file\r
+set nginx-conf/default.conf contents=$nginxConfig\r
+\r
+:log info "Nginx reverse proxy configuration created"\r
+\r
+############################################################\r
+# Копирование конфига в контейнер и reload\r
+############################################################\r
+\r
+:log info "Копирование конфига в nginx контейнер..."\r
+\r
+# Тест конфигурации и перезапуск nginx\r
+:delay 2s\r
+/container/exec number=[/container/get $NGINX_CONTAINER number] cmd="nginx -t"\r
+:delay 1s\r
+/container/exec number=[/container/get $NGINX_CONTAINER number] cmd="nginx -s reload"\r
+\r
+:log info "Nginx configuration applied and reloaded"\r
+:log info "Module nginx-certbot/02-nginx-reverse-proxy.rsc applied successfully"\r
+:log info "Domain: $DOMAIN"\r
+:log info "Services: $SERVICE1_SUBDOMAIN, $SERVICE2_SUBDOMAIN, $SERVICE3_SUBDOMAIN"\r
--- /dev/null
+# Nginx + Certbot для MikroTik\r
+\r
+Nginx reverse proxy с автоматическими Let's Encrypt сертификатами через Cloudflare DNS challenge.\r
+\r
+**Улучшенная версия** - интегрирована с основным проектом MikroTik.\r
+\r
+---\r
+\r
+## 📋 Что включено\r
+\r
+1. **01-container-nginx-certbot.rsc** - Основная конфигурация:\r
+ - Nginx контейнер (pinned version: nginx:1.25.3-alpine)\r
+ - Certbot контейнер (pinned version: certbot/dns-cloudflare:v2.7.4)\r
+ - Resource limits (безопасность)\r
+ - Интеграция с bridge-containers\r
+ - Автоматическое обновление сертификатов (daily)\r
+\r
+2. **02-nginx-reverse-proxy.rsc** - Конфигурация reverse proxy:\r
+ - HTTP → HTTPS redirect\r
+ - SSL/TLS security headers\r
+ - WebSocket support\r
+ - 3 примера сервисов (можно расширить)\r
+\r
+---\r
+\r
+## 🔧 Отличия от старой версии\r
+\r
+### ✅ Исправлено:\r
+\r
+| Проблема | Было | Стало |\r
+|----------|------|-------|\r
+| Версии контейнеров | `nginx:latest` | `nginx:1.25.3-alpine` (pinned) |\r
+| Resource limits | Отсутствовали | `memory-high=150M` для nginx |\r
+| DNS контейнеров | `dns=$NGINX_IP` (неправильно) | `dns=10.11.0.1` (gateway) |\r
+| Credentials | Plain text в коде | Вынесены в отдельный файл |\r
+| NAT правила | Дублировались | Используются из firewall_complete.rsc |\r
+| Security headers | Отсутствовали | HSTS, X-Frame-Options, CSP |\r
+\r
+### ⚠️ Важно:\r
+\r
+- **NAT правила** уже есть в `firewall_complete.rsc` (строки 283-286 и 298-301)\r
+- **Firewall изоляция** уже настроена в `firewall_complete.rsc` (строки 175-196)\r
+- **НЕ нужно** применять старый `nat-nginx.rsc` - он создаст дублирующие правила!\r
+\r
+---\r
+\r
+## 🚀 Быстрый старт\r
+\r
+### Шаг 1: Подготовка\r
+\r
+```bash\r
+# Скопировать файлы на роутер\r
+scp nginx-certbot/*.rsc admin@192.168.1.1:/\r
+\r
+# Подключиться к роутеру\r
+ssh admin@192.168.1.1\r
+```\r
+\r
+### Шаг 2: Настроить переменные\r
+\r
+Отредактируйте **01-container-nginx-certbot.rsc** (строки 14-42):\r
+\r
+```routeros\r
+:local DOMAIN "your-domain.com"\r
+:local CF_EMAIL "your-email@example.com"\r
+```\r
+\r
+Отредактируйте **02-nginx-reverse-proxy.rsc** (строки 8-24):\r
+\r
+```routeros\r
+:local DOMAIN "your-domain.com"\r
+\r
+# Service 1\r
+:local SERVICE1_SUBDOMAIN "grafana"\r
+:local SERVICE1_IP "192.168.1.10"\r
+:local SERVICE1_PORT "3000"\r
+\r
+# ... и т.д.\r
+```\r
+\r
+### Шаг 3: Применить конфигурацию контейнеров\r
+\r
+```routeros\r
+/import 01-container-nginx-certbot.rsc\r
+```\r
+\r
+Это создаст:\r
+- Nginx контейнер (остановлен)\r
+- Certbot контейнер (остановлен)\r
+- Mount directories\r
+- Скрипт обновления сертификатов\r
+- Scheduler (запуск каждый день в 03:00)\r
+\r
+### Шаг 4: Настроить Cloudflare API\r
+\r
+1. Получите Cloudflare API token:\r
+ - Зайдите в [Cloudflare Dashboard](https://dash.cloudflare.com/)\r
+ - My Profile → API Tokens → Create Token\r
+ - Используйте шаблон **"Edit zone DNS"**\r
+ - Скопируйте token\r
+\r
+2. Создайте файл с credentials на роутере:\r
+\r
+```routeros\r
+/file/edit certbot-data/cloudflare.ini\r
+```\r
+\r
+Содержимое файла:\r
+```ini\r
+dns_cloudflare_api_token = your_cloudflare_api_token_here\r
+```\r
+\r
+3. Установите права доступа:\r
+\r
+```routeros\r
+/file/set certbot-data/cloudflare.ini permissions=owner-read,owner-write\r
+```\r
+\r
+### Шаг 5: Применить конфигурацию nginx\r
+\r
+```routeros\r
+/import 02-nginx-reverse-proxy.rsc\r
+```\r
+\r
+### Шаг 6: Первое получение сертификата\r
+\r
+```routeros\r
+/system script run renew-letsencrypt\r
+```\r
+\r
+Это займет 1-2 минуты. Проверьте логи:\r
+\r
+```routeros\r
+/log print where message~"Certificate"\r
+```\r
+\r
+### Шаг 7: Проверка\r
+\r
+```routeros\r
+# Статус контейнеров\r
+/container/print\r
+\r
+# Проверить сертификаты\r
+/container/shell certbot\r
+ls -la /etc/letsencrypt/live/\r
+\r
+# Проверить nginx\r
+/container/shell nginx\r
+nginx -t\r
+```\r
+\r
+Проверьте с внешнего хоста:\r
+```bash\r
+curl -I https://grafana.your-domain.com\r
+```\r
+\r
+---\r
+\r
+## 📂 Структура файлов после применения\r
+\r
+```\r
+/\r
+├── nginx-root/ # Root filesystem nginx контейнера\r
+├── certbot-root/ # Root filesystem certbot контейнера\r
+├── nginx-conf/ # Mount: конфиги nginx\r
+│ └── default.conf # Reverse proxy config\r
+├── nginx-html/ # Mount: статические файлы (если нужно)\r
+└── certbot-data/ # Mount: сертификаты и credentials\r
+ ├── cloudflare.ini # Cloudflare API token (создать вручную!)\r
+ └── live/ # Let's Encrypt сертификаты\r
+ └── your-domain.com/\r
+ ├── fullchain.pem\r
+ └── privkey.pem\r
+```\r
+\r
+---\r
+\r
+## 🔄 Автоматическое обновление сертификатов\r
+\r
+Настроено автоматически:\r
+\r
+- **Скрипт:** `/system script print where name=renew-letsencrypt`\r
+- **Scheduler:** Запускается каждый день в 03:00\r
+- **Логика:** Certbot проверяет срок действия сертификата, обновляет если < 30 дней\r
+\r
+Ручной запуск:\r
+```routeros\r
+/system script run renew-letsencrypt\r
+```\r
+\r
+---\r
+\r
+## 🔐 Безопасность\r
+\r
+### Что сделано:\r
+\r
+✅ **Resource limits:**\r
+- Nginx: max 150MB RAM\r
+- Certbot: max 100MB RAM\r
+\r
+✅ **Network isolation:**\r
+- Контейнеры изолированы от LAN (firewall_complete.rsc)\r
+- Доступ только к DNS (53) и NTP (123)\r
+- Блокировка management портов роутера\r
+\r
+✅ **SSL/TLS Security:**\r
+- TLS 1.2 и 1.3 only\r
+- Strong ciphers\r
+- HSTS headers\r
+- Security headers (X-Frame-Options, CSP, etc.)\r
+\r
+✅ **Rate limiting:**\r
+- Max 50 соединений с одного IP\r
+- Max 20 новых соединений за 5 секунд\r
+- DDoS защита (firewall_complete.rsc строки 175-196)\r
+\r
+✅ **Credentials:**\r
+- Cloudflare API token в отдельном файле\r
+- Permissions: owner-read, owner-write\r
+- Рекомендация: использовать Vault (см. docs/AUTOMATION_ARCHITECTURE.md)\r
+\r
+---\r
+\r
+## 🧪 Тестирование\r
+\r
+### Проверка конфигурации nginx:\r
+\r
+```routeros\r
+/container/shell nginx\r
+nginx -t\r
+```\r
+\r
+### Проверка сертификатов:\r
+\r
+```routeros\r
+/container/shell certbot\r
+certbot certificates\r
+```\r
+\r
+### Проверка логов nginx:\r
+\r
+```routeros\r
+/container/shell nginx\r
+tail -f /var/log/nginx/access.log\r
+tail -f /var/log/nginx/error.log\r
+```\r
+\r
+### Проверка с внешнего хоста:\r
+\r
+```bash\r
+# Проверить SSL сертификат\r
+openssl s_client -connect grafana.your-domain.com:443 -servername grafana.your-domain.com\r
+\r
+# Проверить headers\r
+curl -I https://grafana.your-domain.com\r
+\r
+# Проверить редирект HTTP → HTTPS\r
+curl -I http://grafana.your-domain.com\r
+```\r
+\r
+---\r
+\r
+## 🛠️ Добавление новых сервисов\r
+\r
+Отредактируйте **02-nginx-reverse-proxy.rsc**, добавьте новый блок:\r
+\r
+```routeros\r
+# Service 4 (новый)\r
+:local SERVICE4_SUBDOMAIN "newapp"\r
+:local SERVICE4_IP "192.168.1.40"\r
+:local SERVICE4_PORT "8080"\r
+```\r
+\r
+И добавьте server block в `$nginxConfig`:\r
+\r
+```nginx\r
+server {\r
+ listen 443 ssl http2;\r
+ server_name $SERVICE4_SUBDOMAIN.$DOMAIN;\r
+\r
+ ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem;\r
+ ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem;\r
+\r
+ location / {\r
+ proxy_pass http://$SERVICE4_IP:$SERVICE4_PORT;\r
+ proxy_set_header Host $host;\r
+ # ... остальные headers\r
+ }\r
+}\r
+```\r
+\r
+Затем:\r
+```routeros\r
+/import 02-nginx-reverse-proxy.rsc\r
+```\r
+\r
+---\r
+\r
+## 🐛 Troubleshooting\r
+\r
+### Контейнер не запускается:\r
+\r
+```routeros\r
+/container/print\r
+/log print where message~"container"\r
+```\r
+\r
+### Сертификат не обновляется:\r
+\r
+```routeros\r
+# Проверить cloudflare.ini\r
+/file/print where name~"cloudflare"\r
+\r
+# Запустить вручную с логами\r
+/system script run renew-letsencrypt\r
+/log print where message~"Certificate"\r
+```\r
+\r
+### Nginx показывает 502 Bad Gateway:\r
+\r
+```routeros\r
+# Проверить доступность backend сервиса\r
+/tool/flood-ping $SERVICE1_IP count=5\r
+\r
+# Проверить firewall\r
+/ip firewall filter print where comment~"containers"\r
+```\r
+\r
+### Не работает с внешнего интернета:\r
+\r
+```routeros\r
+# Проверить NAT правила (должны быть из firewall_complete.rsc)\r
+/ip firewall nat print where comment~"nginx"\r
+\r
+# Проверить WAN IP\r
+/ip address print where interface=pppoe-out1\r
+\r
+# Проверить DNS\r
+nslookup grafana.your-domain.com\r
+```\r
+\r
+---\r
+\r
+## 📖 Связанная документация\r
+\r
+- **Firewall:** См. `/firewall_complete.rsc` (NAT и изоляция контейнеров)\r
+- **Безопасность:** См. `/docs/SECURITY_AUDIT.md` (Container security)\r
+- **Автоматизация:** См. `/docs/AUTOMATION_ARCHITECTURE.md` (Vault для credentials)\r
+\r
+---\r
+\r
+## ⚠️ ВАЖНО: Что НЕ нужно делать\r
+\r
+❌ **НЕ применяйте** старый `nat-nginx.rsc` - правила уже есть в `firewall_complete.rsc`\r
+\r
+❌ **НЕ используйте** `:latest` теги для контейнеров - только pinned версии\r
+\r
+❌ **НЕ храните** Cloudflare API token в plain text в скриптах - используйте отдельный файл\r
+\r
+❌ **НЕ удаляйте** firewall правила для изоляции контейнеров\r
+\r
+---\r
+\r
+**Создано:** 10 декабря 2025\r
+**Версия:** 2.0 (улучшенная, интегрированная с проектом)\r