diff options
-rw-r--r-- | docs/reverse-proxy.rst | 141 |
1 files changed, 49 insertions, 92 deletions
diff --git a/docs/reverse-proxy.rst b/docs/reverse-proxy.rst index 2532180..42f8352 100644 --- a/docs/reverse-proxy.rst +++ b/docs/reverse-proxy.rst @@ -1,4 +1,4 @@ -..index:: reverse, proxy, TLS, SSL, https +.. index:: reverse, proxy, TLS, SSL, https .. _using-behind-a-reverse-proxy: @@ -15,7 +15,8 @@ proxies often have lots of useful deployment knobs. If you're using Waitress behind a reverse proxy, you'll almost always want your reverse proxy to pass along the ``Host`` header sent by the client to Waitress, in either case, as it will be used by most applications to generate -correct URLs. +correct URLs. You may also use the proxy headers if passing the Host directly +is not possible, or there are multiple proxies involved. For example, when using nginx as a reverse proxy, you might add the following lines in a ``location`` section. @@ -39,15 +40,9 @@ application. You can do this in one of three ways: 1. You can pass a ``url_scheme`` configuration variable to the ``waitress.serve`` function. -2. You can configure the proxy reverse server to pass a header, - ``X_FORWARDED_PROTO``, whose value will be set for that request as - the ``wsgi.url_scheme`` environment value. Note that you must also - conigure ``waitress.serve`` by passing the IP address of that proxy - as its ``trusted_proxy``. - -3. You can use Paste's ``PrefixMiddleware`` in conjunction with - configuration settings on the reverse proxy server. - +2. You can pass certain well known proxy headers from your proxy server and + use waitress's ``trusted_proxy`` support to automatically configure the + WSGI environment. Using ``url_scheme`` to set ``wsgi.url_scheme`` ----------------------------------------------- @@ -62,25 +57,58 @@ You can have the Waitress server use the ``https`` url scheme by default.: This works if all URLs generated by your application should use the ``https`` scheme. -Passing the ``X_FORWARDED_PROTO`` header to set ``wsgi.url_scheme`` -------------------------------------------------------------------- +Passing the proxy headers to setup the WSGI environment +------------------------------------------------------- If your proxy accepts both HTTP and HTTPS URLs, and you want your application -to generate the appropriate url based on the incoming scheme, also set up -your proxy to send a ``X-Forwarded-Proto`` with the original URL scheme along -with each proxied request. For example, when using nginx:: +to generate the appropriate url based on the incoming scheme, you'll want to +pass waitress ``X-Forwarded-Proto``, however Waitress is also able to update +the environment using ``X-Forwarded-Proto``, ``X-Forwarded-For``, +``X-Forwarded-Host``, and ``X-Forwarded-Port``:: + + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Host $host:$server_port; + proxy_set_header X-Forwarded-Port $server_port; + +when using Apache, ``mod_proxy`` automatically forwards the following headers:: - proxy_set_header X-Forwarded-Proto $scheme; + X-Forwarded-For + X-Forwarded-Host + X-Forwarded-Server -or via Apache:: +You will also want to add for Apache:: RequestHeader set X-Forwarded-Proto https +Configure waitress's ``trusted_proxy_headers`` as appropriate:: + + trusted_proxy_headers = "x-forwarded-for, x-forwarded-host, x-forwarded-proto, x-forwarded-port" + +At this point waitress will set up the WSGI environment using the information +sent in the proxy headers. This will setup the following variables:: + + HTTP_HOST + SERVER_NAME + SERVER_PORT + REMOTE_ADDR + REMOTE_PORT (if available) + wsgi.url_scheme + +Waitress also has support for the `Forwarded (RFC7239) HTTP header +<https://tools.ietf.org/html/rfc7239>`_ which is better defined than the ad-hoc +``X-Forwarded-*``, however support is not nearly as widespread yet. +``Forwarded`` supports similar functionality as the different individual +headers, and is mutually exclusive to using the ``X-Forwarded-*`` headers. + +To configure waitress to use the ``Forwarded`` header, set:: + + trusted_proxy_headers = "forwarded" + .. note:: - You must also configure the Waitress server's ``trusted_proxy`` to - contain the IP address of the proxy in order for this header to override - the default URL scheme. + You must also configure the Waitress server's ``trusted_proxy`` and + to contain the IP address of the proxy Using ``url_prefix`` to influence ``SCRIPT_NAME`` and ``PATH_INFO`` @@ -101,74 +129,3 @@ it will cause the ``PATH_INFO`` of any request which is prefixed with this value to be stripped of the prefix. This is useful in proxying scenarios where you wish to forward all traffic to a Waitress server but need URLs generated by downstream applications to be prefixed with a particular path segment. - - -Using Paste's ``PrefixMiddleware`` to set ``wsgi.url_scheme`` -------------------------------------------------------------- - -If only some of the URLs generated by your application should use the -``https`` scheme (and some should use ``http``), you'll need to use Paste's -``PrefixMiddleware`` as well as change some configuration settings on your -proxy. To use ``PrefixMiddleware``, wrap your application before serving it -using Waitress: - -.. code-block:: python - - from waitress import serve - from paste.deploy.config import PrefixMiddleware - app = PrefixMiddleware(app) - serve(app) - -Once you wrap your application in the the ``PrefixMiddleware``, the -middleware will notice certain headers sent from your proxy and will change -the ``wsgi.url_scheme`` and possibly other WSGI environment variables -appropriately. - -Once your application is wrapped by the prefix middleware, you should -instruct your proxy server to send along the original ``Host`` header from -the client to your Waitress server, as well as sending along a -``X-Forwarded-Proto`` header with the appropriate value for -``wsgi.url_scheme``. - -If your proxy accepts both HTTP and HTTPS URLs, and you want your application -to generate the appropriate url based on the incoming scheme, also set up -your proxy to send a ``X-Forwarded-Proto`` with the original URL scheme along -with each proxied request. For example, when using nginx. - -.. code-block:: nginx - - proxy_set_header X-Forwarded-Proto $scheme; - -It's permitted to set an ``X-Forwarded-For`` header too; the -``PrefixMiddleware`` uses this to adjust other environment variables (you'll -have to read its docs to find out which ones, I don't know what they are). For -the ``X-Forwarded-For`` header. - -.. code-block:: nginx - - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - -Note that you can wrap your application in the PrefixMiddleware declaratively -in a :term:`PasteDeploy` configuration file too, if your web framework uses -PasteDeploy-style configuration: - -.. code-block:: ini - - [app:myapp] - use = egg:mypackage#myapp - - [filter:paste_prefix] - use = egg:PasteDeploy#prefix - - [pipeline:main] - pipeline = - paste_prefix - myapp - - [server:main] - use = egg:waitress#main - listen = 127.0.0.1:8080 - -Note that you can also set ``PATH_INFO`` and ``SCRIPT_NAME`` using -PrefixMiddleware too (its original purpose, really) instead of using Waitress' -``url_prefix`` adjustment. See the PasteDeploy docs for more information. |