A repository of Nginx-related articles

Hotlinked files can be a major cause for bandwidth leeching for some sites.
Here’s how you can hotlink protect your images and other file types using a
simple location directive in your Nginx configuration file :

If you are using an old version of Nginx or if you want to explicitly hide the Nginx version in your HTTP headers and your default error pages, you can use the server_tokens directive in your Nginx configuration. The server_tokens directive can be used either in the http, server or location block.

Just set server_tokens to off (it is set to on by default) to hide your Nginx version in all externally visible places.

server_tokens off;

Just like using Apache’s ServerSignature and ServerTokens directive, your Nginx version should now be hidden in the server signature and the default error pages. To check the server headers, use the HTTP Header Checker utility from Webconfs.com.

We can retrieve the version of Nginx currently installed by calling the Nginx
binary with some command-line parameters. We can use the -v parameter to
display the Nginx version only, or use the -V parameter to display the
version, along with the compiler version and configuration parameters.

In a previous post, we had written about setting up Perl-FastCGI on Nginx.
This article is about setting up PHP-FastCGI. As always, this article assumes
that you are running on Debian Squeeze (or above) and uses aptitude/apt-get
for fetching and installing packages.

Now, there are some tutorials on the internet which wrongly configure Nginx and introduce an arbitrary code execution bug. Note that Nginx passes a request to the php-cgi daemon if the REQUEST_URI has a trailing .php. It does not check whether the file exists or not. Suppose a request is made for /images/dog.jpg/test.php. Nginx will match the trailing .php and pass the request to php-cgi. Now, if test.php does not exist and cgi.fix_pathinfo is set to 1, php-cgi will try to execute /images/dog.jpg with /test.php as pathinfo. This is especially dangerous if you have a public upload directory. In our configuration, this will not happen even if cgi.fix_pathinfo is set to 1. The try_files $uri =404; line checks for the existence of the .php file and returns a 404 response header if it does not exist. Alternatively, cgi.fix_pathinfo can be set to 0, but is is not required as our configuration takes care of it.

Now we’ll use a Debian init script to control the php-cgi daemon which will be
running on port 9000.

Give the file executable permissions and make it start during booting :

chmod +x /etc/init.d/php-fcgi && insserv php-fcgi

Finally, start the fastcgi daemon :

invoke-rc.d php-fcgi start

To check that it is working properly, create this file :

vi /var/www/example.com/info.php

Put this in it :

<?php phpinfo(); ?>

Now go to http://example.com/info.php and you’ll get the PHP information
page showing information about the loaded modules.

Now, there are a couple of options you can change in the PHP-FastCGI init
script, namely, PHP_FCGI_CHILDREN and PHP_FCGI_MAX_REQUESTS.
PHP_FCGI_CHILDREN specifies the number of child processes the php-cgi master
process will spawn. Usually, two, or, even one is sufficient for a medium-
traffic site. PHP_FCGI_MAX_REQUESTS specifies the number of requests each
child process will serve before being terminated and respawned.

The Nginx package in the Debian stable repositories can be quite outdated. It
is often several version behind the latest, whereas the Nginx package from the
testing/unstable repositories is updated frequently with newer versions of
Nginx. We can use apt-pinning to get the a newer version of Nginx (the one
present in the testing/unstable repositories) and it’s dependencies (if
required) will be met from the testing/unstable repositories as well.

Let us first add the testing/unstable repositories to the software sources
list.

Replace testing with unstable if you want to add the unstable repositories
instead of testing.

Now we need to pin the nginx package in testing/unstable to a higher priority
so that it gets selected. Actually, in Debian, nginx is a meta-package that
selects the nginx-full package. So, if you want to use nginx-light
or nginx-extras, use them instead of just “nginx”.

vi /etc/apt/preferences

Add these lines :

Package: nginx
Pin: release a=testing
Pin-Priority: 900

As explained before, you can use nginx-light or nginx-extra instead of nginx
here. You can also use unstable instead of testing.

Now, run :

apt-get update

Check whether the newer version of nginx is selected for install by running :

apt-cache policy nginx

Finally, install/upgrade nginx by running :

apt-get install nginx

or

apt-get upgrade nginx

You’ll have a relatively newer version of Nginx installed after finishing
this.

phpBB ships with a small .htaccess file in the root that has rules to
deny access to the config.php and common.php files in the absence of a PHP
interpreter. I’ll duplicate those rules for an Nginx configuration.

Here’s how the .htaccess file looks like :

Order Allow,Deny
Deny from All
Order Allow,Deny
Deny from All

And here’s what you need to add to your Nginx configuration file in order to
duplicate that behaviour :

location ~ /config.php|/common.php {
deny all;
}

This will deny access to all instances of config/common.php located in the
document root, regardless of where they are located.