Skip to content

Commit

Permalink
Add Prepared configuration for Nginx
Browse files Browse the repository at this point in the history
This setup features some common, reusable configuration (caching, listening…)
in the includes folder, and some sane and safe default configuration for SSL.
  • Loading branch information
Kissaki committed Dec 8, 2015
0 parents commit c3d551d
Show file tree
Hide file tree
Showing 23 changed files with 361 additions and 0 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Prepared configuration for Nginx.

Managing multiple webpages and subdomains requires some structuring,
and reusing common configuration makes sense.

This setup features some common, reusable configuration (caching, listening…)
in the includes folder, and some sane and safe default configuration for SSL.

sites-available contains an example configuration for a subdomain,
including HTTP to HTTPS rewrite, redirection, and seo-url for some
PHP software.

Now that [letsencrypt](http://letsencrypt.org/) is in open beta, a configuration file
`acme-challenge` is also included to map the challenge url path to
a common location (the challenge is temporary, and has nothing to do
with the actual website).

While some software is not able to handle HTTP and HTTPS at the same
time, since letsencrypt is usable, from now on everything should
be set up to only be served as HTTPS. Thus, HTTP to HTTPS redirection
should be used if it was previously available on HTTP. If not, just
do not provide HTTP at all; browsers will automatically pick up HTTPS.

mime-types was extended; e.g. for json.

The default SSL configuration has been moved out of nginx.conf into includes/ssl.
3 changes: 3 additions & 0 deletions conf.d/php-https-fix.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
map $scheme $fastcgi_param_https {
https on;
}
5 changes: 5 additions & 0 deletions includes/acme-challenge
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
location /.well-known/acme-challenge/ {
# When running the letsencrypt client, this is the path to pass as --webroot-path
root /var/www/acme-challenges;
break;
}
2 changes: 2 additions & 0 deletions includes/cache-12h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_header Cache-Control "public";
expires 12h;
2 changes: 2 additions & 0 deletions includes/cache-12h-private
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
add_header Cache-Control "private";
expires 12h;
1 change: 1 addition & 0 deletions includes/cache-no
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
expires epoch;
1 change: 1 addition & 0 deletions includes/cache-no-store
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_header Cache-Control "no-store";
3 changes: 3 additions & 0 deletions includes/common
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
location = /robots.txt { access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }
include includes/deny-dotfiles;
4 changes: 4 additions & 0 deletions includes/deny-dotfiles
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Deny access to hidden dotfiles (beginning with '.')
location /. {
deny all;
}
4 changes: 4 additions & 0 deletions includes/deny-htfiles
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Deny access to .htaccess files, if Apache's document root concurs with nginx's one
location /.ht {
deny all;
}
3 changes: 3 additions & 0 deletions includes/deny-silent
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
deny all;
access_log off;
log_not_found off;
28 changes: 28 additions & 0 deletions includes/fastcgi_params
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

fastcgi_param GATEWAY_INTERFACE CGI/1.1;
fastcgi_param SERVER_SOFTWARE nginx/$nginx_version;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
#fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_param REQUEST_URI $request_uri;
fastcgi_param DOCUMENT_URI $document_uri;
fastcgi_param DOCUMENT_ROOT $document_root;
fastcgi_param SERVER_PROTOCOL $server_protocol;

fastcgi_param HTTPS $https;

fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param REMOTE_PORT $remote_port;
fastcgi_param SERVER_ADDR $server_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_NAME $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
#fastcgi_param REDIRECT_STATUS 200;

fastcgi_read_timeout 120s;
2 changes: 2 additions & 0 deletions includes/listen-http
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
listen 80;
listen [::]:80;
2 changes: 2 additions & 0 deletions includes/listen-http-https
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
include includes/listen-http;
include includes/listen-https;
2 changes: 2 additions & 0 deletions includes/listen-https
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
listen 443 ssl;
listen [::]:443 ssl;
3 changes: 3 additions & 0 deletions includes/php
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
location ~ \.php$ {
include includes/php-inner;
}
8 changes: 8 additions & 0 deletions includes/php-inner
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# http://wiki.nginx.org/Pitfalls#Passing_Uncontrolled_Requests_to_PHP
try_files $uri =404;

include includes/fastcgi_params;
fastcgi_index index.php;

#fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
39 changes: 39 additions & 0 deletions includes/ssl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# nginx HTTPS doc: http://nginx.org/en/docs/http/configuring_https_servers.html
# nginx ssl module doc: http://nginx.org/en/docs/http/ngx_http_ssl_module.html
# Secure HTTPS Guidelines: https://www.ssllabs.com/downloads/SSL_TLS_Deployment_Best_Practices_1.3.pdf
# Mozilla tool for configuration https://mozilla.github.io/server-side-tls/ssl-config-generator/?server=nginx-1.8.0&openssl=1.0.1f&hsts=yes&profile=intermediate
# https://bettercrypto.org/static/applied-crypto-hardening.pdf
# https://www.ssllabs.com/downloads/SSL_TLS_Deployment_Best_Practices.pdf
# Test: https://www.ssllabs.com/ssltest/

# For performance: Session cache, shared across workers.
# Lifetime increased. For effect, general keep-alive should already be enabled.
ssl_session_cache shared:SSL:50m;
ssl_session_timeout 1h;

# SSLv2 SSLv3 must not be supported. TLS are the successors. Use TLSv1.1 and TLSv1.2.
# TLSv1 is secure with careful configuration, but maybe should be supported for old clients.
# TLS > 1.0 requires openssl > 1.0 (`openssl version`) - will only work if available.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

# Specifies that server ciphers should be preferred over client ciphers when using the SSLv3 and TLS protocols.
# http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_prefer_server_ciphers
ssl_prefer_server_ciphers on;

# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
# generate with openssl dhparam -out dhparam.pem 2048
ssl_dhparam /etc/ssl/dhparam.pem;

# default: HIGH:!aNULL:!MD5
# example: ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv3:+EXP;
# For full list see command 'openssl ciphers'
# Value result can be checked with openssl ciphers -v '<value>'
#ssl_ciphers DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA;
# ssl_ciphers HIGH:!aNULL:!MD5:!DSS:!RC4;

# bettercrypto cryptohardening recommendation
#ssl_ciphers 'EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!ECDSA:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA';
# Mozilla tool intermediate (compatible to older clients)
#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:kEDH+AESGCM: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:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-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';
# Mozilla tool modern
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:kEDH+AESGCM: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:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK';
11 changes: 11 additions & 0 deletions includes/ssl-hsts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security
# Instruct browsers to only interact with HTTPS
# Note: Using values lower than 6 months makes SSL Labs check complain
#add_header Strict-Transport-Security max-age=10000;
# one month
#add_header Strict-Transport-Security max-age=2628000;
# six months
add_header Strict-Transport-Security max-age=15768000;

# use this only if all subdomains support HTTPS!
# add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
8 changes: 8 additions & 0 deletions includes/ssl-stapling
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# https://blog.mozilla.org/security/2013/07/29/ocsp-stapling-in-firefox/
# Send cert validity information ourselves, so the user does not have to ask the CA (who
# then knows the user visited the website).
# Test with openssl s_client -connect www.example.com:443 -servername www.example.com -status < /dev/null | grep OCSP
ssl_stapling on;
ssl_stapling_verify on;
# Public Google DNS 8.8.8.8
resolver 8.8.8.8;
90 changes: 90 additions & 0 deletions mime.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
application/javascript js;
application/atom+xml atom;
application/rss+xml rss;

text/markdown; charset=UTF-8 md;
text/mathml mml;
text/plain txt;
text/vnd.sun.j2me.app-descriptor jad;
text/vnd.wap.wml wml;
text/x-component htc;

image/png png;
image/tiff tif tiff;
image/vnd.wap.wbmp wbmp;
image/x-icon ico;
image/x-jng jng;
image/x-ms-bmp bmp;
image/svg+xml svg svgz;
image/webp webp;

application/font-woff woff;
application/java-archive jar war ear;
application/json json;
application/mac-binhex40 hqx;
application/msword doc;
application/pdf pdf;
application/postscript ps eps ai;
application/rtf rtf;
application/vnd.apple.mpegurl m3u8;
application/vnd.ms-excel xls;
application/vnd.ms-fontobject eot;
application/vnd.ms-powerpoint ppt;
application/vnd.wap.wmlc wmlc;
application/vnd.google-earth.kml+xml kml;
application/vnd.google-earth.kmz kmz;
application/x-7z-compressed 7z;
application/x-cocoa cco;
application/x-java-archive-diff jardiff;
application/x-java-jnlp-file jnlp;
application/x-makeself run;
application/x-perl pl pm;
application/x-pilot prc pdb;
application/x-rar-compressed rar;
application/x-redhat-package-manager rpm;
application/x-sea sea;
application/x-shockwave-flash swf;
application/x-stuffit sit;
application/x-tcl tcl tk;
application/x-x509-ca-cert der pem crt;
application/x-xpinstall xpi;
application/xhtml+xml xhtml;
application/xspf+xml xspf;
application/zip zip;

application/octet-stream bin exe dll;
application/octet-stream deb;
application/octet-stream dmg;
application/octet-stream iso img;
application/octet-stream msi msp msm;

application/vnd.openxmlformats-officedocument.wordprocessingml.document docx;
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx;
application/vnd.openxmlformats-officedocument.presentationml.presentation pptx;

audio/midi mid midi kar;
audio/mpeg mp3;
audio/ogg ogg;
audio/x-m4a m4a;
audio/x-realaudio ra;

video/3gpp 3gpp 3gp;
video/mp2t ts;
video/mp4 mp4;
video/mpeg mpeg mpg;
video/quicktime mov;
video/webm webm;
video/x-flv flv;
video/x-m4v m4v;
video/x-mng mng;
video/x-ms-asf asx asf;
video/x-ms-wmv wmv;
video/x-msvideo avi;
}
51 changes: 51 additions & 0 deletions nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
worker_connections 768;
# multi_accept on;
}

http {

##
# Basic Settings
##

sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;

# server_names_hash_bucket_size 64;
server_name_in_redirect on;

include /etc/nginx/mime.types;
default_type application/octet-stream;

include includes/ssl;

##
# Logging Settings
##

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

##
# Gzip Settings
##

gzip on;
gzip_disable "msie6";

##
# Virtual Host Configs
##

include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
63 changes: 63 additions & 0 deletions sites-available/example.org.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

# Redirect unhandled subdomains
server {
include includes/listen-http-https;
server_name www.example.org 127.0.0.1;
rewrite ^ $scheme://example.org$request_uri?;
}

# Enforce HTTPS
server {
include includes/listen-http;
include includes/acme-challenge;
server_name example.org;
rewrite ^ https://$server_name$request_uri? permanent;
}

server {
include includes/listen-https;
include includes/ssl-stapling;
include includes/ssl-hsts;
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/example.org/chain.pem;

server_name example.org;

root /var/www/example.org/htdocs;
index index.html index.php;

# Make sure to create these folders before hand!
access_log /var/log/nginx/example/example.access.log;
error_log /var/log/nginx/example/example.error.log;

# Static Redirects (recommendation: move them to a site specific include file to reduce clutter here)
location = /old/url/path {
rewrite ^ $scheme://example.org/new/url permanent;
}

include includes/deny-dotfiles;

location /images/ {
include includes/cache-12h;
}
location /live-stats/ {
include includes/cache-no;
}

location /joomla {
# Joomla
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location /wordpress {
# Wordpress
try_files $uri $uri/ /wordpress/index.php?q=$uri&$args;
# Wordpress (it doesn't REALLY need the "q" parameter)
#try_files $uri $uri/ /index.php;
}
location /piwik/ {
alias /var/www/piwik/htdocs/piwik;
}

include includes/php;
}

0 comments on commit c3d551d

Please sign in to comment.