|
| 1 | +# Nginx configuration for WordPress |
| 2 | + |
| 3 | +## Introduction |
| 4 | + |
| 5 | + This is a nginx configuration for running [WordPress](http://wordpress.org "WordPress"). |
| 6 | + |
| 7 | + It differs from the _usual_ configuration, like the |
| 8 | + [one](http://wiki.nginx.org/Wordpress "Nginx Wiki WordPress |
| 9 | + config") available on the [Nginx Wiki](http://wiki.nginx.org "Nginx |
| 10 | + Wiki"). |
| 11 | + |
| 12 | + It makes use of **nested locations** with named capture groups |
| 13 | + instead of |
| 14 | + [fastcgi_split\_path\_info](http://wiki.nginx.org/HttpFcgiModule#fastcgi_split_path_info |
| 15 | + "FastCGI split path info"). |
| 16 | + |
| 17 | + This example configuration assumes that the site is called |
| 18 | + `example.com`. Change accordingly to reflect your server setup. |
| 19 | + |
| 20 | +## Features |
| 21 | + |
| 22 | + 1. Filtering of invalid HTTP `Host` headers. |
| 23 | + |
| 24 | + 2. Access to install files, like `install.php,` is protected using |
| 25 | + [HTTP Basic Auth](http://wiki.nginx.org/NginxHttpAuthBasicModule |
| 26 | + "Basic Auth Nginx Module"). |
| 27 | + |
| 28 | + 3. Protection of all the _internal_ directories, like version |
| 29 | + control repositories and the `readme` file(s) |
| 30 | + that come with WP or an external plugin. |
| 31 | + |
| 32 | + 4. Faster and more secure handling of PHP FastCGI by Nginx using |
| 33 | + named groups in regular expressions instead of using |
| 34 | + [fastcgi_split\_path\_info](http://wiki.nginx.org/HttpFcgiModule#fastcgi_split_path_info |
| 35 | + "FastCGI split path info"). Requires Nginx version ≥ 0.8.25. |
| 36 | + |
| 37 | + 5. Compatible with the WordPress plugin |
| 38 | + [wp-super-cache](http://wordpress.org/extend/plugins/wp-super-cache "WordPress |
| 39 | + SuperCache") for serving static pages to anonymous users. |
| 40 | + |
| 41 | + |
| 42 | +## Basic Auth for access to restricted files like install.php |
| 43 | + |
| 44 | + `install.php` and the WordPress `readme.html` are protected using |
| 45 | + Basic Auth. The readme file discloses the version number of |
| 46 | + WordPress. |
| 47 | + |
| 48 | + Not only `install.php`, but any PHP file that has **install.php** |
| 49 | + as the ending is protected. This way if, for example, there's a |
| 50 | + permission problem with `wp-config.php` and WP can't read the file |
| 51 | + it will invoke `install.php` since it assumes that if no specific |
| 52 | + configuration information is available then the site must not yet |
| 53 | + be installed. Now imagine that this happens on your site and that |
| 54 | + someone stumbles on the `install.php`? If not protected by the |
| 55 | + Basic Auth, information disclosure would be the least potential |
| 56 | + problem. |
| 57 | + |
| 58 | + You have to create the `.htpasswd-users` file with the user(s) and |
| 59 | + password(s). For that, if you're on Debian or any of its |
| 60 | + derivatives like Ubuntu you need the |
| 61 | + [apache2-utils](http://packages.debian.org/search?suite%3Dall§ion%3Dall&arch%3Dany&searchon%3Dnames&keywords%3Dapache2-utils) |
| 62 | + package installed. Then create your password file by issuing: |
| 63 | + |
| 64 | + htpasswd -d -b -c .htpasswd-users <user> <password> |
| 65 | + |
| 66 | + You should delete this command from your shell history |
| 67 | + afterwards with `history -d <command number>` or alternatively |
| 68 | + omit the `-b` switch, then you'll be prompted for the password. |
| 69 | + |
| 70 | + This creates the file (there's a `-c` switch). For adding |
| 71 | + additional users omit the `-c`. |
| 72 | + |
| 73 | + Of course you can rename the password file to whatever you want, |
| 74 | + then accordingly change its name in the virtual host config |
| 75 | + file, `example.com`. |
| 76 | + |
| 77 | +## Installation |
| 78 | + |
| 79 | + 1. Move the old `/etc/nginx` directory to `/etc/nginx.old`. |
| 80 | + |
| 81 | + 2. Clone the git repository from github: |
| 82 | + |
| 83 | + `git clone https://github.com/perusio/chive-wordpress.git` |
| 84 | + |
| 85 | + 3. Edit the `sites-available/example.com` configuration file to |
| 86 | + suit your requirements. Namely replacing `example.com` with |
| 87 | + **your** domain. |
| 88 | + |
| 89 | + 4. Setup the PHP handling method. It can be: |
| 90 | + |
| 91 | + + Upstream HTTP server like Apache with mod_php |
| 92 | + |
| 93 | + + FastCGI process using php-cgi. In this case an |
| 94 | + [init script](https://github.com/perusio/php-fastcgi-debian-script |
| 95 | + "Init script for php-cgi") is |
| 96 | + required. This is how the server is configured out of the |
| 97 | + box. It uses UNIX sockets. You can use TCP sockets if you prefer. |
| 98 | + |
| 99 | + + [PHP FPM](http://www.php-fpm.org "PHP FPM"), this requires you |
| 100 | + to configure your fpm setup, in Debian/Ubuntu this is done in |
| 101 | + the `/etc/php5/fpm` directory. |
| 102 | + |
| 103 | + Check that the socket is properly created and is listening. This |
| 104 | + can be done with `netstat`, like this for UNIX sockets: |
| 105 | + |
| 106 | + `netstat --unix -l` |
| 107 | + |
| 108 | + `netstat -t -l` |
| 109 | + |
| 110 | + It should display the PHP CGI socket. |
| 111 | + |
| 112 | + 5. Create the `/etc/nginx/sites-enabled` directory and enable the |
| 113 | + virtual host using one of the methods described below. |
| 114 | + |
| 115 | + 6. Reload Nginx: |
| 116 | + |
| 117 | + `/etc/init.d/nginx reload` |
| 118 | + |
| 119 | + 7. Check that WordPress is working by visiting the configured site |
| 120 | + in your browser. |
| 121 | + |
| 122 | + 8. Remove the `/etc/nginx.old` directory. |
| 123 | + |
| 124 | + 9. Done. |
| 125 | + |
| 126 | +## Enabling and Disabling Virtual Hosts |
| 127 | + |
| 128 | + I've created a shell script |
| 129 | + [nginx_ensite](http://github.com/perusio/nginx_ensite) that lives |
| 130 | + here on github for quick enabling and disabling of virtual hosts. |
| 131 | + |
| 132 | + If you're not using that script then you have to **manually** |
| 133 | + create the symlinks from `sites-enabled` to `sites-available`. Only |
| 134 | + the virtual hosts configured in `sites-enabled` will be available |
| 135 | + for Nginx to serve. |
| 136 | + |
| 137 | + |
| 138 | +## Getting the latest Nginx packaged for Debian or Ubuntu |
| 139 | + |
| 140 | + I maintain a [debian repository](http://debian.perusio.net/unstable |
| 141 | + "my debian repo") with the |
| 142 | + [latest](http://nginx.org/en/download.html "Nginx source download") |
| 143 | + version of Nginx. This is packaged for Debian **unstable** or |
| 144 | + **testing**. The instructions for using the repository are |
| 145 | + presented on this [page](http://debian.perusio.net/debian.html |
| 146 | + "Repository instructions"). |
| 147 | + |
| 148 | + It may work or not on Ubuntu. Since Ubuntu seems to appreciate more |
| 149 | + finding semi-witty names for their releases instead of making clear |
| 150 | + what's the status of the software included, meaning. Is it |
| 151 | + **stable**? Is it **testing**? Is it **unstable**? The package may |
| 152 | + work with your currently installed environment or not. I don't have |
| 153 | + the faintest idea which release to advise. So you're on your |
| 154 | + own. Generally the APT machinery will sort out for you any |
| 155 | + dependencies issues that might exist. |
| 156 | + |
| 157 | +## My other Nginx configurations on github |
| 158 | + |
| 159 | + + [drupal](https://github.com/perusio/drupal-with-nginx "Drupal |
| 160 | + Nginx configuration") |
| 161 | + |
| 162 | + + [piwik](https://github.com/perusio/piwik-nginx "Piwik Nginx |
| 163 | + configuration") |
| 164 | + |
| 165 | + + [chive](https://github.com/perusio/piwik-nginx "Chive Nginx |
| 166 | + configuration") |
| 167 | + |
0 commit comments