Skip to content

Instantly share code, notes, and snippets.

@hwdsl2
Last active June 10, 2021 23:05
Show Gist options
  • Save hwdsl2/d18a387d6436e319b85b to your computer and use it in GitHub Desktop.
Save hwdsl2/d18a387d6436e319b85b to your computer and use it in GitHub Desktop.
Actual nginx.conf for Lin's Tech Blog (http://blog.ls20.com - click for tutorial). Published with Ghost, Nginx and ModSecurity
user nginx;
# Set this to match the number of CPU cores
worker_processes 2;
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;
add_header X-Frame-Options SAMEORIGIN;
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options nosniff;
# HTTP Strict Transport Security - force secure HTTPS connections
# add_header Strict-Transport-Security max-age=15768000;
# add_header X-Cache-Status $upstream_cache_status;
sendfile on;
gzip on;
gzip_comp_level 6;
gzip_disable "msie6";
gzip_min_length 150;
gzip_proxied any;
gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/json application/javascript;
gzip_vary on;
proxy_cache_path /run/shm/nginx levels=1:2 keys_zone=one:8m max_size=200M inactive=1y;
proxy_temp_path /run/shm/nginx/tmp;
# If you do not manage your blog via SSH port forwarding, set these to higher values:
# client_body_buffer_size 128k;
# client_max_body_size 20m;
# Controlling buffer overflow attacks
# http://www.cyberciti.biz/tips/linux-unix-bsd-nginx-webserver-security.html
client_body_buffer_size 8k;
client_header_buffer_size 1k;
client_max_body_size 1m;
large_client_header_buffers 4 8k;
client_body_timeout 12;
client_header_timeout 12;
keepalive_timeout 15 15;
send_timeout 10;
map_hash_bucket_size 256;
# This is for use with CloudFlare Flexible SSL, to identify the "real" scheme of requests
map $http_x_forwarded_proto $real_scheme {
default $scheme;
https https;
}
map $request_uri $loggable {
default 1;
"~^/rss/?$" 0;
"/favicon.ico" 0;
"/browserconfig.xml" 0;
"/sitemap.xml" 0;
"/robots.txt" 0;
}
# These settings provide more detailed Nginx logs. For example, "$real_scheme" is added
# to the default log format. In addition, extra logs will be created in "access_logs".
# Please be sure to create folder "/opt/nginx/logs/access_logs" with these permissions:
# drwx------ 2 nginx root 4096 Apr 9 00:35 access_logs/
log_format main '$remote_addr - $remote_user [$time_local] "$real_scheme" "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /opt/nginx/logs/access.log main if=$loggable;
access_log /opt/nginx/logs/access_logs/$host.log main if=$loggable;
access_log /opt/nginx/logs/access_logs/$host-$status.log main if=$loggable;
ModSecurityEnabled on;
ModSecurityConfig modsecurity.conf;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=1r/s;
# In this block, put all IP addresses (or ranges) that
# you do not want Nginx to log in "access.log"
geo $myips {
default 0;
127.0.0.0/8 1; YOUR_IP_ADDRESS 1;
}
# Try to identify some robots by their IPs (NOT complete!)
geo $botips {
default 0;
# bingbot/msnbot:
157.55.32.0/22 1; 157.55.36.0/24 1; 157.56.229.0/24 1; 157.56.92.0/24 1;
157.56.93.0/24 1; 65.55.24.0/24 1; 65.55.52.0/24 1; 65.55.55.0/24 1;
65.55.213.0/24 1; 65.55.215.0/24 1; 131.253.24.0/22 1; 199.30.16.0/20 1;
157.55.39.0/24 1; 207.46.13.0/24 1; 40.77.167.0/24 1;
# Baiduspider:
123.125.71.0/24 1; 180.76.5.0/24 1; 180.76.6.0/24 1; 220.181.108.0/24 1;
# Googlebot:
209.85.238.0/24 1; 72.14.199.0/24 1; 66.249.64.0/19 1;
}
map $http_user_agent $isbot {
default 0;
"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 1;
"Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" 1;
"Mozilla/5.0 (Windows NT 6.1; rv:6.0) Gecko/20110814 Firefox/6.0 Google Favicon" 1;
"Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)" 1;
"Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)" 1;
"Mozilla/5.0 (compatible; YandexBot/3.0; +http://yandex.com/bots)" 1;
"Mozilla/5.0 (iPhone; CPU iPhone OS 8_1 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B411 Safari/600.1.4 (compatible; YandexMobileBot/3.0; +http://yandex.com/bots)" 1;
"Mozilla/5.0 (compatible; YandexImages/3.0; +http://yandex.com/bots)" 1;
"Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)" 1;
"Mozilla/5.0 (compatible; linkdexbot/2.0; +http://www.linkdex.com/bots/)" 1;
"Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)" 1;
"Mozilla/5.0 (compatible; archive.org_bot; Wayback Machine Live Record; +http://archive.org/details/archive.org_bot)" 1;
"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0); 360Spider(compatible; HaosouSpider; http://www.haosou.com/help/help_3_2.html)" 1;
"Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.89 Safari/537.1; 360Spider(compatible; HaosouSpider; http://www.haosou.com/help/help_3_2.html)" 1;
"Mozilla/5.0 (compatible; MojeekBot/0.6; +https://www.mojeek.com/bot.html)" 1;
"Mozilla/5.0 (compatible; DotBot/1.1; http://www.opensiteexplorer.org/dotbot, [email protected])" 1;
"Mozilla/5.0 (compatible; coccoc/1.0; +http://help.coccoc.com/)" 1;
"Mozilla/5.0 (compatible; MJ12bot/v1.4.5; http://www.majestic12.co.uk/bot.php?+)" 1;
"Mozilla/5.0 (compatible; MegaIndex.ru/2.0; +http://megaindex.com/crawler)" 1;
"Mozilla/5.0 (compatible; SeznamBot/3.2; +http://fulltext.sblog.cz/)" 1;
"Mozilla/5.0 (compatible; AhrefsBot/5.1; +http://ahrefs.com/robot/)" 1;
"Mozilla/5.0 (compatible; Lipperhey-Kaus-Australis/5.0; +https://www.lipperhey.com/en/about/)" 1;
"Mozilla/5.0 (compatible; BLEXBot/1.0; +http://webmeup-crawler.com/)" 1;
"Mozilla/5.0 (compatible; spbot/4.4.2; +http://OpenLinkProfiler.org/bot )" 1;
"Mozilla/5.0 (compatible; Qwantify/2.2w; +https://www.qwant.com/)/*" 1;
"Mozilla/5.0 (compatible; archive.org_bot +http://www.archive.org/details/archive.org_bot)" 1;
"Mozilla/5.0 (compatible; SemrushBot/1.1~bl; +http://www.semrush.com/bot.html)" 1;
"Mozilla/5.0 (compatible; Findxbot/1.0; +http://www.findxbot.com)" 1;
"Y!J-ASR/0.1 crawler (http://www.yahoo-help.jp/app/answers/detail/p/595/a_id/42716/)" 1;
"Sogou web spider/4.0(+http://www.sogou.com/docs/help/webmasters.htm#07)" 1;
"AddThis.com (http://support.addthis.com/)" 1;
"~Tiny Tiny RSS/.* \(http://tt-rss\.org/\)" 1;
"~Googlebot-Mobile/2\.1" 1;
}
map $http_referer $badref {
default 0;
"~*try\.php\?u=http" 1;
"~*(semalt|rankings-analytics|(buttons|videos)-for|(best|success|100dollars|top1)-seo).*\.com" 1;
"~*(baltkurs|(burger|pizza)-imperia|hundejo|hvd-store|pizza-tycoon|wrennmusic|magnet-to-torrent|torrent-to-magnet)\.com" 1;
"~*(cyberspacers\.us|exchange\.cx|nanoyou\.org|justprofit\.xyz|(wordpress-crew|acuclubs|responsive-test)\.net|buyessaynow\.biz)" 1;
}
map $http_user_agent $blocked_ua {
default 0;
"" 1;
"~^$" 1;
"Mozilla/4.0" 1;
"~Mozilla/4\.0 \(compatible; MSIE (4\.0|5\.0|5\.5|6\.0)" 1;
"~*(Indy Library|Squider|User-Agent|libwww-perl|morfeus|urllib|ZmEu|Nutch|masscan|libcurl|Wget)" 1;
}
upstream ghost_upstream {
server 127.0.0.1:2368;
keepalive 64;
}
# These settings are for use with CloudFlare ONLY. They provide
# "real" visitor IPs in your logs instead of CloudFlare IPs.
set_real_ip_from 199.27.128.0/21;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 172.64.0.0/13;
real_ip_header CF-Connecting-IP;
server {
listen 80;
# HTTP/2 is the second major version of the HTTP network protocol
# with many benefits such as improved page loading speed.
listen 443 ssl http2;
server_name blog.ls20.com;
ssl_certificate /opt/nginx/conf/ssl-unified_startssl.crt;
ssl_certificate_key /path/to/my/private_key.pem;
# These SSL settings enable Perfect Forward Secrecy (PFS) if supported
# by the browser. Test your server at: https://www.ssllabs.com/ssltest/
# Due to the SSLv3 POODLE vulnerability, it is excluded from the protocol list.
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDH+AESGCM:DH+AESGCM:ECDH+AES256:DH+AES256:ECDH+AES128:DH+AES:ECDH+3DES:DH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Refer to: https://weakdh.org/sysadmin.html
ssl_dhparam /opt/nginx/conf/dhparams.pem;
# SSL Stapling - reduces latency and improves SSL performance
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /opt/nginx/conf/ssl-stapling_startssl.crt;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 10s;
# Reject all invalid hostnames and un-needed HTTP methods
if ($http_host = '') { return 404; }
if ($host !~* ^blog\.ls20\.com$ ) { return 404; }
if ($request_method !~ ^(GET|HEAD|OPTIONS)$ ) { return 405; }
# Block some referral spams
if ($badref = 1) { return 403; }
root /var/www/blog.ls20.com/public;
# Block "sensitive" locations in Nginx
location ~* \.(db|hbs|conf)$ { deny all; }
location ~ /\. { deny all; }
location ~ ~$ { deny all; }
# If you do not manage your blog via SSH port forwarding, comment out this line:
location ~ ^/(ghost/|signout/) { deny all; }
# Return 404 for some URLs requested by web scanners. They are not needed for Ghost blog.
# Comment out this location block if you use e.g. WordPress or PHP.
location ~* (\.php|manager/html|webdav|invoker|myadmin|pma|phptest|phppath|cgi-bin|wp-admin|wp-login|cfide|web-console|administrator|filemanager|busybox|uploadify|nyet\.gif) {
return 404;
}
# Generate favicons for different devices for your blog
# at this website: http://realfavicongenerator.net/
location ~ ^/(apple-touch-icon|favicon|mstile).*\.png$ {
expires 30d;
access_log off;
}
location ~ ^/(favicon\.ico|browserconfig\.xml)$ { expires 30d; access_log off; }
location ~ ^/(sitemap\.xml|robots\.txt|BingSiteAuth\.xml)$ { access_log off; }
# Static files served directly by Nginx
location ~ ^/assets/(js|css|fonts)/ {
root /var/www/blog.ls20.com/content/themes/casper;
expires 30d;
access_log off;
}
location ~ ^/content/images/ {
root /var/www/blog.ls20.com;
expires 30d;
access_log off;
}
# If you do not manage your blog via SSH port forwarding
# at http://localhost:2368/ghost/, uncomment these two blocks.
# location ~ ^/(img/|css/|lib/|vendor/|fonts/) {
# root /var/www/blog.ls20.com/core/client/assets;
# expires 30d;
# access_log off;
# }
# location ~ ^/(shared/|built/) {
# root /var/www/blog.ls20.com/core;
# expires 30d;
# access_log off;
# }
location / {
limit_conn conn_limit_per_ip 10;
limit_req zone=req_limit_per_ip burst=10 nodelay;
if ($uri ~ ^/rss/?$ ) { set $blocked_ua 0; }
if ($isbot = 1) { set $blocked_ua 0; access_log off; }
if ($botips = 1) { set $blocked_ua 0; access_log off; }
if ($myips = 1) { set $blocked_ua 0; access_log off; }
# Block "bad" user-agents
if ($blocked_ua = 1) { return 307 http://www.browser-update.org/update.html; }
# if ($isbot = 1) { access_log off; }
# if ($botips = 1) { access_log off; }
# if ($myips = 1) { access_log off; }
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 $real_scheme;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_set_header Connection "";
# If you do not manage your blog via SSH port forwarding, uncomment this line:
# proxy_pass_header X-CSRF-TOKEN;
proxy_http_version 1.1;
proxy_cache one;
proxy_cache_key "$real_scheme$host$request_uri";
# To avoid serving "out-of-date" content via Nginx, it is recommended to
# use a shorter time period on the line below (e.g. 10m instead of 30d).
proxy_cache_valid 200 301 302 30d;
proxy_cache_valid 404 10m;
proxy_cache_bypass $myips;
proxy_cache_use_stale error timeout invalid_header updating http_500 http_502 http_503 http_504;
proxy_intercept_errors on;
# If you do not manage your blog via SSH port forwarding, comment out this line:
proxy_ignore_headers Cache-Control;
proxy_hide_header X-Powered-By;
}
location = /503.html { root html; internal; }
location = /50x.html { root html; internal; }
location = /404.html { root html; internal; }
error_page 404 /404.html;
error_page 503 /503.html;
error_page 500 502 504 /50x.html;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment