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

8.1 KiB
Raw Blame History

Настройка 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":

# Передача реального 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" (если доступен):

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:

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 сети:
docker network inspect bridge | grep Gateway
  1. Используйте этот IP-адрес вместо host.docker.internal

3. Настройка Docker Compose (если приложение тоже в Docker)

Если оба сервиса в Docker, используйте общую сеть:

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. Проверка работы

После настройки используйте тестовый эндпоинт для проверки:

curl -H "X-Forwarded-For: 192.168.1.100" https://your-domain.com/api/debug/ip

Или откройте в браузере: https://your-domain.com/api/debug/ip

5. Ожидаемый результат

В ответе должно быть:

{
  "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, добавьте:

proxy_set_header CF-Connecting-IP $http_cf_connecting_ip;

Для AWS Load Balancer

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;

Специальные настройки для приложений на хосте

Проверка доступности приложения из Docker

Убедитесь, что ваше приложение доступно из Docker контейнера:

# Проверьте, что приложение слушает на всех интерфейсах
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:

// Вместо
app.listen(PORT, () => {
  console.log(`Сервер запущен на порту ${PORT}`);
});

// Используйте
app.listen(PORT, "0.0.0.0", () => {
  console.log(`Сервер запущен на порту ${PORT}`);
});

Альтернативные способы подключения

Если host.docker.internal не работает:

  1. Используйте IP-адрес хоста:

    # Найдите IP-адрес хоста
    ip route show default | awk '/default/ {print $3}'
    
  2. Используйте режим host network для nginx Proxy Manager:

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