diff --git a/docs/en/installation/nginx.md b/docs/en/installation/nginx.md index b9390385d..844a6d296 100644 --- a/docs/en/installation/nginx.md +++ b/docs/en/installation/nginx.md @@ -6,83 +6,147 @@ These instructions are also covered in less detail on the The prerequisite is that you have already installed Nginx and you are able to run PHP files via the FastCGI-wrapper from Nginx. -Now you need to set up a virtual host in Nginx with the following -configuration settings: +Now you need to set up a virtual host in Nginx with configuration settings +that are similar to those shown below. +
+If you don't fully understand the configuration presented here, consult the +[nginx documentation](http://nginx.org/en/docs/). + +Especially be aware of [accidental php-execution](https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ "Don't trust the tutorials") when extending the configuration. +
+But enough of the disclaimer, on to the actual configuration — typically in `nginx.conf`: server { listen 80; - - # SSL configuration (optional, but recommended for security) - include ssl - - root /var/www/example.com; - index index.php index.html index.htm; - server_name example.com; - include silverstripe3; - include htaccess; + root /var/www/example.com; + + # SSL configuration (optional, but recommended for security) + # (remember to actually force logins to use ssl) + include ssl + + include silverstripe3.conf; + include htaccess.conf; + + # rest of the server section is optional, but helpful + # maintenance page if it exists + error_page 503 @maintenance; + if (-f $document_root/maintenance.html ) { + return 503; + } + location @maintenance { + try_files /maintenance.html =503; + } + + # always show SilverStripe's version of 500 error page + error_page 500 /assets/error-500.html; + + # let the user's browser cache static files (e.g. 2 weeks) + expires 2w; + + # in case your machine is slow, increase the timeout + # (also remembers php's own timeout settings) + #fastcgi_read_timeout 300s; } -Here is the include file `silverstripe3`: +Here is the include file `silverstripe3.conf`: location / { try_files $uri @silverstripe; } - + + # only needed for installation - disable this location (and remove the + # index.php and install.php files) after you installed SilverStripe + # (you did read the blogentry linked above, didn't you) + location ~ ^/(index|install).php { + fastcgi_split_path_info ^((?U).+\.php)(/?.+)$; + include fastcgi.conf; + fastcgi_pass unix:/run/php-fpm/php-fpm-silverstripe.sock; + } + + # whitelist php files that are called directly and need to be interpreted + location = /framework/thirdparty/tinymce/tiny_mce_gzip.php { + include fastcgi.conf; + fastcgi_pass unix:/run/php-fpm/php-fpm-silverstripe.sock; + } + location = /framework/thirdparty/tinymce-spellchecker/rpc.php { + include fastcgi.conf; + fastcgi_pass unix:/run/php-fpm/php-fpm-silverstripe.sock; + } + location @silverstripe { - include fastcgi_params; - - # Defend against arbitrary PHP code execution - # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini - # More info: - # https://nealpoole.com/blog/2011/04/setting-up-php-fastcgi-and-nginx-dont-trust-the-tutorials-check-your-configuration/ - fastcgi_split_path_info ^(.+\.php)(/.+)$; - + expires off; + include fastcgi.conf; + fastcgi_pass unix:/run/php-fpm/php-fpm-silverstripe.sock; + # note that specifying a fixed script already protects against execution + # of arbitrary files, but remember the advice above for any other rules + # you add yourself (monitoring, etc,....) fastcgi_param SCRIPT_FILENAME $document_root/framework/main.php; fastcgi_param SCRIPT_NAME /framework/main.php; fastcgi_param QUERY_STRING url=$uri&$args; - fastcgi_pass unix:/var/run/php5-fpm.sock; - fastcgi_index index.php; - fastcgi_buffer_size 32k; - fastcgi_buffers 4 32k; - fastcgi_busy_buffers_size 64k; + # tuning is up to your expertise, but buffer_size needs to be >= 8k, + # otherwise you'll get "upstream sent too big header while reading + # response header from upstream" errors. + fastcgi_buffer_size 8k; + #fastcgi_buffers 4 32k; + #fastcgi_busy_buffers_size 64k; } +
+With only the above configuration, nginx would hand out any existing file +uninterpreted, so it would happily serve your precious configuration files, +including all your private api-keys and whatnot to any random visitor. So you +**must** restrict access further. +
+You don't need to use separate files, but it is easier to have the permissive +rules distinct from the restricting ones. -Here is the include file `htaccess`: +Here is the include file `htaccess.conf`: - # Don't serve up any .htaccess files - location ~ /\.ht { - deny all; - } - - # Deny access to silverstripe-cache - location ~ ^/silverstripe-cache { - deny all; - } - - # Don't execute scripts in the assets + # Don't try to find nonexisting stuff in assets (esp. don't pass through php) location ^~ /assets/ { - try_files $uri $uri/ =404; + try_files $uri =404; } - # Block access to yaml files - location ~ \.yml$ { + # Deny access to silverstripe-cache, vendor or composer.json/.lock + location ^~ /silverstripe-cache/ { + deny all; + } + location ^~ /vendor/ { + deny all; + } + location ~ /composer\.(json|lock) { deny all; } - # cms & framework .htaccess rules - location ~ ^/(cms|framework|mysite)/.*\.(php|php[345]|phtml|inc)$ { + # Don't serve up any "hidden" files or directories + # (starting with dot, like .htaccess or .git) + # also don't serve web.config files + location ~ /(\.|web\.config) { + deny all; + } + + # Block access to yaml files (and don't forget about backup + # files that editors tend to leave behind) + location ~ \.(yml|bak|swp)$ { + deny all; + } + location ~ ~$ { + deny all; + } + + # generally don't serve any php-like files + # (as they exist, they would be served as regular files, and not interpreted. + # But as those can contain configuration data, this is bad nevertheless) + # If needed, you can always whitelist entries. + location ~ \.(php|php[345]|phtml|inc)$ { deny all; } location ~ ^/(cms|framework)/silverstripe_version$ { deny all; } - location ~ ^/framework/.*(main|static-main|rpc|tiny_mce_gzip)\.php$ { - allow all; - } Here is the optional include file `ssl`: @@ -95,8 +159,9 @@ Here is the optional include file `ssl`: The above configuration sets up a virtual host `example.com` with rewrite rules suited for SilverStripe. The location block named -`@silverstripe` passes all php scripts to the FastCGI-wrapper via a Unix -socket. This example is from a site running Ubuntu with the php5-fpm -package. +`@silverstripe` passes all requests that aren't matched by one of the other +location rules (and cannot be satisfied by serving an existing file) to +SilverStripe framework's main.php script, that is run by the FastCGI-wrapper, +that in turn is accessed via a Unix socket. Now you can proceed with the SilverStripe installation normally.