From 18af4e8ec6e2a1892cd94b6c9a714274733b4b44 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 7 Aug 2014 11:04:42 -0400 Subject: [PATCH 1/5] 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 From c55bc2e0b2cef20b12099659efb0fb4cf3245a1d Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 7 Aug 2014 11:16:57 -0400 Subject: [PATCH 2/5] Adding another note about how AppCache is a reverse proxy at the IP address 127.0.0.1 --- cookbook/request/load_balancer_reverse_proxy.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst index 4dee539a481..a75d68e7abc 100644 --- a/cookbook/request/load_balancer_reverse_proxy.rst +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -11,6 +11,12 @@ special ``X-Forwarded-*`` headers. For example, instead of reading the ``REMOTE_ 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. +.. tip:: + + If your using Symfonys :ref:`AppCache` for caching, + then you *are* using a reverse proxy with the IP address ``127.0.0.1``. + You'll need to configure that address as a trusted proxy below. + 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. From 81053abf48d34c54ee9feadb02494c87ae22bd8d Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 7 Aug 2014 11:18:32 -0400 Subject: [PATCH 3/5] Fixing build error --- cookbook/request/load_balancer_reverse_proxy.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst index a75d68e7abc..f9cc3e1fcb5 100644 --- a/cookbook/request/load_balancer_reverse_proxy.rst +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -86,8 +86,8 @@ 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 --------------------------------------------------------------- +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 From 89e4d9d2fbe025f0c26c0a78240fb1c9c13e7148 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 7 Aug 2014 13:28:25 -0400 Subject: [PATCH 4/5] A bunch of changes thanks to @xabbuh and @stof --- book/http_cache.rst | 7 ++-- .../http_foundation/trusting_proxies.rst | 2 +- cookbook/cache/varnish.rst | 4 +- .../request/load_balancer_reverse_proxy.rst | 42 +++++++++++-------- 4 files changed, 30 insertions(+), 25 deletions(-) diff --git a/book/http_cache.rst b/book/http_cache.rst index 9777b8a6396..4b25eda1ebd 100644 --- a/book/http_cache.rst +++ b/book/http_cache.rst @@ -163,9 +163,8 @@ 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. +the ``trusted_proxies`` configuration (see :ref:`reference `). +Without this, the client's IP address and a few other things won't report correctly. .. tip:: @@ -1011,7 +1010,7 @@ possible. .. tip:: The listener only responds to local IP addresses or - :doc:`trusted proxies`. + :doc:`trusted proxies `. .. note:: diff --git a/components/http_foundation/trusting_proxies.rst b/components/http_foundation/trusting_proxies.rst index 67ffe2a956a..61d4448914f 100644 --- a/components/http_foundation/trusting_proxies.rst +++ b/components/http_foundation/trusting_proxies.rst @@ -7,7 +7,7 @@ Trusting Proxies .. tip:: If you're using the Symfony Framework, start by reading - :doc:`/cookbookrequest/load_balancer_reverse_proxy`. + :doc:`/cookbook/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-*`` diff --git a/cookbook/cache/varnish.rst b/cookbook/cache/varnish.rst index 483cc6b4982..03c0b690381 100644 --- a/cookbook/cache/varnish.rst +++ b/cookbook/cache/varnish.rst @@ -12,9 +12,9 @@ cached content quickly and including support for :ref:`Edge Side Includes ` +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`. +:doc:`trusted proxy `. .. index:: single: Varnish; configuration diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst index f9cc3e1fcb5..896995e84bd 100644 --- a/cookbook/request/load_balancer_reverse_proxy.rst +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -9,11 +9,11 @@ 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. +true IP will be stored in an ``X-Forwarded-For`` header. .. tip:: - If your using Symfonys :ref:`AppCache` for caching, + If you're using Symfony's :ref:`AppCache` for caching, then you *are* using a reverse proxy with the IP address ``127.0.0.1``. You'll need to configure that address as a trusted proxy below. @@ -38,10 +38,18 @@ and which reverse proxy IP addresses will be doing this type of thing: .. code-block:: xml - - - - + + + + + + + + .. code-block:: php @@ -50,29 +58,27 @@ and which reverse proxy IP addresses will be doing this type of thing: '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 +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 :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! ----------------------------------------------------- +But What if 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 +1. Configure your web server(s) to *not* respond to traffic from *any* clients 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 + done inside of your front controller:: // web/app.php // ... @@ -83,15 +89,15 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. // ... 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. +If you allow outside traffic, they could "spoof" their 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``). +these (:doc:`see reference `. +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 From 5ab6c4abb0675a114923896dc8761e97641b2188 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Fri, 8 Aug 2014 13:18:41 -0400 Subject: [PATCH 5/5] Title case fix thanks to @xabbuh! --- cookbook/request/load_balancer_reverse_proxy.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/request/load_balancer_reverse_proxy.rst b/cookbook/request/load_balancer_reverse_proxy.rst index 896995e84bd..d8e81f73bc3 100644 --- a/cookbook/request/load_balancer_reverse_proxy.rst +++ b/cookbook/request/load_balancer_reverse_proxy.rst @@ -66,7 +66,7 @@ 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 What if the IP of my Reverse Proxy Changes Constantly! +But what if the IP of my Reverse Proxy Changes Constantly! ---------------------------------------------------------- Some reverse proxies (like Amazon's Elastic Load Balancers) don't have a