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

Когда вы разворачиваете своё приложение, вы можете находиться за распределителем нагрузки (например, эластичное распределение нагрузки AWS) или обратным прокси (например, 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
// public/index.php

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

// сообщить Symfony о вашем обратном прокси
Request::setTrustedProxies(
    // the IP address (or range) of your proxy
    ['192.0.0.1', '10.0.0.0/8'],

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

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

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

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

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

Некоторые обратные прокси (вроде Эластичного распределения нагрузки AWS) не имеют статичного IP адреса или даже диапазона, который вы можете охватить с помощью CIDS примечания. В этомслучае, вам нужно будет - очень осторожно - доверить всем прокси.

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

  2. Когда вы гарантировали, что траффик будет исходить только от доверенных обратных проекси, сконфигурируйте Symfony всегда доверять входящему запросу:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    // public/index.php
    
    // ...
    Request::setTrustedProxies(
        // доверять *всем* запросам
        array('127.0.0.1', $request->server->get('REMOTE_ADDR')),
    
        // если вы используете ЭБН, иначе вышеописанная константа
        Request::HEADER_X_FORWARDED_AWS_ELB
    );
    

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

Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.