From b8b4269fe8cec468564cd31a7be09dc6524285ee Mon Sep 17 00:00:00 2001 From: Alex Date: Wed, 14 Jan 2026 21:10:15 +0300 Subject: [PATCH] =?UTF-8?q?=D0=B2=D0=B0=D1=88=D0=B5=20=D1=81=D0=BE=D0=BE?= =?UTF-8?q?=D0=B1=D1=89=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BC=D0=BC?= =?UTF-8?q?=D0=B8=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/routes/pages.js | 71 ++++++++++++++- docs-en/FAQ.md | 9 +- docs-en/service-terms.md | 1 + docs/FAQ.md | 9 +- docs/service-terms.md | 1 + frontend/nginx-local.conf | 19 ++++ frontend/nginx-simple.conf | 21 +++-- frontend/src/services/webSshService.js | 88 ++++++++++++++++--- .../src/views/content/PublishedPageView.vue | 1 + sync-to-vds.sh | 14 +-- webssh-agent/nginx-template.conf | 44 ++++++++-- 11 files changed, 239 insertions(+), 39 deletions(-) diff --git a/backend/routes/pages.js b/backend/routes/pages.js index 22070d7..162f26c 100644 --- a/backend/routes/pages.js +++ b/backend/routes/pages.js @@ -45,7 +45,12 @@ async function ensureAdminPagesTable(fields) { 'created_at TIMESTAMP DEFAULT NOW()', 'updated_at TIMESTAMP DEFAULT NOW()', 'show_in_blog BOOLEAN DEFAULT FALSE', // Показывать в блоге - 'slug TEXT UNIQUE' // URL-friendly идентификатор для SEO + 'slug TEXT UNIQUE', // URL-friendly идентификатор для SEO + 'category_id INTEGER', // ID категории + 'parent_id INTEGER', // ID родительской страницы + 'order_index INTEGER DEFAULT 0', // Порядок сортировки + 'nav_path TEXT', // Путь навигации + 'is_index_page BOOLEAN DEFAULT FALSE' // Является ли индексной страницей ]; for (const field of fields) { columns.push(`"${field}_encrypted" TEXT`); @@ -89,6 +94,41 @@ async function ensureAdminPagesTable(fields) { } } + // Добавляем поле category_id если его нет + if (!existingCols.includes('category_id')) { + await db.getQuery()( + `ALTER TABLE ${tableName} ADD COLUMN category_id INTEGER` + ); + } + + // Добавляем поле parent_id если его нет + if (!existingCols.includes('parent_id')) { + await db.getQuery()( + `ALTER TABLE ${tableName} ADD COLUMN parent_id INTEGER` + ); + } + + // Добавляем поле order_index если его нет + if (!existingCols.includes('order_index')) { + await db.getQuery()( + `ALTER TABLE ${tableName} ADD COLUMN order_index INTEGER DEFAULT 0` + ); + } + + // Добавляем поле nav_path если его нет + if (!existingCols.includes('nav_path')) { + await db.getQuery()( + `ALTER TABLE ${tableName} ADD COLUMN nav_path TEXT` + ); + } + + // Добавляем поле is_index_page если его нет + if (!existingCols.includes('is_index_page')) { + await db.getQuery()( + `ALTER TABLE ${tableName} ADD COLUMN is_index_page BOOLEAN DEFAULT FALSE` + ); + } + for (const field of fields) { const encryptedField = `${field}_encrypted`; if (!existingCols.includes(encryptedField)) { @@ -205,9 +245,25 @@ async function generateUniqueSlug(title, pageId, tableName) { return slug; } +// Middleware для условной обработки multer (только для multipart/form-data) +const conditionalUpload = (req, res, next) => { + const contentType = req.headers['content-type'] || ''; + if (contentType.includes('multipart/form-data')) { + return upload.single('file')(req, res, next); + } + // Для JSON запросов пропускаем multer + next(); +}; + // Создать страницу (только для админа) -router.post('/', upload.single('file'), async (req, res) => { +router.post('/', conditionalUpload, async (req, res) => { console.log('[pages] POST /: Начало обработки запроса на создание страницы'); + console.log('[pages] POST /: Content-Type:', req.headers['content-type']); + console.log('[pages] POST /: req.body тип:', typeof req.body); + console.log('[pages] POST /: req.body ключи:', req.body ? Object.keys(req.body) : 'req.body пуст'); + console.log('[pages] POST /: req.body содержимое:', JSON.stringify(req.body || {}, null, 2).substring(0, 500)); + console.log('[pages] POST /: req.file:', req.file ? { name: req.file.originalname, size: req.file.size } : 'нет файла'); + try { if (!req.session || !req.session.authenticated) { console.log('[pages] POST /: Ошибка аутентификации - сессия не найдена'); @@ -245,6 +301,15 @@ router.post('/', upload.single('file'), async (req, res) => { // Собираем данные страницы const bodyRaw = req.body || {}; + // Проверяем, что body не пустой + if (!bodyRaw || Object.keys(bodyRaw).length === 0) { + console.error('[pages] POST /: req.body пуст или не определен'); + return res.status(400).json({ + error: 'Отсутствуют данные страницы', + message: 'Тело запроса пустое. Проверьте Content-Type и формат данных.' + }); + } + // Обрабатываем required_permission: если это пустая строка или 'null', устанавливаем null let requiredPermission = null; if (bodyRaw.required_permission) { @@ -2056,7 +2121,7 @@ Disallow: /admin/ Disallow: /content/create Disallow: /content/edit -Sitemap: ${baseUrl}/api/pages/public/sitemap.xml +Sitemap: ${baseUrl}/sitemap.xml `; res.setHeader('Content-Type', 'text/plain'); diff --git a/docs-en/FAQ.md b/docs-en/FAQ.md index 537ba33..9732198 100644 --- a/docs-en/FAQ.md +++ b/docs-en/FAQ.md @@ -89,7 +89,8 @@ DLE is designed for **all types of organizations** that need transparent collect ✅ **All licenses include:** - Lifetime access to the application -- All future updates free +- All future updates free for 5 years (for token holders) +- **Free setup by contractors within 5 years** (personalization for your business type, integration with business processes, AI assistant configuration, blockchain accounting setup, feature customization if needed) - Technical support through portal - AI assistant 24/7 without limits - Participation in voting for new features @@ -104,6 +105,7 @@ DLE is designed for **all types of organizations** that need transparent collect - Pay once - Access forever - All updates free for 5 years for license token holders (see [legal/service-terms.md](../legal-en/service-terms.md)) +- **Free setup by contractors within 5 years** after license purchase - No hidden fees - AI works without request limits @@ -142,6 +144,7 @@ DLE is designed for **all types of organizations** that need transparent collect - 🎓 **Online training sessions** (group and individual) - 📚 **Library of recordings** of all sessions - 📧 **Email support** +- ✅ **Free setup by contractors within 5 years** (personalization, integration, AI configuration, feature customization) ### How does the voting system work? @@ -734,6 +737,7 @@ Always end with: "How else can I help? 😊" **All license holders receive**: - ✅ All web application updates (free for 5 years for token holders) +- ✅ **Free setup by contractors within 5 years** (personalization, integration, AI configuration, feature customization) - ✅ Access to documentation and knowledge base - ✅ Technical support through application - ✅ AI assistant 24/7 @@ -803,6 +807,7 @@ You can request refund of **70% of license cost** within **5 years** from purcha - 🎓 Online training sessions (all licenses) - 📚 Library of recordings (all licenses) - 📧 Email support (all licenses) +- ✅ Free setup by contractors within 5 years (all licenses) **SLA (first response time)**: - 🔴 Critical: 4 hours @@ -994,7 +999,7 @@ curl -fsSL https://raw.githubusercontent.com/VC-HB3-Accelerator/DLE/main/setup-t **One-time costs**: - License: $1,000-10,000 USDT - Smart contract deployment: $100-500 (gas fees) -- Setup: $0 (self-service) +- Setup: $0 (free setup by contractors within 5 years included in license) **Monthly costs**: - Hosting: $50-200/month diff --git a/docs-en/service-terms.md b/docs-en/service-terms.md index dd9f44b..18dc1b9 100644 --- a/docs-en/service-terms.md +++ b/docs-en/service-terms.md @@ -17,6 +17,7 @@ Key Points: - License Type: Perpetual, rights determined by number of tokens (1 or 10). - Updates and Basic Maintenance: Free for 5 years from on-chain token transfer date. +- Free Setup by Contractors: Within 5 years after license purchase (personalization, integration, AI configuration, feature customization). - Development Voting: 1 token = 1 vote, decisions by majority ≥51%. - 70% Refund possible if program conditions are met (see original). - Support, releases, knowledge base — through application `https://hb3-accelerator.com/`. diff --git a/docs/FAQ.md b/docs/FAQ.md index e88e703..0be598d 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -89,7 +89,8 @@ DLE создано для **всех типов организаций**, нуж ✅ **Все лицензии включают:** - Пожизненный доступ к приложению -- Все будущие обновления бесплатно +- Все будущие обновления бесплатно 5 лет (для держателей токенов) +- **Бесплатная настройка подрядчиками в течение 5 лет** (персонализация под ваш вид деятельности, интеграция с бизнес-процессами, настройка ИИ-ассистента, настройка блокчейн-учёта, доработка функционала при необходимости) - Техническую поддержку через портал - AI ассистент 24/7 без лимитов - Участие в голосовании за новые функции @@ -104,6 +105,7 @@ DLE создано для **всех типов организаций**, нуж - Оплата один раз - Доступ навсегда - Все обновления бесплатно 5 лет для держателей лицензионных токенов (см. [legal/service-terms.md](../legal/service-terms.md)) +- **Бесплатная настройка подрядчиками в течение 5 лет** после покупки лицензии - Никаких скрытых платежей - AI работает без лимитов на запросы @@ -142,6 +144,7 @@ DLE создано для **всех типов организаций**, нуж - 🎓 **Онлайн-сессии обучения** (групповые и индивидуальные) - 📚 **Библиотека записей** всех сессий - 📧 **Email поддержка** +- ✅ **Бесплатная настройка подрядчиками в течение 5 лет** (персонализация, интеграция, настройка ИИ, доработка функционала) ### Как работает система голосования? @@ -734,6 +737,7 @@ DLE создано для **всех типов организаций**, нуж **Все держатели лицензий получают**: - ✅ Все обновления веб-приложения (бесплатно 5 лет для держателей токенов) +- ✅ **Бесплатная настройка подрядчиками в течение 5 лет** (персонализация, интеграция, настройка ИИ, доработка функционала) - ✅ Доступ к документации и базе знаний - ✅ Техническая поддержка через приложение - ✅ AI ассистент 24/7 @@ -803,6 +807,7 @@ DLE создано для **всех типов организаций**, нуж - 🎓 Онлайн-сессии обучения (все лицензии) - 📚 Библиотека записей (все лицензии) - 📧 Email поддержка (все лицензии) +- ✅ Бесплатная настройка подрядчиками в течение 5 лет (все лицензии) **SLA (время первого ответа)**: - 🔴 Критическая: 4 часа @@ -994,7 +999,7 @@ curl -fsSL https://raw.githubusercontent.com/VC-HB3-Accelerator/DLE/main/setup-t **Единоразовые расходы**: - Лицензия: $1,000-10,000 USDT - Деплой смарт-контракта: $100-500 (gas fees) -- Настройка: $0 (самостоятельно) +- Настройка: $0 (бесплатная настройка подрядчиками в течение 5 лет включена в лицензию) **Ежемесячные расходы**: - Хостинг: $50-200/месяц diff --git a/docs/service-terms.md b/docs/service-terms.md index f80aa36..f9b17a9 100644 --- a/docs/service-terms.md +++ b/docs/service-terms.md @@ -17,6 +17,7 @@ Ключевые тезисы: - Тип лицензии: бессрочная (Perpetual), права определяются количеством токенов (1 или 10). - Обновления и базовое обслуживание: бесплатно 5 лет с даты on-chain передачи токена. +- Бесплатная настройка подрядчиками: в течение 5 лет после покупки лицензии (персонализация, интеграция, настройка ИИ, доработка функционала). - Голосование за развитие: 1 токен = 1 голос, решения большинством ≥51%. - Возврат 70% возможен при соблюдении условий программы (см. оригинал). - Поддержка, релизы, база знаний — через приложение `https://hb3-accelerator.com/`. diff --git a/frontend/nginx-local.conf b/frontend/nginx-local.conf index 5766990..f978233 100644 --- a/frontend/nginx-local.conf +++ b/frontend/nginx-local.conf @@ -28,6 +28,25 @@ http { add_header Content-Type text/plain; } + # Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем + location = /robots.txt { + proxy_pass http://${BACKEND_CONTAINER}:8000/api/pages/public/robots.txt; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type text/plain; + } + + location = /sitemap.xml { + proxy_pass http://${BACKEND_CONTAINER}:8000/api/pages/public/sitemap.xml; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type application/xml; + } + # Основной location location / { # Rate limiting для основных страниц (отключено) diff --git a/frontend/nginx-simple.conf b/frontend/nginx-simple.conf index 5a57ad0..c7776d3 100644 --- a/frontend/nginx-simple.conf +++ b/frontend/nginx-simple.conf @@ -13,13 +13,21 @@ http { # limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s; # limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=5r/s; - # Блокировка известных сканеров и вредоносных ботов + # Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты) map $http_user_agent $bad_bot { default 0; - ~*bot 1; - ~*crawler 1; - ~*spider 1; - ~*scanner 1; + # Разрешаем легитимные поисковые боты + ~*googlebot 0; + ~*bingbot 0; + ~*slurp 0; + ~*duckduckbot 0; + ~*baiduspider 0; + ~*yandex 0; + ~*sogou 0; + ~*exabot 0; + ~*facebot 0; + ~*ia_archiver 0; + # Блокируем вредоносные боты и сканеры ~*sqlmap 1; ~*nikto 1; ~*dirb 1; @@ -29,6 +37,9 @@ http { ~*zap 1; ~*nessus 1; ~*openvas 1; + ~*masscan 1; + ~*nmap 1; + ~*scanner 1; ~*Chrome/[1-4][0-9]\. 1; ~*Firefox/[1-6][0-9]\. 1; ~*Safari/[1-9]\. 1; diff --git a/frontend/src/services/webSshService.js b/frontend/src/services/webSshService.js index c2f32ee..64afb19 100644 --- a/frontend/src/services/webSshService.js +++ b/frontend/src/services/webSshService.js @@ -37,13 +37,21 @@ function getNginxConfig(domain, serverPort) { # limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s; # limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=50r/s; -# Блокировка известных сканеров и вредоносных ботов +# Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты) map $http_user_agent $bad_bot { default 0; - ~*bot 1; - ~*crawler 1; - ~*spider 1; - ~*scanner 1; + # Разрешаем легитимные поисковые боты + ~*googlebot 0; + ~*bingbot 0; + ~*slurp 0; + ~*duckduckbot 0; + ~*baiduspider 0; + ~*yandex 0; + ~*sogou 0; + ~*exabot 0; + ~*facebot 0; + ~*ia_archiver 0; + # Блокируем вредоносные боты и сканеры ~*sqlmap 1; ~*nikto 1; ~*dirb 1; @@ -53,6 +61,9 @@ map $http_user_agent $bad_bot { ~*zap 1; ~*nessus 1; ~*openvas 1; + ~*masscan 1; + ~*nmap 1; + ~*scanner 1; } server { @@ -74,12 +85,31 @@ server { return 404; } - # Защита от доступа к чувствительным файлам - location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config|robots\\\\.txt|sitemap\\\\.xml)$ { + # Защита от доступа к чувствительным файлам (исключаем robots.txt и sitemap.xml для SEO) + location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config)$ { deny all; return 404; } + # Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем + location = /robots.txt { + proxy_pass http://localhost:8000/api/pages/public/robots.txt; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type text/plain; + } + + location = /sitemap.xml { + proxy_pass http://localhost:8000/api/pages/public/sitemap.xml; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type application/xml; + } + # Основной location для фронтенда location / { # Rate limiting для основных страниц (отключено) @@ -476,13 +506,21 @@ app.post('/tunnel/create', async (req, res) => { # limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s; # limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=50r/s; -# Блокировка известных сканеров и вредоносных ботов +# Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты) map $http_user_agent $bad_bot { default 0; - ~*bot 1; - ~*crawler 1; - ~*spider 1; - ~*scanner 1; + # Разрешаем легитимные поисковые боты + ~*googlebot 0; + ~*bingbot 0; + ~*slurp 0; + ~*duckduckbot 0; + ~*baiduspider 0; + ~*yandex 0; + ~*sogou 0; + ~*exabot 0; + ~*facebot 0; + ~*ia_archiver 0; + # Блокируем вредоносные боты и сканеры ~*sqlmap 1; ~*nikto 1; ~*dirb 1; @@ -492,6 +530,9 @@ map $http_user_agent $bad_bot { ~*zap 1; ~*nessus 1; ~*openvas 1; + ~*masscan 1; + ~*nmap 1; + ~*scanner 1; } server { @@ -513,12 +554,31 @@ server { return 404; } - # Защита от доступа к чувствительным файлам - location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config|robots\\\\.txt|sitemap\\\\.xml)$ { + # Защита от доступа к чувствительным файлам (исключаем robots.txt и sitemap.xml для SEO) + location ~* /(\\\\.htaccess|\\\\.htpasswd|\\\\.env|\\\\.git|\\\\.svn|\\\\.DS_Store|Thumbs\\\\.db|web\\\\.config)$ { deny all; return 404; } + # Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем + location = /robots.txt { + proxy_pass http://localhost:8000/api/pages/public/robots.txt; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type text/plain; + } + + location = /sitemap.xml { + proxy_pass http://localhost:8000/api/pages/public/sitemap.xml; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type application/xml; + } + # Основной location для фронтенда location / { # Rate limiting для основных страниц (отключено) diff --git a/frontend/src/views/content/PublishedPageView.vue b/frontend/src/views/content/PublishedPageView.vue index 30059cc..47b4359 100644 --- a/frontend/src/views/content/PublishedPageView.vue +++ b/frontend/src/views/content/PublishedPageView.vue @@ -190,3 +190,4 @@ onMounted(async () => { } + diff --git a/sync-to-vds.sh b/sync-to-vds.sh index 74eb6e6..99b968c 100755 --- a/sync-to-vds.sh +++ b/sync-to-vds.sh @@ -10,13 +10,15 @@ NC='\033[0m' # No Color echo -e "${GREEN}🔄 Синхронизация кода с VDS...${NC}" # Параметры VDS (из настроек) -VDS_HOST="185.26.121.127" +VDS_HOST="185.221.214.140" VDS_USER="root" VDS_PORT="22" VDS_PATH="/home/docker/dapp" # SSH опции SSH_OPTS="-p $VDS_PORT -o StrictHostKeyChecking=no" +# SCP опции (scp использует -P для порта, а не -p) +SCP_OPTS="-P $VDS_PORT -o StrictHostKeyChecking=no" # Проверяем наличие rsync на удаленном сервере echo -e "${YELLOW}🔍 Проверка наличия rsync на VDS...${NC}" @@ -94,7 +96,7 @@ sync_with_tar() { -C "$(dirname "$SRC_DIR")" "$DIR_NAME" # Копируем архив на VDS - scp -e "ssh $SSH_OPTS" "$TMP_TAR" "$VDS_USER@$VDS_HOST:/tmp/" + scp $SCP_OPTS "$TMP_TAR" "$VDS_USER@$VDS_HOST:/tmp/" # Распаковываем на VDS ssh $SSH_OPTS $VDS_USER@$VDS_HOST "mkdir -p $DST_DIR && tar -xzf /tmp/$(basename $TMP_TAR) -C $DST_DIR --strip-components=1 && rm /tmp/$(basename $TMP_TAR)" @@ -129,13 +131,13 @@ fi # Синхронизация docker-compose.prod.yml echo -e "${YELLOW}📦 Синхронизация docker-compose.prod.yml...${NC}" -scp -e "ssh $SSH_OPTS" ./webssh-agent/docker-compose.prod.yml "$VDS_USER@$VDS_HOST:$VDS_PATH/docker-compose.prod.yml" +scp $SCP_OPTS ./webssh-agent/docker-compose.prod.yml "$VDS_USER@$VDS_HOST:$VDS_PATH/docker-compose.prod.yml" # Синхронизация Dockerfile файлов (если они изменились) echo -e "${YELLOW}📦 Синхронизация Dockerfile файлов...${NC}" -scp -e "ssh $SSH_OPTS" ./backend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/backend/Dockerfile" 2>/dev/null || true -scp -e "ssh $SSH_OPTS" ./frontend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/Dockerfile" 2>/dev/null || true -scp -e "ssh $SSH_OPTS" ./frontend/nginx.Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/nginx.Dockerfile" 2>/dev/null || true +scp $SCP_OPTS ./backend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/backend/Dockerfile" 2>/dev/null || true +scp $SCP_OPTS ./frontend/Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/Dockerfile" 2>/dev/null || true +scp $SCP_OPTS ./frontend/nginx.Dockerfile "$VDS_USER@$VDS_HOST:$VDS_PATH/frontend/nginx.Dockerfile" 2>/dev/null || true echo -e "${GREEN}✅ Синхронизация завершена!${NC}" diff --git a/webssh-agent/nginx-template.conf b/webssh-agent/nginx-template.conf index 297fdc2..f75c5b5 100644 --- a/webssh-agent/nginx-template.conf +++ b/webssh-agent/nginx-template.conf @@ -10,13 +10,21 @@ http { limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s; limit_req_zone $binary_remote_addr zone=api_limit_per_ip:10m rate=5r/s; - # Блокировка известных сканеров и вредоносных ботов + # Блокировка известных сканеров и вредоносных ботов (исключая легитимные поисковые боты) map $http_user_agent $bad_bot { default 0; - ~*bot 1; - ~*crawler 1; - ~*spider 1; - ~*scanner 1; + # Разрешаем легитимные поисковые боты + ~*googlebot 0; + ~*bingbot 0; + ~*slurp 0; + ~*duckduckbot 0; + ~*baiduspider 0; + ~*yandex 0; + ~*sogou 0; + ~*exabot 0; + ~*facebot 0; + ~*ia_archiver 0; + # Блокируем вредоносные боты и сканеры ~*sqlmap 1; ~*nikto 1; ~*dirb 1; @@ -26,6 +34,9 @@ http { ~*zap 1; ~*nessus 1; ~*openvas 1; + ~*masscan 1; + ~*nmap 1; + ~*scanner 1; ~*Chrome/[1-4][0-9]\. 1; ~*Firefox/[1-6][0-9]\. 1; ~*Safari/[1-9]\. 1; @@ -54,12 +65,31 @@ http { return 404; } - # Защита от доступа к чувствительным файлам - location ~* /(\.htaccess|\.htpasswd|\.env|\.git|\.svn|\.DS_Store|Thumbs\.db|web\.config|robots\.txt|sitemap\.xml)$ { + # Защита от доступа к чувствительным файлам (исключаем robots.txt и sitemap.xml для SEO) + location ~* /(\.htaccess|\.htpasswd|\.env|\.git|\.svn|\.DS_Store|Thumbs\.db|web\.config)$ { deny all; return 404; } + # Разрешаем доступ к robots.txt и sitemap.xml для поисковых систем + location = /robots.txt { + proxy_pass http://BACKEND_CONTAINER_PLACEHOLDER:8000/api/pages/public/robots.txt; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type text/plain; + } + + location = /sitemap.xml { + proxy_pass http://BACKEND_CONTAINER_PLACEHOLDER:8000/api/pages/public/sitemap.xml; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + add_header Content-Type application/xml; + } + # Защита от доступа к конфигурационным файлам location ~* /\.(env|config|ini|conf|cfg|yml|yaml|json|xml|sql|db|bak|backup|old|tmp|temp|log)$ { deny all;