diff --git a/_build/redirection_map b/_build/redirection_map index 3ce14efbb69..ad3565820f1 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -338,3 +338,4 @@ /security/target_path /security /service_container/third_party /service_container /templating/templating_service /templates +/components/http_foundation/trusting_proxies /request/load_balancer_reverse_proxy diff --git a/components/http_foundation/trusting_proxies.rst b/components/http_foundation/trusting_proxies.rst deleted file mode 100644 index e97404e0a0c..00000000000 --- a/components/http_foundation/trusting_proxies.rst +++ /dev/null @@ -1,65 +0,0 @@ -.. index:: - single: Request; Trusted Proxies - -Trusting Proxies -================ - -.. tip:: - - If you're using the Symfony Framework, start by reading - :doc:`/request/load_balancer_reverse_proxy`. - -If you find yourself behind some sort of proxy - like a load balancer - then -certain header information may be sent to you using special ``X-Forwarded-*`` -headers or the ``Forwarded`` header. For example, the ``Host`` HTTP header is -usually used to return the requested host. But when you're behind a proxy, -the actual host may be stored in an ``X-Forwarded-Host`` header. - -Since HTTP headers can be spoofed, Symfony does *not* trust these proxy -headers by default. If you are behind a proxy, you should manually whitelist -your proxy as follows: - -.. code-block:: php - - use Symfony\Component\HttpFoundation\Request; - - // put this code as early as possible in your application (e.g. in your - // front controller) to only trust proxy headers coming from these IP addresses - Request::setTrustedProxies(array('192.0.0.1', '10.0.0.0/8')); - -You should also make sure that your proxy filters unauthorized use of these -headers, e.g. if a proxy natively uses the ``X-Forwarded-For`` header, it -should not allow clients to send ``Forwarded`` headers to Symfony. - -If your proxy does not filter headers appropriately, you need to configure -Symfony not to trust the headers your proxy does not filter (see below). - -Configuring Header Names ------------------------- - -By default, the following proxy headers are trusted: - -* ``Forwarded`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getClientIp`; -* ``X-Forwarded-For`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getClientIp`; -* ``X-Forwarded-Host`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getHost`; -* ``X-Forwarded-Port`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getPort`; -* ``X-Forwarded-Proto`` Used in :method:`Symfony\\Component\\HttpFoundation\\Request::getScheme` and :method:`Symfony\\Component\\HttpFoundation\\Request::isSecure`; - -If your reverse proxy uses a different header name for any of these, you -can configure that header name via :method:`Symfony\\Component\\HttpFoundation\\Request::setTrustedHeaderName`:: - - Request::setTrustedHeaderName(Request::HEADER_FORWARDED, 'X-Forwarded'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_IP, 'X-Proxy-For'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_HOST, 'X-Proxy-Host'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_PORT, 'X-Proxy-Port'); - Request::setTrustedHeaderName(Request::HEADER_CLIENT_PROTO, 'X-Proxy-Proto'); - -Not Trusting certain Headers ----------------------------- - -By default, if you whitelist your proxy's IP address, then all five headers -listed above are trusted. If you need to trust some of these headers but -not others, you can do that as well:: - - // disables trusting the ``Forwarded`` header - Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null); diff --git a/http_cache/varnish.rst b/http_cache/varnish.rst index 64df73241cb..43d4473b9f2 100644 --- a/http_cache/varnish.rst +++ b/http_cache/varnish.rst @@ -20,24 +20,9 @@ Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves the trusted proxy, Symfony will see all requests as coming through insecure HTTP connections from the Varnish host instead of the real client. -Remember to configure :ref:`framework.trusted_proxies ` -in the Symfony configuration so that Varnish is seen as a trusted proxy and the -:ref:`X-Forwarded ` headers are used. - -Varnish, in its default configuration, sends the ``X-Forwarded-For`` header but -does not filter out the ``Forwarded`` header. If you have access to the Varnish -configuration file, you can configure Varnish to remove the ``Forwarded`` -header: - -.. code-block:: varnish4 - - sub vcl_recv { - unset req.http.Forwarded; - } - -If you do not have access to your Varnish configuration, you can instead -configure Symfony to distrust the ``Forwarded`` header as detailed in -:ref:`How to Configure Symfony to Work behind a Load Balancer or a Reverse Proxy `. +Remember to call the :ref:`Request::setTrustedProxies() ` +method in your front controller so that Varnish is seen as a trusted proxy +and the :ref:`X-Forwarded-* ` headers are used. .. _varnish-x-forwarded-headers: diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 5d5887c1450..8249ec12eec 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -22,7 +22,6 @@ Configuration * `secret`_ * `http_method_override`_ -* `trusted_proxies`_ * `ide`_ * `test`_ * `default_locale`_ @@ -188,39 +187,7 @@ named ``kernel.http_method_override``. trusted_proxies ~~~~~~~~~~~~~~~ -**type**: ``array`` - -Configures the IP addresses that should be trusted as proxies. For more -details, see :doc:`/request/load_balancer_reverse_proxy`. - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/config.yml - framework: - trusted_proxies: [192.0.0.1, 10.0.0.0/8] - - .. code-block:: xml - - - - - - - - - .. code-block:: php - - // app/config/config.php - $container->loadFromExtension('framework', array( - 'trusted_proxies' => array('192.0.0.1', '10.0.0.0/8'), - )); +The ``trusted_proxies`` option was removed in Symfony 3.3. See :doc:`/request/load_balancer_reverse_proxy`. ide ~~~ diff --git a/request/load_balancer_reverse_proxy.rst b/request/load_balancer_reverse_proxy.rst index e1a4370ed56..f656d0e0527 100644 --- a/request/load_balancer_reverse_proxy.rst +++ b/request/load_balancer_reverse_proxy.rst @@ -7,66 +7,48 @@ an AWS Elastic Load Balancer) or a reverse proxy (e.g. Varnish for For the most part, this doesn't cause any problems with Symfony. But, when a request passes through a proxy, certain request information is sent using -either the standard ``Forwarded`` header or non-standard special ``X-Forwarded-*`` -headers. For example, instead of reading the ``REMOTE_ADDR`` header (which -will now be the IP address of your reverse proxy), the user's true IP will be -stored in a standard ``Forwarded: for="..."`` header or a non standard -``X-Forwarded-For`` header. +either the standard ``Forwarded`` header or ``X-Forwarded-*`` headers. For example, +instead of reading the ``REMOTE_ADDR`` header (which will now be the IP address of +your reverse proxy), the user's true IP will be stored in a standard ``Forwarded: for="..."`` +header or a ``X-Forwarded-For`` header. If you don't configure Symfony to look for these headers, you'll get incorrect information about the client's IP address, whether or not the client is connecting via HTTPS, the client's port and the hostname being requested. -Solution: trusted_proxies -------------------------- +.. _request-set-trusted-proxies: -This is no problem, but you *do* need to tell Symfony what is happening -and which reverse proxy IP addresses will be doing this type of thing: +Solution: setTrustedProxies() +----------------------------- -.. configuration-block:: +To fix this, you need to tell Symfony which reverse proxy IP addresses to trust +and what headers your reverse proxy uses to send information: - .. code-block:: yaml +.. code-block:: php - # app/config/config.yml - # ... - framework: - trusted_proxies: [192.0.0.1, 10.0.0.0/8] + // web/app.php - .. code-block:: xml + // ... + $request = Request::createFromGlobals(); - - - + // tell Symfony about your reverse proxy + Request::setTrustedProxies( + // the IP address (or range) of your proxy + ['192.0.0.1', '10.0.0.0/8'], - - - - + // trust *all* "X-Forwarded-*" headers + Request::HEADER_X_FORWARDED_ALL - .. code-block:: php + // or, if your proxy instead uses the "Forwarded" header + // Request::HEADER_FORWARDED - // app/config/config.php - $container->loadFromExtension('framework', array( - 'trusted_proxies' => array('192.0.0.1', '10.0.0.0/8'), - )); + // or, if you're using AWS ELB + // Request::HEADER_X_FORWARDED_AWS_ELB + ); -In this example, you're saying that your reverse proxy (or proxies) has -the IP address ``192.0.0.1`` or matches the range of IP addresses that use -the CIDR notation ``10.0.0.0/8``. For more details, see the -:ref:`framework.trusted_proxies ` option. - -You are also saying that you trust that the proxy does not send conflicting -headers, e.g. sending both ``X-Forwarded-For`` and ``Forwarded`` in the same -request. - -That's it! Symfony will now look for the correct headers to get information -like the client's IP address, host, port and whether the request is -using HTTPS. +The Request object has several ``Request::HEADER_*`` constants that control exactly +*which* headers from your reverse proxy are trusted. The argument is a bit field, +so you can also pass your own value (e.g. ``0b00110``). But what if the IP of my Reverse Proxy Changes Constantly! ---------------------------------------------------------- @@ -79,60 +61,24 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. other than your load balancers. For AWS, this can be done with `security groups`_. #. Once you've guaranteed that traffic will only come from your trusted reverse - proxies, configure Symfony to *always* trust incoming request. This is - done inside of your front controller: + proxies, configure Symfony to *always* trust incoming request: .. code-block:: diff // web/app.php // ... - $request = Request::createFromGlobals(); - + Request::setTrustedProxies(array('127.0.0.1', $request->server->get('REMOTE_ADDR'))); - - // ... + Request::setTrustedProxies( + // trust *all* requests + array('127.0.0.1', $request->server->get('REMOTE_ADDR')), -#. Ensure that the trusted_proxies setting in your ``app/config/config.yml`` - is not set or it will overwrite the ``setTrustedProxies()`` call above. + // if you're using ELB, otherwise use a constant from above + Request::HEADER_X_FORWARDED_AWS_ELB + ); That's it! It's critical that you prevent traffic from all non-trusted sources. If you allow outside traffic, they could "spoof" their true IP address and other information. -.. _request-untrust-header: - -My Reverse Proxy Sends X-Forwarded-For but Does not Filter the Forwarded Header -------------------------------------------------------------------------------- - -Many popular proxy implementations do not yet support the ``Forwarded`` header -and do not filter it by default. Ideally, you would configure this in your -proxy. If this is not possible, you can tell Symfony to distrust the ``Forwarded`` -header, while still trusting your proxy's ``X-Forwarded-For`` header. - -This is done inside of your front controller:: - - // web/app.php - - // ... - Request::setTrustedHeaderName(Request::HEADER_FORWARDED, null); - - $response = $kernel->handle($request); - // ... - -Configuring the proxy server trust is very important, as not doing so will -allow malicious users to "spoof" their IP address. - -My Reverse Proxy Uses Non-Standard (not X-Forwarded) Headers ------------------------------------------------------------- - -Although `RFC 7239`_ recently defined a standard ``Forwarded`` header to disclose -all proxy information, most reverse proxies store information in non-standard -``X-Forwarded-*`` headers. - -But if your reverse proxy uses other non-standard header names, you can configure -these (see ":doc:`/components/http_foundation/trusting_proxies`"). - -The code for doing this will need to live in your front controller (e.g. ``web/app.php``). - .. _`security groups`: http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html .. _`RFC 7239`: http://tools.ietf.org/html/rfc7239