Skip to content

Commit 35a0f66

Browse files
committed
feature #4102 Adding a new entry about reverse proxies in the framework (weaverryan)
This PR was merged into the 2.3 branch. Discussion ---------- Adding a new entry about reverse proxies in the framework Hi guys! | Q | A | ------------- | --- | Doc fix? | no | New docs? | no | Applies to | all (or 2.3+) | Fixed tickets | #2946 #2491 Per #2491, I wanted to answer the simple question: "What do I need to do in order to configure Symfony if I have a reverse proxy". The `trusted_proxies` is already documented in the reference section, but this is a full walk-through of what you should be doing and why. I've also increased links in several places where notes are needed. Thanks! Commits ------- 5ab6c4a Title case fix thanks to @xabbuh! 89e4d9d A bunch of changes thanks to @xabbuh and @stof 81053ab Fixing build error c55bc2e Adding another note about how AppCache is a reverse proxy at the IP address 127.0.0.1 18af4e8 Adding a new entry about reverse proxies in the framework and linking to it in many places
2 parents 3ffc20f + 5ab6c4a commit 35a0f66

File tree

7 files changed

+126
-3
lines changed

7 files changed

+126
-3
lines changed

book/http_cache.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,10 @@ kernel::
162162
The caching kernel will immediately act as a reverse proxy - caching responses
163163
from your application and returning them to the client.
164164

165+
Now that you're using a "proxy", you'll need to configure ``127.0.0.1`` under
166+
the ``trusted_proxies`` configuration (see :ref:`reference <reference-framework-trusted-proxies>`).
167+
Without this, the client's IP address and a few other things won't report correctly.
168+
165169
.. tip::
166170

167171
The cache kernel has a special ``getLog()`` method that returns a string
@@ -1005,8 +1009,8 @@ possible.
10051009

10061010
.. tip::
10071011

1008-
The listener only responds to local IP addresses or trusted
1009-
proxies.
1012+
The listener only responds to local IP addresses or
1013+
:doc:`trusted proxies </cookbook/request/load_balancer_reverse_proxy>`.
10101014

10111015
.. note::
10121016

components/http_foundation/trusting_proxies.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
Trusting Proxies
55
================
66

7+
.. tip::
8+
9+
If you're using the Symfony Framework, start by reading
10+
:doc:`/cookbook/request/load_balancer_reverse_proxy`.
11+
712
If you find yourself behind some sort of proxy - like a load balancer - then
813
certain header information may be sent to you using special ``X-Forwarded-*``
914
headers. For example, the ``Host`` HTTP header is usually used to return

cookbook/cache/varnish.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ Because Symfony2's cache uses the standard HTTP cache headers, the
99
proxy. `Varnish`_ is a powerful, open-source, HTTP accelerator capable of serving
1010
cached content quickly and including support for :ref:`Edge Side Includes <edge-side-includes>`.
1111

12+
Trusting Reverse Proxies
13+
------------------------
14+
15+
For ESI to work correctly and for the :ref:`X-FORWARDED <varnish-x-forwarded-headers>`
16+
headers to be used, you need to configure Varnish as a
17+
:doc:`trusted proxy </cookbook/request/load_balancer_reverse_proxy>`.
18+
1219
.. index::
1320
single: Varnish; configuration
1421

@@ -188,6 +195,8 @@ that will invalidate the cache for a given resource:
188195
}
189196
}
190197
198+
.. _varnish-x-forwarded-headers:
199+
191200
Routing and X-FORWARDED Headers
192201
-------------------------------
193202

cookbook/map.rst.inc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113

114114
* :doc:`/cookbook/request/index`
115115

116+
* :doc:`/cookbook/request/load_balancer_reverse_proxy`
116117
* :doc:`/cookbook/request/mime_type`
117118
* (session) :doc:`/cookbook/session/locale_sticky_session`
118119

cookbook/request/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ Request
44
.. toctree::
55
:maxdepth: 2
66

7+
load_balancer_reverse_proxy
78
mime_type
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
How to Configure Symfony to Work behind a Load Balancer or Reverse Proxy
2+
========================================================================
3+
4+
When you deploy your application, you may be behind a load balancer (e.g.
5+
an AWS Elastic Load Balancer) or a reverse proxy (e.g. Varnish for
6+
:doc:`caching</book/http_cache>`).
7+
8+
For the most part, this doesn't cause any problems with Symfony. But, when
9+
a request passes through a proxy, certain request information is sent using
10+
special ``X-Forwarded-*`` headers. For example, instead of reading the ``REMOTE_ADDR``
11+
header (which will now be the IP address of your reverse proxy), the user's
12+
true IP will be stored in an ``X-Forwarded-For`` header.
13+
14+
.. tip::
15+
16+
If you're using Symfony's :ref:`AppCache<symfony-gateway-cache>` for caching,
17+
then you *are* using a reverse proxy with the IP address ``127.0.0.1``.
18+
You'll need to configure that address as a trusted proxy below.
19+
20+
If you don't configure Symfony to look for these headers, you'll get incorrect
21+
information about the client's IP address, whether or not the client is connecting
22+
via HTTPS, the client's port and the hostname being requested.
23+
24+
Solution: trusted_proxies
25+
-------------------------
26+
27+
This is no problem, but you *do* need to tell Symfony that this is happening
28+
and which reverse proxy IP addresses will be doing this type of thing:
29+
30+
.. configuration-block::
31+
32+
.. code-block:: yaml
33+
34+
# app/config/config.yml
35+
# ...
36+
framework:
37+
trusted_proxies: [192.0.0.1, 10.0.0.0/8]
38+
39+
.. code-block:: xml
40+
41+
<!-- app/config/config.xml -->
42+
<?xml version="1.0" encoding="UTF-8" ?>
43+
<container xmlns="http://symfony.com/schema/dic/services"
44+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
45+
xmlns:framework="http://symfony.com/schema/dic/symfony"
46+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
47+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
48+
49+
<framework:config trusted-proxies="192.0.0.1, 10.0.0.0/8">
50+
<!-- ... -->
51+
</framework>
52+
</container>
53+
54+
.. code-block:: php
55+
56+
// app/config/config.php
57+
$container->loadFromExtension('framework', array(
58+
'trusted_proxies' => array('192.0.0.1', '10.0.0.0/8'),
59+
));
60+
61+
In this example, you're saying that your reverse proxy (or proxies) has
62+
the IP address ``192.0.0.1`` or matches the range of IP addresses that use
63+
the CIDR notation ``10.0.0.0/8``. For more details, see :ref:`reference-framework-trusted-proxies`.
64+
65+
That's it! Symfony will now look for the correct ``X-Forwarded-*`` headers
66+
to get information like the client's IP address, host, port and whether or
67+
not the request is using HTTPS.
68+
69+
But what if the IP of my Reverse Proxy Changes Constantly!
70+
----------------------------------------------------------
71+
72+
Some reverse proxies (like Amazon's Elastic Load Balancers) don't have a
73+
static IP address or even a range that you can target with the CIDR notation.
74+
In this case, you'll need to - *very carefully* - trust *all* proxies.
75+
76+
1. Configure your web server(s) to *not* respond to traffic from *any* clients
77+
other than your load balancers. For AWS, this can be done with `security groups`_.
78+
79+
1. Once you've guaranteed that traffic will only come from your trusted reverse
80+
proxies, configure Symfony to *always* trust incoming request. This is
81+
done inside of your front controller::
82+
83+
// web/app.php
84+
// ...
85+
86+
Request::setTrustedProxies(array($request->server->get('REMOTE_ADDR')));
87+
88+
$response = $kernel->handle($request);
89+
// ...
90+
91+
That's it! It's critical that you prevent traffic from all non-trusted sources.
92+
If you allow outside traffic, they could "spoof" their true IP address and
93+
other information.
94+
95+
My Reverse Proxy Uses Non-Standard (not X-Forwarded) Headers
96+
------------------------------------------------------------
97+
98+
Most reverse proxies store information on specific ``X-Forwarded-*`` headers.
99+
But if your reverse proxy uses non-standard header names, you can configure
100+
these (:doc:`see reference </components/http_foundation/trusting_proxies>`.
101+
The code for doing this will need to live in your front controller (e.g. ``web/app.php``).
102+
103+
.. _`security groups`: http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-elb-security-groups.html

reference/configuration/framework.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ trusted_proxies
145145
**type**: ``array``
146146

147147
Configures the IP addresses that should be trusted as proxies. For more details,
148-
see :doc:`/components/http_foundation/trusting_proxies`.
148+
see :doc:`/cookbook/request/load_balancer_reverse_proxy`.
149149

150150
.. versionadded:: 2.3
151151
CIDR notation support was introduced in Symfony 2.3, so you can whitelist whole

0 commit comments

Comments
 (0)