Skip to content

Instantly share code, notes, and snippets.

@mrhahn3000
Last active January 26, 2021 16:40
Show Gist options
  • Save mrhahn3000/373a307cf55d57fe475cd445f0523077 to your computer and use it in GitHub Desktop.
Save mrhahn3000/373a307cf55d57fe475cd445f0523077 to your computer and use it in GitHub Desktop.
This is a very good configuration for Ghost Blog behind an ngnix web server hosted on a Raspberry Pi. All settings regarding security, secrecy and performance :) Using Let's encrypt as certificate provider.
##
# Caching
##
# sets the proxy cache path location, max size 2g
proxy_cache_path /var/cache/nginx/ levels=1:2 keys_zone=blog_cache:10m max_size=2g inactive=120m;
# add a cache HIT/MISS header
add_header X-Proxy-Cache $upstream_cache_status;
# transfers the 'Host' header to the backend
proxy_set_header Host $http_host;
# uses the defined cache zone
proxy_cache blog_cache;
# cache 200 10 minutes, 404 1 minute, others status codes not cached
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
# transfers real client IP to your ghost app,
# otherwise you would see your server ip
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# Allow the browser to cache the full page for 10 minutes
expires 10m;
##
# HTTP Server
##
server {
listen [::]:80 http2 ipv6only=on;
server_name yourdomain.com www.yourdomain.com;
root /var/www/ghost;
# Prevent Bots from crawling the ghost admin, about, imprint and data-privacy pages
location /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /ghost/\nDisallow: /imprint\nDisallow: /data-privacy\nDisallow: /about\n";
}
return 301 https://$server_name$request_uri;
}
##
# HTTPS Server
##
server {
listen [::]:443 ssl http2 default_server ipv6only=on;
server_name yourdomain.com www.yourdomain.com;
root /var/www/ghost;
# Prevent Bots from crawling the ghost admin, about, imprint and data-privacy pages
location /robots.txt {
add_header Content-Type text/plain;
return 200 "User-agent: *\nDisallow: /ghost/\nDisallow: /imprint\nDisallow: /data-privacy\nDisallow: /about\n";
}
# API
location ~ ^/(?:ghost/api) {
# Tell the browser to don't cache API calls
expires 0;
add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
proxy_pass http://127.0.0.1:2368;
}
# add some caching on static assets
location ~* \.(jpg|jpeg|png|gif|ico|css|js|eot|woff)$ {
# ghost sends Cache-Control max-age=0 on CSS/JS for now
proxy_ignore_headers "Cache-Control";
# Allow the browser to cache static files for 30 days
expires 30d;
proxy_pass http://127.0.0.1:2368;
}
# remove caching on admin urls
location ~ ^/(?:ghost) {
# For extra security, add a basic auth for admin area
# auth_basic "Restricted";
# auth_basic_user_file /etc/nginx/include/htpasswd;
# Tell the browser to don't cache admin calls
expires 0;
add_header Cache-Control "no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0";
proxy_pass http://127.0.0.1:2368;
}
location / {
# ghost sends a 'set-cookie' header on every request
# nginx says "no caching" if 'set-cookie' is set
# we do not need cookies on non-admin pages (blog posts)
# so we ignore cookies and we hide them on pages other than /ghost/ (admin)
proxy_ignore_headers "Set-Cookie";
proxy_hide_header "Set-Cookie";
proxy_ignore_headers "Cache-Control";
proxy_hide_header "Cache-Control";
proxy_pass http://127.0.0.1:2368;
}
##
# SSL
##
ssl on;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
}
##
# Gzip Settings
##
gzip on;
gzip_static on;
gzip_disable "msie6";
gzip_min_length 1100;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types image/svg+xml text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json application/javascript text/x-component font/truetype font/opentype;
##
# Misc
##
# do not show incoming Etags, if-modified-since is sufficient
proxy_hide_header Etag;
proxy_set_header X-NginX-Proxy true;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_hide_header X-Powered-By;
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
include /etc/nginx/ssl.conf;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
include /etc/nginx/gzip.conf;
##
# Virtual Host Configs
##
include /etc/nginx/security.conf;
include /etc/nginx/caching.conf;
include /etc/nginx/misc.conf;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
##
# Security Stuff
##
add_header X-XSS-Protection "1; mode=block";
add_header X-Frame-Options "DENY";
add_header X-Content-Type-Options nosniff;
##
# Harden nginx against DDOS
##
client_header_timeout 10;
client_body_timeout 10;
keepalive_timeout 10 10;
send_timeout 10;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
ssl_session_timeout 10m;
ssl_session_cache shared:SSL:10m;
##
# Forward Secrecy
##
# Enable most secure ciphers
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:ECDHE-RSA-AES128-GCM-SHA256:AES256+EECDH:DHE-RSA-AES128-GCM-SHA256:AES256+EDH:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4';
ssl_dhparam /etc/nginx/dh2048.pem;
ssl_ecdh_curve secp384r1;
# Enable OCSP Stapling
resolver 8.8.8.8 8.8.4.4;
ssl_stapling on;
# Enable HSTS for a year
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment