From 18af4e8ec6e2a1892cd94b6c9a714274733b4b44 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 7 Aug 2014 11:04:42 -0400 Subject: [PATCH] Adding a new entry about reverse proxies in the framework and linking to it in many places --- book/http_cache.rst | 9 +- .../http_foundation/trusting_proxies.rst | 5 + cookbook/cache/varnish.rst | 9 ++ cookbook/map.rst.inc | 1 + cookbook/request/index.rst | 1 + .../request/load_balancer_reverse_proxy.rst | 91 +++++++++++++++++++ reference/configuration/framework.rst | 2 +- 7 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 cookbook/request/load_balancer_reverse_proxy.rst diff --git a/book/http_cache.rst b/book/http_cache.rst index 53943266ac7..9777b8a6396 100644 --- a/book/http_cache.rst +++ b/book/http_cache.rst @@ -162,6 +162,11 @@ kernel:: The caching kernel will immediately act as a reverse proxy - caching responses from your application and returning them to the client. +Now that you're using a "proxy", you'll need to configure ``127.0.0.1`` under +the ``trusted_proxies`` configuration. See +:ref:`framework.trusted_proxies `. Without +this, the client's IP address and a few other things won't report correctly. + .. tip:: The cache kernel has a special ``getLog()`` method that returns a string @@ -1005,8 +1010,8 @@ possible. .. tip:: - The listener only responds to local IP addresses or trusted - proxies. + The listener only responds to local IP addresses or + :doc:`trusted proxies`. .. note:: diff --git a/components/http_foundation/trusting_proxies.rst b/components/http_foundation/trusting_proxies.rst index 5ce8f888c50..67ffe2a956a 100644 --- a/components/http_foundation/trusting_proxies.rst +++ b/components/http_foundation/trusting_proxies.rst @@ -4,6 +4,11 @@ Trusting Proxies ================ +.. tip:: + + If you're using the Symfony Framework, start by reading + :doc:`/cookbookrequest/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. For example, the ``Host`` HTTP header is usually used to return diff --git a/cookbook/cache/varnish.rst b/cookbook/cache/varnish.rst index 5a80b034188..483cc6b4982 100644 --- a/cookbook/cache/varnish.rst +++ b/cookbook/cache/varnish.rst @@ -9,6 +9,13 @@ Because Symfony2's cache uses the standard HTTP cache headers, the proxy. `Varnish`_ is a powerful, open-source, HTTP accelerator capable of serving cached content quickly and including support for :ref:`Edge Side Includes `. +Trusting Reverse Proxies +------------------------ + +For ESI to work correctly and for the :ref:`X-FORWARDED` +headers to be used, you need to configure Varnish as a +:doc:`trusted proxy`. + .. index:: single: Varnish; configuration @@ -188,6 +195,8 @@ that will invalidate the cache for a given resource: } } +.. _varnish-x-forwarded-headers: + Routing and X-FORWARDED Headers ------------------------------- diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 5399f3f637e..20992e334b9 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -113,6 +113,7 @@ * :doc:`/cookbook/request/index` + * :doc:`/cookbook/request/load_balancer_reverse_proxy` * :doc:`/cookbook/request/mime_type` * (session) :doc:`/cookbook/session/locale_sticky_session` diff --git a/cookbook/request/index.rst b/cookbook/request/index.rst index 4df7f7eb2d8..018f778e153 100644 --- a/cookbook/request/index.rst +++ b/cookbook/request/index.rst @@ -4,4 +4,5 @@ Request .. toctree:: :maxdepth: 2 + load_balancer_reverse_proxy mime_type diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst new file mode 100644 index 00000000000..4dee539a481 --- /dev/null +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -0,0 +1,91 @@ +How to Configure Symfony to Work behind a Load Balancer or Reverse Proxy +======================================================================== + +When you deploy your application, you may be behind a load balancer (e.g. +an AWS Elastic Load Balancer) or a reverse proxy (e.g. Varnish for +:doc:`caching`). + +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 +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 ``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 +------------------------- + +This is no problem, but you *do* need to tell Symfony that this is happening +and which reverse proxy IP addresses will be doing this type of thing: + +.. 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'), + )); + +In this example, you're saying that your reverse proxy (or proxies) have +the IP address ``192.0.0.1`` or match the range of IP addresses that use +the CIDR notation ``10.0.0.0/8``. For more details, see :ref:`reference-framework-trusted-proxies`. + +That's it! Symfony will now look for the correct ``X-Forwarded-*`` headers +to get information like the client's IP address, host, port and whether or +not the request is using HTTPS. + +But I the IP of my Reverse Proxy Changes Constantly! +---------------------------------------------------- + +Some reverse proxies (like Amazon's Elastic Load Balancers) don't have a +static IP address or even a range that you can target with the CIDR notation. +In this case, you'll need to - *very carefully* - trust *all* proxies. + +1. Configure your web server(s) to not respond to traffic from *any* servers + other than your load balancers. For AWS, this can be done with `security groups`_. + +1. 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: + +.. code-block:: php + + // web/app.php + // ... + + Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR'))); + + $response = $kernel->handle($request); + // ... + +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 true IP address +and other information. + +My Reverse Proxy Uses Non-Standard (not X-Forwarded-*) Headers +-------------------------------------------------------------- + +Most reverse proxies store information on specific ``X-Forwarded-*`` headers. +But if your reverse proxy uses 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/DeveloperGuide/using-elb-security-groups.html diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 3b2a21c0d87..3339381e271 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -145,7 +145,7 @@ trusted_proxies **type**: ``array`` Configures the IP addresses that should be trusted as proxies. For more details, -see :doc:`/components/http_foundation/trusting_proxies`. +see :doc:`/cookbook/request/load_balancer_reverse_proxy`. .. versionadded:: 2.3 CIDR notation support was introduced in Symfony 2.3, so you can whitelist whole