Tuesday, March 4, 2014

Configure NGinx to serve static files and Apache for dynamic

CentOS 6.x

rpm -Uvh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
Now that the repo is installed, we need to install NGinx

yum install nginx

Configuring NGinx

Now that NGinx is installed we need to create a VirtualHost (actually NGinx calls them Server Blocks) for each site we are hosting.
nano /etc/nginx/conf.d/virtual.conf
#Insert one of these for each of the virtualhosts you have configured in Apache

server {
listen 80;
root /path/to/site/root;
index index.php index.html index.htm;
server_name www.yourdomain.com yourdomain.com;
location / {
try_files $uri $uri/ /index.php;
location ~ \.php$ {

proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;


location ~ /\.ht {
deny all;

This configuration tells NGinx to try and serve the requested file, but to pass the request onto Apache if it's unable to do so. Requests for PHP files should be forwarded automatically. Apache will be told who requested the file in the 'X-Forwarded-For' header.

The final section tells NGinx not to check requests for .htaccess files as no one want anyone to see the contents of these.


Configuring Apache

We want users to hit our NGinx installation (otherwise this effort is wasted) but Apache is currently sat on port 80. So we're going to move it to 8080 (given that's the port we specified in the NGinx configuration we created).

nano /etc/httpd/conf/httpd.conf
# Find the following
Listen (someIP) 80
# Change the port to
Listen 8080

# Now at the bottom of the file, you'll find your virtualhost directives,
# Change all port definitions of 80 to 8080
# Don't forget the Default virtualhost definition
# <virtualhost *:80> becomes <virtualhost *:8080>

We change the Listen address as we don't want external hosts to access Apache directly, everything should go through NGinx. Ideally, we also want to forbid outside access to port 8080 at the firewall to ensure that the point of entry to our system is restricted to the authorised route - through NGinx.

Start the Services
We've now configured Apache to listen on a different port, so all we need to do know is restart Apache (so that it moves to port 8080) and start NGinx so that it can start handling requests.

service httpd restart
service nginx start
Now if you browse to your site, nothing should have changed visibly. However, if you check the HTTP headers you should see NGinx instead of Apache, checking a phpinfo file should still show Apache as having called the PHP parser though.


Additional Considerations
By adding NGinx into the mix, we're increasing our potential attack surface a little - we've now got an extra application to keep patched and up to date (which is why we installed from the repo's and didn't go out-of-band). Although we've hidden Apache away behind NGinx, don't assume it's automatically shielded - if a vulnerability is exploited using a valid request, NGinx will pass the request through verbatim (assuming it couldn't handle itself). What you are protected from, though, is exploits that involve an invalid request.

SSL Connections
Nothing we've done will affect SSL connections, if Apache was configured to listen on port 443, it will continue to do so. However, this also means that all SSL requests will be handled by Apache and so the memory benefits of using NGinx as a proxy won't be present on these connections. It's more than possible (and not particularly hard) to set NGinx up as a reverse SSL proxy, but that's outside the scope of this documentation (although the steps involved are almost identical).

If your server is running CPanel, you probably won't want to edit everything by hand. In that instance, it may be worth trying the CPanel NGinx plugin at http://nginxcp.com/. Plesk users should find that support for NGinx is included, so long as they are running version 11 or later.

No comments:

Post a Comment