From ad5a19d27e9a1e1de7646dda5bb6cae3783352b9 Mon Sep 17 00:00:00 2001 From: Fovway Date: Sun, 26 Oct 2025 15:32:57 +0700 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B0=20=D0=B4=D0=BE=D0=BA=D1=83=D0=BC=D0=B5?= =?UTF-8?q?=D0=BD=D1=82=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=20=D0=BD?= =?UTF-8?q?=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B5=20NGINX=20?= =?UTF-8?q?=D0=B8=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D1=84=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20IP-=D0=B0=D0=B4=D1=80?= =?UTF-8?q?=D0=B5=D1=81=D0=B0=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Изменены разделы документации для настройки NGINX Proxy Manager, добавлены инструкции для приложений, работающих на хосте. - Расширена логика получения IP-адреса клиента с учетом дополнительных заголовков и приоритетов, улучшая обработку запросов через прокси. - Добавлены альтернативные способы подключения для случаев, когда `host.docker.internal` не работает. --- NGINX_PROXY_SETUP.md | 116 ++++++++++++++++++++++++++++++++++++++++--- QUICK_SETUP.md | 57 +++++++++++++++++++++ server.js | 32 ++++++------ 3 files changed, 183 insertions(+), 22 deletions(-) create mode 100644 QUICK_SETUP.md diff --git a/NGINX_PROXY_SETUP.md b/NGINX_PROXY_SETUP.md index e6a51cb..a32bce9 100644 --- a/NGINX_PROXY_SETUP.md +++ b/NGINX_PROXY_SETUP.md @@ -58,9 +58,57 @@ location / { } ``` -### 2. Настройка Docker Compose (если используется) +### 2. Настройка для приложения на хосте (не в Docker) -Если ваш nginx Proxy Manager работает в Docker, убедитесь, что в docker-compose.yml правильно настроена сеть: +Если ваш nginx Proxy Manager работает в Docker, а приложение - на хосте, используйте `host.docker.internal` для подключения: + +#### В настройках прокси-хоста в nginx Proxy Manager: + +**Forward Hostname/IP:** `host.docker.internal` +**Forward Port:** `3000` (или ваш порт) + +#### Или в Custom Nginx Configuration: + +```nginx +location / { + proxy_pass http://host.docker.internal:3000; + + # Передача реального IP-адреса + 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; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Client-IP $remote_addr; + + # Дополнительные настройки + proxy_set_header Host $host; + proxy_set_header X-Forwarded-Server $host; + + # Таймауты + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # Буферизация + proxy_buffering off; + proxy_request_buffering off; +} +``` + +#### Альтернативный способ (если host.docker.internal не работает): + +1. Найдите IP-адрес хоста в Docker сети: + +```bash +docker network inspect bridge | grep Gateway +``` + +2. Используйте этот IP-адрес вместо `host.docker.internal` + +### 3. Настройка Docker Compose (если приложение тоже в Docker) + +Если оба сервиса в Docker, используйте общую сеть: ```yaml version: "3.8" @@ -91,7 +139,7 @@ networks: driver: bridge ``` -### 3. Проверка работы +### 4. Проверка работы После настройки используйте тестовый эндпоинт для проверки: @@ -101,7 +149,7 @@ curl -H "X-Forwarded-For: 192.168.1.100" https://your-domain.com/api/debug/ip Или откройте в браузере: `https://your-domain.com/api/debug/ip` -### 4. Ожидаемый результат +### 5. Ожидаемый результат В ответе должно быть: @@ -116,7 +164,7 @@ curl -H "X-Forwarded-For: 192.168.1.100" https://your-domain.com/api/debug/ip } ``` -### 5. Отладка +### 6. Отладка Если IP-адрес все еще неправильный: @@ -124,8 +172,9 @@ curl -H "X-Forwarded-For: 192.168.1.100" https://your-domain.com/api/debug/ip 2. Убедитесь, что заголовки передаются (используйте `/api/debug/ip`) 3. Проверьте настройки сети Docker 4. Убедитесь, что nginx Proxy Manager не находится за дополнительными прокси +5. Проверьте, что ваше приложение слушает на правильном порту и адресе -### 6. Дополнительные настройки +### 7. Дополнительные настройки #### Для Cloudflare @@ -142,8 +191,63 @@ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; ``` +## Специальные настройки для приложений на хосте + +### Проверка доступности приложения из Docker + +Убедитесь, что ваше приложение доступно из Docker контейнера: + +```bash +# Проверьте, что приложение слушает на всех интерфейсах +netstat -tlnp | grep :3000 + +# Должно показать что-то вроде: +# tcp6 0 0 :::3000 :::* LISTEN 1234/node +# или +# tcp 0 0 0.0.0.0:3000 0.0.0.0:* LISTEN 1234/node +``` + +**Важно:** Если вы видите `127.0.0.1:3000` или `::1:3000`, то приложение недоступно из Docker контейнера. + +Если приложение слушает только на `127.0.0.1:3000`, измените настройки в `server.js`: + +```javascript +// Вместо +app.listen(PORT, () => { + console.log(`Сервер запущен на порту ${PORT}`); +}); + +// Используйте +app.listen(PORT, "0.0.0.0", () => { + console.log(`Сервер запущен на порту ${PORT}`); +}); +``` + +### Альтернативные способы подключения + +Если `host.docker.internal` не работает: + +1. **Используйте IP-адрес хоста:** + + ```bash + # Найдите IP-адрес хоста + ip route show default | awk '/default/ {print $3}' + ``` + +2. **Используйте режим host network для nginx Proxy Manager:** + ```yaml + services: + nginx-proxy-manager: + image: jc21/nginx-proxy-manager:latest + network_mode: host + volumes: + - ./data:/data + - ./letsencrypt:/etc/letsencrypt + ``` + ## Примечания - После изменения настроек nginx Proxy Manager перезапустите контейнер - Убедитесь, что ваш Node.js сервер настроен с `app.set("trust proxy", true)` +- Убедитесь, что приложение слушает на `0.0.0.0:PORT`, а не только на `127.0.0.1:PORT` - Тестовый эндпоинт `/api/debug/ip` можно удалить после настройки diff --git a/QUICK_SETUP.md b/QUICK_SETUP.md new file mode 100644 index 0000000..12972dd --- /dev/null +++ b/QUICK_SETUP.md @@ -0,0 +1,57 @@ +# Быстрая настройка IP-адресов для nginx Proxy Manager + +## Ваша ситуация + +- nginx Proxy Manager работает в Docker +- Ваше приложение NoteJS работает на хосте (не в Docker) +- IP-адрес всегда показывает 90.189.198.107 (IP прокси) + +## Быстрое решение + +### 1. В nginx Proxy Manager + +1. Откройте настройки вашего прокси-хоста +2. В разделе **"Advanced"** → **"Custom Nginx Configuration"** добавьте: + +```nginx +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; +proxy_set_header X-Client-IP $remote_addr; +``` + +### 2. В настройках прокси-хоста + +- **Forward Hostname/IP:** `host.docker.internal` +- **Forward Port:** `3000` + +### 3. Проверка + +Откройте в браузере: `https://your-domain.com/api/debug/ip` + +Должно показать реальный IP-адрес клиента вместо 90.189.198.107. + +### 4. Если не работает + +1. Проверьте, что приложение слушает на всех интерфейсах: + + ```bash + netstat -tlnp | grep :3000 + ``` + +2. Если видите `127.0.0.1:3000`, измените в `server.js`: + + ```javascript + app.listen(PORT, "0.0.0.0", () => { + console.log(`🚀 Сервер запущен на порту ${PORT}`); + }); + ``` + +3. Перезапустите nginx Proxy Manager: + ```bash + docker restart nginx-proxy-manager + ``` + +## Готово! + +После этих настроек ваше приложение будет получать реальные IP-адреса клиентов. diff --git a/server.js b/server.js index a844e73..4baf5ad 100644 --- a/server.js +++ b/server.js @@ -312,18 +312,26 @@ function getClientIP(req) { console.log("ALL HEADERS:", JSON.stringify(req.headers, null, 2)); console.log("========================"); - // Приоритет заголовков для nginx proxy manager: - // 1. X-Real-IP (часто используется nginx) - // 2. X-Forwarded-For (стандартный заголовок) - // 3. CF-Connecting-IP (если используется Cloudflare) - // 4. X-Client-IP - // 5. req.ip (Express с trust proxy) - // 6. req.socket.remoteAddress (прямое соединение) + // Приоритет для получения реального IP клиента: + // 1. req.socket.remoteAddress (для случаев с дополнительными прокси) + // 2. X-Real-IP (часто используется nginx) + // 3. X-Forwarded-For (стандартный заголовок) + // 4. CF-Connecting-IP (если используется Cloudflare) + // 5. X-Client-IP + // 6. req.ip (Express с trust proxy) let ip = null; + // Проверяем socket_remoteAddress в первую очередь (для случаев с дополнительными прокси) + if ( + req.socket?.remoteAddress && + req.socket.remoteAddress !== "::1" && + req.socket.remoteAddress !== "127.0.0.1" + ) { + ip = req.socket.remoteAddress; + } // Проверяем X-Real-IP (nginx часто использует этот заголовок) - if (req.headers["x-real-ip"]) { + else if (req.headers["x-real-ip"]) { ip = req.headers["x-real-ip"]; } // Проверяем X-Forwarded-For (берем первый IP из списка) @@ -350,14 +358,6 @@ function getClientIP(req) { else if (req.ip && req.ip !== "::1" && req.ip !== "127.0.0.1") { ip = req.ip; } - // В крайнем случае используем socket remoteAddress - else if ( - req.socket?.remoteAddress && - req.socket.remoteAddress !== "::1" && - req.socket.remoteAddress !== "127.0.0.1" - ) { - ip = req.socket.remoteAddress; - } // Очищаем IP от скобок IPv6, портов и кавычек if (ip && ip !== "unknown") {