Reverse proxy configuration help

Jonathan Matthews contact at
Mon Feb 18 17:03:04 UTC 2013

On 18 February 2013 15:06, jims <nginx-forum at> wrote:
> I am new to nginx, it being recommended to solve a problem.

[ Having read your mail, this kind of reverse proxying is exactly what
nginx is very good at; I think you're just trying to do too much, too
quickly, and need to step back from the problem for a moment to
identify what your first steps should be; then iterate from simple to
complex behaviours, only moving forward once each behaviour works
successfully. ]

> The problem:  I have a VPS hosting a website and an application server in my
> DMZ.  I have a test and prod version of each.  I want both DMZ'ed servers
> reverse-proxied such that requests where the referrer is the test web server
> always go to the test app server and requests where the referrer is anything
> but the test web server always go to the production app server.

When you say "referrer", do you really mean the referrer as
distinguished by client-originated HTTP headers? I wouldn't do that,
personally ...

> The app servers can only be accessed over https, and the proxy will
> eventually but not quite yet.

That last part may be more of an issue for you, as you'll discover you
need an IP address per SSL site you want to host.

> Question:  What is the best way to accomplish this?  I am trying to use two
> different registered host names which are registered to the secondary IP on
> the VPS, as the proxied names for the app servers, but that's not working
> too well.  I wonder if it would be better to have a single server name for
> the proxy with the two proxied servers selected based on referrer, rather
> than trying to redirect to another server name, with one server name
> servicing one proxied server and the other, the other proxied server.

Goodness, no. I wouldn't /touch/ referer headers for HTTP routing. So

> Regardless, I can't seem to get past the connection to the backend server.
> I keep getting a 110 connection failure.  I have tried several
> configurations but none seem to work.

What does a connection, via telnet/netcat, from the server, show you?

> The problem I'm running into may be related to use of the valid_referers
> directive.  It doesn't seem to do what I need, which is to use one back-end
> for requests referred from one web server host but use the other for all
> other requests.

I may be repeating a single tune here, but I would really force your
business to re-examine your requirements if you think this is
desirable behaviour.

> If I have two server directives with the same IP but two different server
> names, it seems I can't have two location directives, one within each server
> name.

Each server may have zero or more location directives.
Each location belongs to exactly one server stanza.

I don't understand exactly what you think doesn't work, but if it
contradicts the above 2 lines, then it's not legal nginx config.

>  If I could get that to work, it seems to me it should allow me to
> redirect to the default app server using the valid_referers directive within
> the referrer-specific app server's server directive, but that doesn't seem
> to work the way I expect, either.

When you say "redirect" here, you really mean "reverse proxy", don't you?
"Redirecting" is a very specific, unrelated thing in HTTP-server-speak ...

> I don't have a config file to post because it has gone through a dozen
> iterations already, none of which have been saved.

apt-get install git-core :-P

> A generic example of
> one that doesn't work would be :
> server {
>    listen;
>    server_name;
>    valid_referers;
>      if ($invalid_referer) {
>         return   301$request_uri;
>       }
>   proxy_bind;
>   access_log /var/log/nginx/devpxyaccess.log main;
>   error_log /var/log/nginx/devpxyerror.log debug;
>   location / {
>       proxy_pass;
>       proxy_redirect / ;
>    }
> }
> server {
>   listen ;
>   server_name ;
>   proxy_bind ;
>   access_log /var/log/nginx/pxyaccess.log main ;
>   error_log /var/log/nginx/pxyerror.log debug ;
>   location / {
>       proxy_pass ;
>       proxy_redirect / ;
>   }
> }

The only real problem I can see is that you don't have a resolver
specified, so nginx doesn't know how to resolve the app FQDNs.
Irrespective of this, there are much nicer ways to achieve this, which
might use:

* Nginx maps to translate from client Host header to backend FQDN.
* Access/error logs specified using variables, but DRY them out at a
higher level than per-server (i.e. state them once, globally, at the
http level.
* A single server stanza, switching between backends.

I could write a version that uses these concepts for you, but I'd be
depriving you of the educational and life-affirming journey of Getting
There Yourself if I did ;-)

If you want to get the best possible help with this, reduce the
clutter in your example/failing config (i.e. make the smallest
possible config that doesn't do what you think it /should/ do), and
re-engage with the list.

> When I do that it says "location" directive isn't allowed here...

When you do what?

Jonathan Matthews // Oxford, London, UK

More information about the nginx mailing list