Item14551: Update the default Nginx configuration examples
Priority: Enhancement
Current State: Waiting for Feedback
Released In: 2.1.5
Target Release: patch
The current example Nginx configuration has a few issues:
- It uses an if statement for referrer blocking. There are better solutions available.
- It uses an [A-Z] regular expression to detect short URLs, which doesn't support accented characters.
- Redirecting to /bin/view for short URLs loops if a redirect is present to remove /bin/view when users enter long URLs on a short url site.
I suggest including the below example by default. A
VirtualHostingContrib example should be included as part of that contrib, and not in the default nginx configuration.
server {
listen 80 http2 fastopen=50 reuseport;
#listen 443 ssl http2 fastopen=50 reuseport;
server_name mysite.org;
set $foswiki_root "/var/www/mysite";
root $foswiki_root;
set $foswiki_fcgi 127.0.0.1:9000
#set $foswiki_fcgi unix:/var/run/foswiki/foswiki.sock;
access_log /var/log/nginx/mysite-access.log;
error_log /var/log/nginx/mysite-error.log;
#error_log /var/log/nginx/mysite-error.log debug; # optional extra debugging
client_max_body_size 100M; # Set to maximum attachment size, See also ATTACHFILESIZELIMIT
# Example SSL configuration parameters
# ssl_certificate /etc/letsencrypt/live/mysite_cert__current.pem;
# ssl_certificate_key /etc/letsencrypt/live/mysite_privkey__current.pem;
# ssl_protocols TLSv1.3;# Requires nginx >= 1.13.0 else use TLSv1.2
# ssl on;
# ssl_prefer_server_ciphers on;
# ssl_dhparam /etc/nginx/dhparam.pem; # openssl dhparam -out /etc/nginx/dhparam.pem 4096
# ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
# ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0
# ssl_session_timeout 10m;
# ssl_session_cache shared:SSL:10m;
# ssl_session_tickets off; # Requires nginx >= 1.5.9
# ssl_stapling on; # Requires nginx >= 1.3.7
# ssl_stapling_verify on; # Requires nginx => 1.3.7
# resolver 127.0.0.1 [::1]:5353 valid=30s; # ipv6 Requires >= 1.5.8, multiple servers >= 1.1.7 cache time >= 1.1.9
# resolver_timeout 5s;
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
# add_header X-Frame-Options DENY;
# add_header X-Content-Type-Options nosniff;
# add_header X-XSS-Protection "1; mode=block";
# add_header X-Robots-Tag none;
# For blocking of misbehaving search engines, and other bad bots we suggest the following
# https://github.com/oohnoitz/nginx-blacklist/blob/master/blacklist.conf
# or: https://github.com/Stevie-Ray/referrer-spam-blocker/blob/master/referral-spam.conf
location = /favicon.ico {
limit_except GET { deny all; }
log_not_found off;
access_log off;
}
location = /robots.txt {
limit_except GET { deny all; }
allow all;
log_not_found off;
access_log off;
}
# Allow google site verification files
#location ~ ^/google.*\.html$ {
# limit_except GET { deny all; }
# allow all;
# log_not_found off;
# access_log off;
# try_files $uri 404;
#}
# Short URL redirect (matches prefix)
# If a user enters /bin/view directly, redirect them to the short URL
location /bin/view/ {
rewrite ^/bin/view/(.*) /$1 permanent;
}
# Set a default landing page (matches exact)
location = / {
limit_except GET POST { deny all; }
root $foswiki_root;
rewrite .* /Web/WebHome;
}
# Deny all the important directories (match regex)
location ~ ^(/lib|/data|/locale|/templates|/test|/tools|/work) {
deny all;
}
# Allow pub access (matches prefix)
location /pub/ {
limit_except GET { deny all; }
allow all;
}
# Cache and zip files served from certain paths (matches regex)
# WARNING: files need to be legitimately gzipped, and not be symlinks to the non-gzipped content.
location ~ ^/pub/(Main|System|Applications|images|cache)/ {
limit_except GET { deny all; }
expires 8h;
gzip_static on;
}
# Any explicit bin scripts - pass to FCGI backend (matches prefix)
location /bin/ {
limit_except GET POST { deny all; }
gzip off;
fastcgi_pass $foswiki_fcgi;
fastcgi_split_path_info ^(/bin/\w+)(.*);
# Captures two variables ($fastcgi_script_name) and ($fastcgi_path_info)
include fastcgi_params; # include this first, to allow overrides below
fastcgi_param SCRIPT_FILENAME $foswiki_root/bin/$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
# For any other URLs pass it to the FCGI backend with view script (matches prefix)
location / {
limit_except GET POST { deny all; }
gzip off;
fastcgi_pass $foswiki_fcgi;
fastcgi_split_path_info ()?(.*); # no script, default it to view
include fastcgi_params; # include this first, to allow overrides below
fastcgi_param SCRIPT_FILENAME $foswiki_root/bin/view;
fastcgi_param SCRIPT_NAME view;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}
--
GeorgeClark - 03 Dec 2017
Michael, can you review this as an improved sample nginx configuration? Except for some cosmetic changes, I've tested it on 3 different sites. I'm a bit uneasy about that last fastcgi_split_path_info with the empty script capture. Maybe it should be (nomatch)?(.*) My live configs include the common file definitions, letsencrypt config, and the tls settings. I pasted much of it inline for this example.
--
GeorgeClark - 03 Dec 2017
I was able to simplify the fcgi location block down to just one. Foswiki seems to just get the script right.
# For any other URLs pass it to the FCGI backend. Foswiki figures out the script, even when missing.
location / {
limit_except GET POST { deny all; }
gzip off;
fastcgi_pass $foswiki_fcgi;
fastcgi_split_path_info ^(/bin/\w+)?(.*); # no script, default it to view
include fastcgi_params; # include this first, to allow overrides below
fastcgi_param SCRIPT_FILENAME $foswiki_root/$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
--
GeorgeClark - 11 Dec 2017
And after running this on a live site with
XSendFileContrib protecting some attachments, I've settled on:
server {
...
set $foswiki_root "/var/www/foswiki/distro/core";
root $foswiki_root;
# This handles robots.txt, google keys, etc.
include snippets/common-files.conf;
# Default landing page - exact prefix match.
location = / {
root $foswiki_root;
rewrite .* /bin/view/Main/WebHome;
}
# This regex will override any prefix matches defined further down unless blocked by ^~
location ~ ^/pub/(System|Applications|images|cache)/ {
allow all;
expires 12h;
gzip_static on;
}
# Shorter regex, so if above longer match misses, then send it to xsendfile.
location ~ ^/pub/ {
rewrite ^/pub/(.*)$ /bin/xsendfile/$1;
}
# xsendfile internally redirects here for permitted files.
# ^~ prevents any regex matching if the prefix matches.
location ^~ /protected_files/ {
internal;
alias $foswiki_root/pub/;
}
# This is also an absolute prefix. If /bin/ prefix matches, don't do any further matching.
location ^~ /bin/ {
gzip off;
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(/bin/\w+)(.*);
# Captures two variables ($fastcgi_script_name) and ($fastcgi_path_info)
fastcgi_param SCRIPT_FILENAME $foswiki_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
include fastcgi_params;
}
# regex to pick up all the restricted stuff.
location ~ ^(/lib|/data|/locale|/templates|/tools|/work) {
deny all;
}
# Short URL redirect. Very short match, so this should not override any other specific matces.
location ~ ^/ {
rewrite ^/(.*)$ /bin/view/$1;
}
}
--
GeorgeClark - 12 Mar 2018