
Useful snippets for Nginx configs

Good day, dear Khabravites! In Elasticweb, we secretly advocate for Nginx and, probably, we are one of the few hosting companies that do not support Apache and .htaccess respectively. In this regard, a large number of hits in those. Support is related to helping write a configuration file for Nginx. Therefore, we decided to collect a collection of useful snippets and a collection of ready-made Nging configs for the most popular CMS / CMF / PHP frameworks.
Ready configs:
- Asgard cms
- Bolt CMS
- CMS Made Simple
- Codeigniter
- Data life engine
- Drupal 7, 8
- FuelPHP
- Joomla 2, 3
- KodiCMS
- Kohana
- Laravel
- MaxSite CMS
- MediaWiki
- MODx Revolution
- Octobercms
- Opencart 1.5
- phpBB3
- Processwire 2
- Symfony
- Wordpress 4
- Yii advanced
- Yii basic
- ZenCart 1.5
- Zend framework
Nginx Commands
Basic commands for performing basic operations while Nginx is running.
- nginx -V - check the version of Nginx, its compiled configuration parameters and installed modules.
- nginx -t - test the configuration file and check its location.
- nginx -s reload - restart the configuration file without restarting Nginx.
Location block in PHP
A simple template for quick and easy installation of PHP, FPM or CGI on your website.
location ~ \.php$ {
try_files $uri =404;
client_max_body_size 64m;
client_body_buffer_size 128k;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/path/to/php.sock;
}
Rewrite and redirection
Force www
The correct way to determine the remote server is by domain without www and redirect it from www :
server {
listen 80;
server_name example.org;
return 301 $scheme://www.example.org$request_uri;
}
server {
listen 80;
server_name www.example.org;
...
}
Also works for HTTPS.
Force no-www
The correct way to determine the remote server is from the c www domain and redirect it without www :
server {
listen 80;
server_name example.org;
}
server {
listen 80;
server_name www.example.org;
return 301 $scheme://example.org$request_uri;
}
Force HTTPS
Method for forwarding from HTTP to HTTPS:
server {
listen 80;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
# let the browsers know that we only accept HTTPS
add_header Strict-Transport-Security max-age=2592000;
...
}
Force trailing slash
This line adds a slash
/
at the end of each URL, only if there are no periods or parameters in the URL. That is, after example.com/index.php or example.com/do?some=123, the slash will not be delivered.rewrite ^([^.\?]*[^/])$ $1/ permanent;
Redirect to page
server {
location = /oldpage.html {
return 301 http://example.org/newpage.html;
}
}
Redirect to the site
server {
server_name old-site.com
return 301 $scheme://new-site.com$request_uri;
}
Redirect to a specific path in a URI
location /old-site {
rewrite ^/old-site/(.*) http://example.org/new-site/$1 permanent;
}
Performance
Caching
Permanently allow browsers to cache static content. Nginx will set both headers: Expires and Cache-Control.
location /static {
root /data;
expires max;
}
You can disable browsers caching (for example, to track requests) as follows:
location = /empty.gif {
empty_gif;
expires -1;
}
Gzip compression
gzip on;
gzip_buffers 16 8k;
gzip_comp_level 6;
gzip_http_version 1.1;
gzip_min_length 256;
gzip_proxied any;
gzip_vary on;
gzip_types
text/xml application/xml application/atom+xml application/rss+xml application/xhtml+xml image/svg+xml
text/javascript application/javascript application/x-javascript
text/x-json application/json application/x-web-app-manifest+json
text/css text/plain text/x-component
font/opentype application/x-font-ttf application/vnd.ms-fontobject
image/x-icon;
gzip_disable "msie6";
File cache
If you have cached a large number of static files through Nginx, then caching metadata of these files will save delay time.
open_file_cache max=1000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
SSL cache
Enabling SSL caching will allow you to resume SSL sessions and reduce the time for the next calls to the SSL / TLS protocol.
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
Upstream support
Activating caching using Upstream connections:
upstream backend {
server 127.0.0.1:8080;
keepalive 32;
}
server {
...
location /api/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
Monitoring
By default, the Stub Status module is not built, its assembly must be enabled using the configuration parameter —with-http_stub_status_module and activated using:
location /status {
stub_status on;
access_log off;
}
This setting will allow you to receive status in plain text format for the total number of requests and client connections (accepted, processed, active).
A more informative status from Nginx can be obtained using Luameter , which is somewhat more difficult to install and requires the presence of a Nginx Lua module. This will provide the following metrics for the various configuration groups in JSON format:
- The total number of requests / responses.
- The total number of responses grouped by status code: 1xx, 2xx, 3xx, 4xx, 5xx.
- The total number of bytes received / sent to the client.
- Intermediate periods of time to estimate the minimum, maximum, median, delays, etc.
- The average number of queries for ease of monitoring and forecasting the load.
- And so on…
Luameter dashboard example .
Also ngxtop is great for collecting statistics .
Security
Activation of basic authentication
First you need to create a password and save it in a plain text file:
имя:пароль
Then set the nitro settings for the server / location block that you want to protect:
auth_basic "This is Protected";
auth_basic_user_file /path/to/password-file;
Open local access only
location /local {
allow 127.0.0.1;
deny all;
...
}
SSL settings protection
- Disable SSLv3 if it is enabled by default. This will prevent the POODLE SSL Attack .
- The ciphers that best provide protection. Mozilla Server Side TLS and Nginx .
# don’t use SSLv3 ref: POODLE CVE-2014-356 - http://nginx.com/blog/nginx-poodle-ssl/ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Ciphers set to best allow protection from Beast, while providing forwarding secrecy, as defined by Mozilla (Intermediate Set) - https://wiki.mozilla.org/Security/Server_Side_TLS#Nginx ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA'; ssl_prefer_server_ciphers on;
Other
Subqueries after completion
There are situations when you need to transfer a request to another backend in the add-on or after its processing . The first case is to track the number of completed downloads by calling the API after the user has downloaded the file. The second case is to track a request to which you would like to return as quickly as possible (possibly with an empty .gif) and make the corresponding entries in the background. post_action , which allows you to define a subquery and will be rejected at the end of the current request, is the best solution for both options.
location = /empty.gif {
empty_gif;
expires -1;
post_action @track;
}
location @track {
internal;
proxy_pass http://tracking-backend;
}
Distribution of resources between sources
The easiest and most well-known way of cross-domain request to your server:
location ~* .(eot|ttf|woff) {
add_header Access-Control-Allow-Origin *;
}
Sources
Many thanks to all for your attention!