In this post I hope to show how to configure nginx as a reverse proxy to a back-end CentOS 5 server running Apache.
When you add an nginx reverse proxy layer on top of Apache, Apache thinks that all connections originate from the server running nginx. This creates a couple annoying problems:
- Every entry in the Apache access logs appears to come from the IP of the nginx server
- Securing sessions by checking that a user’s IP address hasn’t changed becomes more difficult.
- This is especially true when using open source software. OS packages usually look for the client’s IP in the REMOTE_ADDR variable.
To resolve these issues, we’ll use the Apache mod_rpaf module to populate the REMOTE_ADDR using a special HTTP header inserted by nginx. A typical request would work as follows:
- 1.2.3.4 sends HTTP request to nginx server
- nginx determines that it needs to proxy pass the request to a back-end Apache server (e.g. by looking at the content-type or virtual host).
- nginx adds an HTTP header “X-Forwarded-For” with the client’s real IP
- nginx forwards (proxy_pass) the request to back-end Apache server
- mod_rpaf in Apache detects that the request is coming from the nginx IP, then substitutes REMOTE_ADDR with the contents of X-Forwarded-For
- Apache handles request as normal. Applications do not need to be aware of the reverse proxy.
To install mod_rpaf on the CentOS 5 box:
wget http://stderr.net/apache/rpaf/download/mod_rpaf-0.6.tar.gz tar zxvf mod_rpaf-0.6.tar.gz cd mod_rpaf-0.6 # Patch Makefile so it looks for 'apxs' instead of 'apxs2' (required # when compiling under CentOS 5): sed -ie 's/apxs2/apxs/' Makefile make rpaf-2.0 make install-2.0
Create /etc/httpd/conf.d/rpaf.conf:
# Path to mod_rpaf-2.0.so, relative to /etc/httpd/ LoadModule rpaf_module modules/mod_rpaf-2.0.so RPAFenable On RPAFsethostname On # Define our reverse proxy IP. Only substitute client IP in # when we receive a request from this IP. RPAFproxy_ips 192.168.0.1 # The header where the real client IP address is stored. RPAFheader X-Forwarded-For
Configure nginx to reverse proxy our CNAME IP address to the back-end container. We won’t go into installing nginx here, instead I’ve included the relevant configuration section in /etc/nginx/nginx.conf. This configuration says to reverse proxy all requests to the virtual host ‘myvirtualhost.com’:
server {
listen 80;
server_name myvirtualhost.com;
location / {
proxy_pass http://192.168.0.56;
proxy_redirect default;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
After restarting Apache & nginx, you should be able to successfully connect to your back-end Apache via the nginx reverse proxy layer. Inspecting the Apache environment will show a couple new headers, but other than that requests look the same as if clients were connecting directly without the proxy.
Omg, you saved me! Thanks!
Thanks for the tips! Could you please tell me how to implement this on Debian installation?
I used this guide to setup my server:
http://www.sysadmin.md/debian-lamp-nginx-installation-for-high-loaded-webservers.html
Thanks, this is exactly what I was looking for.
[...] maxgarrick.com » Reverse proxy with nginx – May 29th ( tags: nginx reverse_proxy mod_rpaf apache tips tricks guide howto reverseproxy ) [...]
[...] http://developer.mindtouch.com/User:PeteE/Varnish_Installation http://varnish.projects.linpro.no/ http://maxgarrick.com/reverse-proxy-with-nginx [...]