Skip to content

Instantly share code, notes, and snippets.

Last active November 3, 2022 05:37
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save hwdsl2/2556d2cf9d73ba858c63 to your computer and use it in GitHub Desktop.
Example nginx.conf for Ghost blog with Nginx and Naxsi -
user nginx;
worker_processes 2; # Set this equal to the number of CPU cores
events { worker_connections 1024; }
http {
server_names_hash_bucket_size 64;
types_hash_max_size 2048;
server_tokens off;
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 15;
gzip on;
gzip_comp_level 6;
gzip_disable "msie6";
gzip_min_length 150;
gzip_proxied any;
gzip_types text/plain text/xml text/css application/json application/javascript;
gzip_vary on;
proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=one:8m max_size=1000M inactive=60m;
proxy_temp_path /var/tmp;
client_max_body_size 20m;
client_body_buffer_size 128k;
include /etc/nginx/naxsi_core.rules;
upstream ghost_upstream {
keepalive 64;
server {
listen 80;
listen 443 ssl;
server_name YOUR.DOMAIN.NAME;
ssl_certificate /opt/nginx/conf/ssl-unified.crt;
ssl_certificate_key /opt/nginx/conf/YOUR.DOMAIN.NAME.pem;
# Due to the SSLv3 POODLE vulnerability, it is excluded from the protocol list.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers RC4:HIGH:!MEDIUM:!aNULL:!MD5:!DH:!EDH;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
if ($request_method !~ ^(GET|HEAD|POST|PUT|DELETE)$ ) { return 444; }
if ($host != $server_name) {
return 301 $scheme://$server_name$request_uri;
location ~* \.(db|hbs|conf)$ { deny all; }
location ~ /\. { deny all; }
location ~ ~$ { deny all; }
# Uncomment this block if you wish to use your own files
# instead of those auto-generated by Ghost blog
# location ~ ^/(sitemap\.xml|robots\.txt|favicon\.ico)$ {
# root /var/www/YOUR.DOMAIN.NAME/public;
# access_log off;
# log_not_found off;
# }
# Static files served directly by Nginx
location ~ ^/assets/(img|js|css|fonts)/ {
root /var/www/YOUR.DOMAIN.NAME/content/themes/casper;
expires 30d;
access_log off;
location ~ ^/(img/|css/|lib/|vendor/|fonts/) {
root /var/www/YOUR.DOMAIN.NAME/core/client/assets;
expires 30d;
access_log off;
location ~ ^/content/images/ {
root /var/www/YOUR.DOMAIN.NAME;
expires 30d;
access_log off;
location ~ ^/(shared/|built/) {
root /var/www/YOUR.DOMAIN.NAME/core;
expires 30d;
access_log off;
location / {
include /etc/nginx/mysite.rules;
proxy_pass http://ghost_upstream;
proxy_redirect off;
proxy_read_timeout 180s;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
proxy_pass_header X-CSRF-TOKEN;
proxy_http_version 1.1;
proxy_cache one;
proxy_cache_key "$scheme$host$request_uri";
proxy_cache_valid 200 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_intercept_errors on;
proxy_hide_header X-Powered-By;
location = /RequestDenied { return 500; }
location = /50x.html { root html; internal; }
#error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
Copy link

ghost commented Mar 29, 2020

Very impressive. Thank you.
I benefited most from seeing how you set the headers in the proxy. I used a subset of the ones you provided and it works for me.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
should be
ssl_protocols TLSv1.1 TLSv1.2;
these days now that TLSv1 is no longer considered to be secure.

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