- Изменены разделы документации для настройки NGINX Proxy Manager, добавлены инструкции для приложений, работающих на хосте. - Расширена логика получения IP-адреса клиента с учетом дополнительных заголовков и приоритетов, улучшая обработку запросов через прокси. - Добавлены альтернативные способы подключения для случаев, когда `host.docker.internal` не работает.
254 lines
8.1 KiB
Markdown
254 lines
8.1 KiB
Markdown
# Настройка nginx Proxy Manager для корректной передачи IP-адресов
|
||
|
||
## Проблема
|
||
|
||
При использовании nginx Proxy Manager в режиме bridge, реальный IP-адрес клиента может не передаваться корректно, и вместо него всегда показывается IP-адрес прокси-сервера (например, 90.189.198.107).
|
||
|
||
## Решение
|
||
|
||
### 1. Настройка nginx Proxy Manager
|
||
|
||
В настройках прокси-хоста в nginx Proxy Manager добавьте следующие заголовки:
|
||
|
||
#### В разделе "Advanced" → "Custom Nginx Configuration":
|
||
|
||
```nginx
|
||
# Передача реального 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 X-Forwarded $scheme://$host;
|
||
|
||
# Установка доверенного прокси
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Forwarded-Server $host;
|
||
```
|
||
|
||
#### Или в разделе "Custom Nginx Configuration" (если доступен):
|
||
|
||
```nginx
|
||
location / {
|
||
proxy_pass http://your-app-container: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;
|
||
}
|
||
```
|
||
|
||
### 2. Настройка для приложения на хосте (не в Docker)
|
||
|
||
Если ваш 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"
|
||
services:
|
||
nginx-proxy-manager:
|
||
image: jc21/nginx-proxy-manager:latest
|
||
container_name: nginx-proxy-manager
|
||
ports:
|
||
- "80:80"
|
||
- "443:443"
|
||
- "81:81"
|
||
volumes:
|
||
- ./data:/data
|
||
- ./letsencrypt:/etc/letsencrypt
|
||
networks:
|
||
- npm-network
|
||
restart: unless-stopped
|
||
|
||
your-app:
|
||
image: your-app-image
|
||
container_name: your-app
|
||
networks:
|
||
- npm-network
|
||
restart: unless-stopped
|
||
|
||
networks:
|
||
npm-network:
|
||
driver: bridge
|
||
```
|
||
|
||
### 4. Проверка работы
|
||
|
||
После настройки используйте тестовый эндпоинт для проверки:
|
||
|
||
```bash
|
||
curl -H "X-Forwarded-For: 192.168.1.100" https://your-domain.com/api/debug/ip
|
||
```
|
||
|
||
Или откройте в браузере: `https://your-domain.com/api/debug/ip`
|
||
|
||
### 5. Ожидаемый результат
|
||
|
||
В ответе должно быть:
|
||
|
||
```json
|
||
{
|
||
"detected_ip": "192.168.1.100", // Реальный IP клиента
|
||
"headers": {
|
||
"x-forwarded-for": "192.168.1.100",
|
||
"x-real-ip": "192.168.1.100",
|
||
"x-client-ip": "192.168.1.100"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6. Отладка
|
||
|
||
Если IP-адрес все еще неправильный:
|
||
|
||
1. Проверьте логи nginx Proxy Manager
|
||
2. Убедитесь, что заголовки передаются (используйте `/api/debug/ip`)
|
||
3. Проверьте настройки сети Docker
|
||
4. Убедитесь, что nginx Proxy Manager не находится за дополнительными прокси
|
||
5. Проверьте, что ваше приложение слушает на правильном порту и адресе
|
||
|
||
### 7. Дополнительные настройки
|
||
|
||
#### Для Cloudflare
|
||
|
||
Если вы используете Cloudflare, добавьте:
|
||
|
||
```nginx
|
||
proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;
|
||
```
|
||
|
||
#### Для AWS Load Balancer
|
||
|
||
```nginx
|
||
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` можно удалить после настройки
|