Nginx configuration for this:

  • if client request does not have x_forwarded_for, deny the request showing a 404
  • allow access site even if x_forwarded_for:
  • if “Host” header is a IP use /var/www/vhosts/ip as root dir
  • if “Host” header is a domain use /var/www/vhosts/$domain as root dir
  • if “Host” is sub0.sub1.oranything.domain still goes to /home/vhosts/$domain
  • backend for PHP fastcgi
  • if requested file doesnt exist throw 404 error
  • setting the default index page

Strongly based on http://kbeezie.com/view/nginx/

server {

server_name www.example.com default_server;
listen 0.0.0.0:80;

# Keep a root path in the server level, this will help automatically fill
# Information for stuff like FastCGI Parameters
root /var/www/vhosts/;

# You can set access and error logs at http, server and location level
access_log /var/log/nginx/server.access.log;
error_log /var/log/nginx/server.error.log debug;

# if client request does not have x_forwarded_for, deny the request,
if ($http_x_forwarded_for = "" ) { set $x 1; }
# .. except if host is www.public1.com|www.public2.com
if ($host ~* "(www\.public1\.com|www\.public2\.com)" ) { set $x 0; }
# .. or if uri is publicdir
if ($uri ~* "(publicdir)" ) { set $x 0; }
# .. evaluating $x
if ($x = 1) { return 404; }

# if Host is a IP vhost is "ip"
if ($host ~* "(\d+)\.(\d+)\.(\d+)\.(\d+)" ) { set $vhost "ip"; }

# if Host is a DN vhost is the vhost
if ($host ~* "(\w+\.)*(\w+)\.([a-z]+)" ) { set $vhost "$2.$3"; }

# If file doesnt exist: Error 404
if (!-e $document_root/$vhost/$uri) { return 403; }

# Setting the index page
set $i "/index.html";
if (-e $document_root/$vhost/index.php) { set $i "/index.php"; }
if (-e $document_root/$vhost/index.htm) { set $i "/index.htm"; }
if ($uri ~* "(.*)/") {
rewrite ^(.*)(/)$ $1$i redirect;
}
if (-d $document_root/$vhost/$uri) {
rewrite ^(.*)$ $1$i redirect;
}

# It will try for static file, folder, then falls back to index.php
# Assuming index.php is capable of parsing the URI automatically
location / {
try_files /$vhost$uri /$vhost/index.php ;
}

# Prevent ".." navigations: Error 403
location ~ \..*/.*\.php$ {
return 403;
}

# This block will catch static file requests, such as images, css, js
# The ?: prefix is a 'non-capturing' mark, meaning we do not require
# the pattern to be captured into $1 which should help improve performance
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
# Some basic cache-control for static files to be sent to the browser
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}

# PHP location block and parameters
location ~ \.php {
if (!-e $document_root/$vhost/$uri) { return 404; }
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;

fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param SCRIPT_FILENAME $document_root/$vhost/$fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
#fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_ADDR $remote_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param HTTP_HOST $host;

fastcgi_connect_timeout 60;
fastcgi_send_timeout 180;
fastcgi_read_timeout 180;
fastcgi_buffer_size 128k;
fastcgi_buffers 8 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_intercept_errors on;

# I use a socket for php, tends to be faster
# for TCP just use 127.0.0.1:port#
# fastcgi_pass unix:/opt/php-fpm.sock;
fastcgi_pass 127.0.0.1:9000;

# Not normally needed for wordpress since you are
# sending everything to index.php in try_files
# this tells it to use index.php when the url
# ends in a trailing slash such as domain.com/
fastcgi_index index.php;
}

# Most sites won't have configured favicon or robots.txt
# and since its always grabbed, turn it off in access log
# and turn off it's not-found error in the error log
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }

# Rather than just denying .ht* in the config, why not deny
# access to all .invisible files
location ~ /\. { deny all; access_log off; log_not_found off; }
}

Leave a comment

:-)

I’m Pablo Saavedra, a former Unix systems administrator turned embedded software developer, now dedicated to squashing bugs and optimizing performance on embedded devices..

I’m degree  in Computer Science by Universade da Coruña (Spain).

Of course, my hobbies are anything similar to computers, but also boxing, fitness, good beers, … You can follow me on twitter or my linkedin profile,