Как сконфигурировать Symfony так, чтобы она работала за балансировщиком нагрузок или обратным прокси

Как сконфигурировать Symfony так, чтобы она работала за балансировщиком нагрузок или обратным прокси

Когда вы развёртываете ваше приложение, вы можете находиться за балансировщиком загрузок (например, AWS Elastic Load Balancer) или обратным прокси (например, Varnish для кеширования).

По большей части это не создаёт никаких проблем с Symfony. Однако, когда запрос проходит через прокси, определённая информация о запросе отправляется, используя либо стандартный заголовок Forwarded, либо заголовки X-Forwarded-*. Например, вместо того, чтобы считать заголовок REMOTE_ADDR (который теперь будет IP-адресом вашего обратного прокси), настоящий IP пользователя будет сохранён в стандартном заголовке Forwarded: for="..." или заголовке X-Forwarded-For.

Если вы не сконфигурировали Symfony так, чтобы она искала эти заголовки, вы получите неверную информацию об IP-адресе клиента, подключается он через HTTPS или нет, клиентском порте и имени запрашиваемого хоста.

Решение: setTrustedProxies()

Чтобы исправить это, вам нужно сказать Symfony, каким IP-адресам обратного прокси можно доверять, и какие заголовки использует ваш обратный прокси для отправки информации:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// web/app.php

// ...
$request = Request::createFromGlobals();

// сообщите Symfony о вашем обратном прокси
Request::setTrustedProxies(
    // IP-адрес (или область) вашего прокси
    ['192.0.0.1', '10.0.0.0/8'],

    // доверять *всем* заголовкам "X-Forwarded-*"
    Request::HEADER_X_FORWARDED_ALL

    // или, если ваш прокси использует заголовок "Forwarded"
    // Request::HEADER_FORWARDED

    // или, если вы используете AWS ELB
    // Request::HEADER_X_FORWARDED_AWS_ELB
);

Объект Request имеет несколько констант Request::HEADER_*, которые контролируют, каким именно заголовкам из вашего обратного прокси можно доверять. Аргумент является полем логической величины, так что вы также можете передать ваше собственное значение (например, 0b00110).

Но если IP моего обратного прокси постоянно изменяется!

Некоторые обратные прокси (как балансировщики загрузок Amazon's Elastic Load Balancers) не имеют статичного IP-адреса или даже области, которую вы можете указать с помощью нотации CIDR. В этом случае, вам нужно будет очень осторожно доверить всем прокси.

  1. Сконфигурируйте ваш(и) веб-сервер(ы) так, чтобы они не отвечали на трафик от любых клиентов, кроме ваших балансировщиков нагрузок. В AWS это может быть сделано с помощью групп безопасности.
  2. Как только вы гарантировали, что трафик будет появляться только из ваших доверенных обратных прокси, сконфигурируйте Symfony так, чтобы она всегда доверяла входящим запросам:

// web/app.php

// ... Request::setTrustedProxies( // доверять всем запросам array('127.0.0.1', $request->server->get('REMOTE_ADDR')),

// если вы используете ELB, в другом случае - константа, описанная выше
Request::HEADER_X_FORWARDED_AWS_ELB

);

Вот и все! Критично важно, чтобы вы предотвратили поступление трафика из всех не доверенных источников. Если вы разрешите внешний трафик, он может "спародировать" свой настоящий IP-адрес и другую информацию.