# Reverse proxy configuration help

**URL:** <https://www.ruby-forum.com/t/reverse-proxy-configuration-help/226699>\
**Category:** NGINX\
**Created:** [February 18, 2013, 4:06pm UTC](https://www.ruby-forum.com/t/reverse-proxy-configuration-help/226699 "2013-02-18T16:06:34Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jims](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/838e76/32.png) [@jims](https://www.ruby-forum.com/u/jims)\
**Post date:** [February 18, 2013, 4:06pm UTC](https://www.ruby-forum.com/t/reverse-proxy-configuration-help/226699/1 "2013-02-18T16:06:34Z")

</div>

I am new to nginx, it being recommended to solve a problem.

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.

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

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.

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.

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.

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. 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.

I don’t have a config file to post because it has gone through a dozen  
iterations already, none of which have been saved. A generic example  
of  
one that doesn’t work would be :

server {  
listen 10.10.10.10:80;  
server\_name [devappxy.mydomain.com](http://devappxy.mydomain.com);  
valid\_referers [devweb.mydomain.com](http://devweb.mydomain.com);  
if ($invalid\_referer) {  
return 301 http://apppxy.mydomain.com$request\_uri;  
}  
proxy\_bind 10.10.10.10;  
access\_log /var/log/nginx/devpxyaccess.log main;  
error\_log /var/log/nginx/devpxyerror.log debug;  
location / {  
proxy\_pass [https://devapp.mydomain.com](https://devapp.mydomain.com);  
proxy\_redirect [https://devapp.mydomain.com](https://devapp.mydomain.com) / ;  
}  
}  
server {  
listen 10.10.10.10:80 ;  
server\_name [apppxy.mydomain.com](http://apppxy.mydomain.com) ;  
proxy\_bind 10.10.10.10 ;  
access\_log /var/log/nginx/pxyaccess.log main ;  
error\_log /var/log/nginx/pxyerror.log debug ;  
location / {  
proxy\_pass [https://prodapp.mydomain.com](https://prodapp.mydomain.com) ;  
proxy\_redirect [https://prodapp.mydomain.com](https://prodapp.mydomain.com) / ;  
}  
}

When I do that it says “location” directive isn’t allowed here…

Posted at Nginx Forum:

> **[Reverse proxy configuration help](https://forum.nginx.org/read.php?2,236278,236278#msg-236278)**
>
> I am new to nginx, it being recommended to solve a problem. 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...

---

<div class="post-metadata">

**Author:** ![jims](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/838e76/32.png) [@jims](https://www.ruby-forum.com/u/jims)\
**Post date:** [February 18, 2013, 6:03pm UTC](https://www.ruby-forum.com/t/reverse-proxy-configuration-help/226699/2 "2013-02-18T18:03:32Z")

</div>

On 18 February 2013 15:06, jims [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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  
unreliable!

> 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 😛

> access\_log /var/log/nginx/devpxyaccess.log main;  
> access\_log /var/log/nginx/pxyaccess.log main ;  
> error\_log /var/log/nginx/pxyerror.log debug ;  
> location / {  
> proxy\_pass [https://prodapp.mydomain.com](https://prodapp.mydomain.com) ;  
> proxy\_redirect [https://prodapp.mydomain.com](https://prodapp.mydomain.com) / ;  
> }  
> }

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

Jonathan M. // Oxford, London, UK

> **[Jonathan Matthews :: Words Typed, Great Rates For Cash](https://www.jpluscplusm.com)**

---

<div class="post-metadata">

**Author:** ![jims](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/838e76/32.png) [@jims](https://www.ruby-forum.com/u/jims)\
**Post date:** [February 19, 2013, 1:27pm UTC](https://www.ruby-forum.com/t/reverse-proxy-configuration-help/226699/3 "2013-02-19T13:27:59Z")

</div>

## Jonathan M. Wrote:

> On 18 February 2013 15:06, jims [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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. ]

Point taken. Going straight for the desired end result doesn’t always  
save  
time…

Thanks for your response, Jonathan. It has been helpful. Read on for  
responses to your comments…

> When you say “referrer”, do you really mean the referrer as  
> distinguished by client-originated HTTP headers? I wouldn’t do that,  
> personally …

When I say “referrer” I mean the site where the link is presented to the  
end  
user. If that is what is “distinguished by client-originated HTTP  
headers”  
then yes.  
The desired result is that if a person is in our pool of testers and is  
testing the development website, any app server link (although pointing  
putatively to the production app server) would be sent to the  
reverse-proxy  
that’s front-ending the test app server. The idea is to minimize  
unauthorized traffic to the test server. By using only links that get  
to  
the production app server, if someone saves the link and tries again  
later,  
they will hit the production app server’s reverse-proxy front-end. They  
would only hit our test app server if they are actively testing for us.  
Once testing is complete, the proven code can be promoted to te  
production  
webste without having to deal with changing test links to prod links in  
the  
process Those who will be maintaining the links ongoing should not be  
expected either to change links as part of a move-to-production or to  
have  
to learn how to put variables into all the links, and we would not have  
to  
modify the CMS to handle links with variables - they should be able to  
copy  
and paste to create links, which resulting content should be able to be  
promoted to production without change, or it defeats the purpose of  
using a  
modern content-management system.

> > 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.

Normally, yes, and each of the app server hostnames has its own  
registered  
IP address now, with trusted certs associated. We are working on  
obtaining  
a wildcard cert which we’d use for the proxy as well as the website, and  
will add IP addresses to the proxy if necessary. I would hope that,  
since  
we want the proxy to choose between two back-end app servers for the  
same  
front-end uri, depending on whether or not there is a referrer of the  
development website, one IP should be all that’s needed on the  
front-end,  
correct?

> > 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  
> unreliable!

OK. How would you recommend ensuring that if you click on a link on our  
dev  
site, it goes to the proxied test app server but if you access that same  
URL  
in any other way, whether by way of a link on the prod website, a  
bookmark,  
someone emailing you the link - the request goes to the proxied prod app  
server? As I said, I’m an nginx newb, so monosyllabic responses are  
appreciated… 😉

> > 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?

I get a connection. I haven’t figured out the right HTTP command to  
send to  
get a valid response yet, but I get a response - not a timeout.

> desirable behaviour.

See my earlier response explaining the business requirement, to  
understand  
why this is a desireable behavior.

> contradicts the above 2 lines, then it’s not legal nginx config.

If you look at the example conf I posted, that configuration - two  
separate  
server stanzas, each with a location directive, and I get that message.  
I  
probably have something else misconfigured. Again, newb…

> .  
> The redirect is a redirect - telling nginx to use a different  
> reverse-proxy  
> “upstream” server from what it would normally use based on the URL in  
> the  
> request. However, if there is a better way to get the same result I am  
> all  
> for it. For example, a method whereby the same front-end url chooses an  
> upstream server based on the valid\_referer criterion, or whatever it is  
> you  
> would recommend other than the referrer,.
> 
> > 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 😛

I don’t want to install apt on my centos server 😕 How 'bout ‘yum  
install  
git-core?’

> > access\_log /var/log/nginx/devpxyaccess.log main;  
> > access\_log /var/log/nginx/pxyaccess.log main ;  
> > 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.  
> Would that work if the goal is to direct traffic based on where you’re  
> coming from? I will explore…
> - 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.  
> The logs are specified at per-server to quickly identify where the  
> failure  
> lies. They will be only at the nginx.conf http level when I have a  
> suceessful configuration.
> - A single server stanza, switching between backends.

I like the idea - I’m just stuck on how to get it to switch based on  
where  
the client is coming from…

> When you do what?

When I set up my included config file to use the two-server-stanza  
configuration I posted (with hostnames/addresses pointing to real-life  
stuff, of course) that’s what I get when issuing the service restart.

> ## Jonathan
> 
> Jonathan M. // Oxford, London, UK  
> [http://www.jpluscplusm.com/contact.html](http://www.jpluscplusm.com/contact.html)
> 
> * * *
> 
> nginx mailing list  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)

Thanks again - you’ve been quite helpful.

Jim.

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,236278,236312#msg-236312](http://forum.nginx.org/read.php?2,236278,236312#msg-236312)

---

<div class="post-metadata">

**Author:** ![jims](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/838e76/32.png) [@jims](https://www.ruby-forum.com/u/jims)\
**Post date:** [February 20, 2013, 6:17pm UTC](https://www.ruby-forum.com/t/reverse-proxy-configuration-help/226699/4 "2013-02-20T18:17:43Z")

</div>

Jonathan,

I just want to thank you for helping a newbie out, once again. Your  
advice  
helped me to get things going,

Now I get to fine-tune it…

## jims Wrote:

> > identify what your first steps should be; then iterate from simple
> > 
> > > The problem: I have a VPS hosting a website and an application  
> > > When you say “referrer”, do you really mean the referrer as  
> > > reverse-proxy that’s front-ending the test app server. The idea is to  
> > > the CMS to handle links with variables - they should be able to copy
> > 
> > use two  
> > name  
> > website, a bookmark, someone emailing you the link - the request goes
> > 
> > all  
> > different
> > 
> > > to work the way I expect, either.  
> > > the same result I am all for it. For example, a method whereby the  
> > > I don’t want to install apt on my centos server 😕 How 'bout 'yum  
> > > proxy\_bind 10.10.10.10;  
> > > proxy\_bind 10.10.10.10 ;  
> > > specified, so nginx doesn’t know how to resolve the app FQDNs.  
> > > the  
> > > depriving you of the educational and life-affirming journey of  
> > > When you do what?  
> > > nginx mailing list  
> > > [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> > > [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)
> 
> Thanks again - you’ve been quite helpful.
> 
> Jim.

Posted at Nginx Forum:  
[http://forum.nginx.org/read.php?2,236278,236361#msg-236361](http://forum.nginx.org/read.php?2,236278,236361#msg-236361)
