Как настроить Nginx в Docker, чтобы он мог использовать реальный IP-адрес?

Как настроить Nginx в Docker, чтобы он имел доступ к реальному IP-адресу и мог обращаться к другим контейнерам? Это необходимо для использования GeoIP.
  • 19 января 2024 г. 14:29
Ответы на вопрос 2
Для того чтобы Nginx в Docker мог использовать реальный IP-адрес пользователя и обращаться к другим контейнерам, вам понадобится выполнить ряд шагов:

### 1. Проброс IP адреса:

Для того, чтобы Nginx мог видеть реальные IP адреса клиентов, нужно настроить Docker, чтобы он передавал эти IP адреса внутрь контейнера. Обычно это достигается путём использования режима сети `host` для Docker контейнера с Nginx, однако этот метод работает только на Linux и не подходит для Docker на macOS или Windows.

Пример команды запуска контейнера с использованием сети хоста:
```sh
docker run --net=host ...
```

Или в `docker-compose.yml`:
```yaml
services:
  nginx:
    image: nginx
    network_mode: host
```

### 2. Настройка Nginx:

Добавьте в конфигурацию Nginx (обычно это файл `nginx.conf` или файлы в директории `/etc/nginx/conf.d/`) настройку для обработки заголовка `X-Real-IP` или `X-Forwarded-For`. Эти заголовки обычно используются для передачи оригинальных IP-адресов клиентов через прокси-сервера.

Пример настройки:
```nginx
server {
    listen 80;
    
    # Устанавливаем внутренний IP-адрес клиента на основе заголовка X-Real-IP
    set_real_ip_from  172.17.0.0/16; # Замените на диапазон своей Docker сети
    real_ip_header    X-Real-IP;
    
    ...
}
```

Кроме того, если вы используете Nginx в качестве прокси-сервера для других контейнеров, удостоверьтесь, что вы настроили правильные `upstream` директивы, чтобы проксировать запросы к нужным контейнерам.

Пример:
```nginx
upstream myapp {
    server app_container:8000;
}

server {
    ...
    
    location / {
        proxy_pass http://myapp;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
```

### 3. Отключение пользовательской сети Docker:

Если вы используете стандартную Docker bridge сеть (обычно `docker0`), возможно, потребуется обратить внимание на правила брандмауэра на хосте и настройку IP-таблиц, чтобы убедиться, что трафик корректно пробрасывается в контейнеры. Это может не понадобиться, если вы используете `host` network mode, потому что в этом случае контейнеры используют сетевой стек хоста.

### 4. GeoIP модуль:

Если вы хотите использовать GeoIP функции в Nginx, убедитесь, что в вашем образе Nginx установлен модуль GeoIP и он включён в конфигурацию. Вам также понадобится база данных GeoIP, которую нужно будет загрузить и обновлять при необходимости.

Пример директивы GeoIP:
```nginx
geoip_country /path/to/geoip/GeoIP.dat;
map $geoip_country_code $country {
    default no;
    RU yes;
    ...
}

server {
    ...
    
    location / {
        if ($country = yes) {
            # Разрешаем доступ для Российских IP адресов
        }
    }
}
```

Помните, что настройка сети и правил брандмауэра может варьироваться в зависимости от вашей сп
Первый вариант - передаешь адрес вручную (например, через переменные окружения) 
Второй вариант - изменяешь тип сети контейнера

При запуске контейнера необходимо указывать --network host
Тогда контейнер не будет в изолированной сети и будет использовать сеть хоста - как будто не в докере запускается.
Чтобы IP адрес получить можно ip route использовать. Например, так:
/sbin/ip route|awk '/default/ { print $3 }'

Замечание: этот скрипт находит IP помеченный путем по умолчанию, если у тебя несколько интерфейсов, то возможно придется указывать вручную.
Похожие вопросы