Обновлена документация по настройке NGINX и улучшена функция получения IP-адреса клиента

- Изменены разделы документации для настройки NGINX Proxy Manager, добавлены инструкции для приложений, работающих на хосте.
- Расширена логика получения IP-адреса клиента с учетом дополнительных заголовков и приоритетов, улучшая обработку запросов через прокси.
- Добавлены альтернативные способы подключения для случаев, когда `host.docker.internal` не работает.
This commit is contained in:
Fovway 2025-10-26 15:32:57 +07:00
parent 0cb0b27f20
commit ad5a19d27e
3 changed files with 183 additions and 22 deletions

View File

@ -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` можно удалить после настройки

57
QUICK_SETUP.md Normal file
View File

@ -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-адреса клиентов.

View File

@ -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") {