Skip to content

Instantly share code, notes, and snippets.



Forked from plentz/nginx.conf
Last active Jun 11, 2021
What would you like to do?
Nginx configuration for best security and modest performance. Full info on
#
# latest version on
# security test score:
# your nginx version might not have all directives included, test this configuration before using in production against your nginx:
# $ nginx -c /etc/nginx/nginx.conf -t
server {
# public key, contains your public key and class 1 certificate, to create:
# (example for startssl)
# $ (cat & wget -O - | tee -a /etc/nginx/ssl/domain.pem > /dev/null
ssl_certificate /etc/nginx/ssl/domain.pem;
# private key (decoded), decode encoded with RSA key with command:
# $ openssl rsa -in decoded.key -out domain.key
ssl_certificate_key /etc/nginx/ssl/domain.key;
# Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits
# to generate your dhparam.pem file, run in the terminal:
# $ openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# don't forget to set secure rights to these files:
# $ chmod 400 /etc/nginx/ssl/*
# make it bigger for more sessions, one megabyte for ~ 4000 session
ssl_session_cache shared:SSL:100m;
ssl_session_timeout 60m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ciphers are latest modern from (only place you can trust on web)
# working example:
ssl_ciphers '<paste intermediate ciphersuite here>';
ssl_prefer_server_ciphers on;
# OCSP Stapling ---
# fetch OCSP records from URL in ssl_certificate and cache them
ssl_stapling on;
ssl_stapling_verify on;
# dns resolver, we're using Google IPv4 and IPv6 servers
resolver [2001:4860:4860::8888];
# verify chain of trust of OCSP response using Root CA and Intermediate certs, example for StartSSL:
# $ wget -O - | tee -a ca-certs.pem > /dev/null
ssl_trusted_certificate /etc/nginx/ssl/root_CA_cert_plus_intermediates;
# consider turning 'deferred' off on old versions of nginx if you occur any problems
listen 443 deferred spdy ssl;
listen [::]:443 deferred spdy ssl ipv6only=on;
root /var/local/www/example;
index index.html;
autoindex off;
charset utf-8;
#don't send the nginx version number in error pages and Server header
server_tokens off;
# enabling HSTS(HTTP Strict Transport Security)
add_header Strict-Transport-Security 'max-age=31536000' always;
# enabling Public Key Pinning Extension for HTTP (HPKP)
# tool for checking and generating proper certificates:
# to generate use on of these:
# $ openssl rsa -in my-website.key -outform der -pubout | openssl dgst -sha256 -binary | base64
# $ openssl req -in my-website.csr -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
# $ openssl x509 -in my-website.crt -pubkey -noout | openssl rsa -pubin -outform der | openssl dgst -sha256 -binary | base64
add_header Public-Key-Pins 'pin-sha256="base64+info1="; max-age=31536000' always;
# config to don't allow the browser to render the page inside an frame or
# iframe and avoid clickjacking
# if you need to allow [i]frames, you can use SAMEORIGIN
# or set an uri with ALLOW-FROM uri
# warning, this option breaking some analitics tools
add_header X-Frame-Options DENY;
# when serving user-supplied content, include a
# X-Content-Type-Options: nosniff header along with the Content-Type:
# header to disable content-type sniffing on some browsers.
add_header X-Content-Type-Options nosniff;
# this header enables the Cross-site scripting (XSS) filter, it's usually
# enabled by default anyway, so the role of this header is to re-enable
# the filter for this particular website if it was disabled by the user.
add_header X-XSS-Protection "1; mode=block";
location / {
# try_files might be dangerous, please read:
try_files $uri $uri/ =404;
# deny access to files, starting with dot (hidden) or ending with ~ (temp)
location ~ /\. {
access_log off;
log_not_found off;
deny all;
location ~ ~$ {
access_log off;
log_not_found off;
deny all;
# block of rules for static content
location ~ /{favicon.ico|favicon.png|robots.txt}$ {
access_log off;
log_not_found off;
expires 1y;
add_header Cache-Control public,max-age=259200;
location ~* \.(jpg|jpeg|png|gif|ico|css|js|mp3)$ {
expires 30d;
add_header Cache-Control public,max-age=259200;
server {
# catch all unsecure requests (both IPv4 and IPv6)
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
# this means, *
# permanently redirect client to https version of the site
return 301;

This comment has been minimized.

Copy link

@C0nw0nk C0nw0nk commented Sep 24, 2018

Should use a privacy respecting and worlds fastest DNS resolver instead of Google's and IPv4 resolver what is slow and Does not respect privacy or security. Cloudflares resolver also includes both IPv4 IPv6 resolver and alternative fallback DNS resolver alternative resolver for is for IPV4 is and IPv6 2606:4700:4700::1001 as can be found on their website privacy security and speed comes first.

Here is my code for their resolver to support both IPv4 and IPv6 (Can disable IPv6 and will still work universal setup)

#Cloudflare resolver
resolver [2606:4700:4700::1111] [2606:4700:4700::1001];

Fastest DNS resolvers in the world ( is the fastest most secured and private unlike google)!dns-resolvers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment