Перейти к содержанию

Express за прокси

При запуске Express-приложения за reverse proxy (обратным прокси) некоторые API Express могут возвращать значения, отличающиеся от ожидаемых. Чтобы это учесть, используется настройка приложения trust proxy, которая позволяет API Express использовать информацию, переданную прокси. Самый частый случай — вместо IP клиента отображается внутренний IP reverse proxy.

При настройке trust proxy важно точно понимать конфигурацию reverse proxy. Так как эта опция доверяет данным из запроса, конфигурация в Express должна соответствовать реальной схеме работы прокси.

Параметр trust proxy можно установить в одно из значений, описанных ниже.

Boolean

Если true, IP клиента определяется как самое левое значение в заголовке X-Forwarded-For.

Если false, считается, что приложение напрямую подключено к клиенту, и IP клиента берется из req.socket.remoteAddress. Это значение по умолчанию.

При установке true убедитесь, что последний доверенный reverse proxy удаляет/перезаписывает заголовки X-Forwarded-For, X-Forwarded-Host и X-Forwarded-Proto, иначе клиент сможет подставить произвольные значения.

IP addresses

Можно указать IP-адрес, подсеть или массив IP/подсетей, которым нужно доверять как reverse proxy. Ниже список преднастроенных имен подсетей:

  • loopback - 127.0.0.1/8, ::1/128
  • linklocal - 169.254.0.0/16, fe80::/10
  • uniquelocal - 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, fc00::/7

IP-адреса можно задать любым из следующих способов:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// specify a single subnet
app.set('trust proxy', 'loopback');
// specify a subnet and an address
app.set('trust proxy', 'loopback, 123.123.123.123');
// specify multiple subnets as CSV
app.set('trust proxy', 'loopback, linklocal, uniquelocal');
app.set('trust proxy', [
    'loopback',
    'linklocal',
    'uniquelocal',
]); // specify multiple subnets as an array

Если список задан, указанные IP-адреса или подсети исключаются из определения клиентского адреса, и IP клиента определяется как ближайший к приложению недоверенный адрес. Механизм работает так: проверяется, доверен ли req.socket.remoteAddress. Если да, адреса из X-Forwarded-For проверяются справа налево до первого недоверенного.

Number

Используется адрес, находящийся не дальше чем в n хопах от приложения Express. req.socket.remoteAddress считается первым хопом, остальные ищутся в X-Forwarded-For справа налево. Значение 0 означает, что первый недоверенный адрес — это req.socket.remoteAddress, то есть reverse proxy отсутствует.

При таком режиме важно убедиться, что до приложения нет нескольких маршрутов разной длины, где клиент может оказаться ближе, чем заданное число хопов. Иначе клиент сможет подставить произвольные значения.

Function

Пользовательская реализация логики доверия.

1
2
3
4
5
6
app.set('trust proxy', (ip) => {
    if (ip === '127.0.0.1' || ip === '123.123.123.123')
        return true;
    // trusted IPs
    else return false;
});

Включение trust proxy приводит к следующим последствиям:

  • Значение req.hostname берется из X-Forwarded-Host, который может быть установлен клиентом или прокси.
  • X-Forwarded-Proto может быть установлен reverse proxy, чтобы сообщить приложению протокол (https, http или даже некорректное значение). Это отражается в req.protocol.
  • req.ip и req.ips заполняются на основе адреса сокета и заголовка X-Forwarded-For, начиная с первого недоверенного адреса.

Настройка trust proxy реализована с помощью пакета proxy-addr. Подробнее — в его документации.

Комментарии