NoteJS/NGINX_PROXY_SETUP.md
Fovway ad5a19d27e Обновлена документация по настройке NGINX и улучшена функция получения IP-адреса клиента
- Изменены разделы документации для настройки NGINX Proxy Manager, добавлены инструкции для приложений, работающих на хосте.
- Расширена логика получения IP-адреса клиента с учетом дополнительных заголовков и приоритетов, улучшая обработку запросов через прокси.
- Добавлены альтернативные способы подключения для случаев, когда `host.docker.internal` не работает.
2025-10-26 15:32:57 +07:00

254 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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