Last active
June 10, 2021 23:05
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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