user nginx; worker_processes auto; events { worker_connections 1024; multi_accept on; } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 15; types_hash_max_size 2048; server_tokens off; client_max_body_size 64m; limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; include mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Gzip Settings ## gzip on; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; gzip_vary on; gzip_proxied any; gzip_comp_level 8; # gzip_buffers 16 8k; # gzip_http_version 1.1; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/rss+xml text/javascript image/svg+xml application/vnd.ms-fontobject application/x-font-ttf font/opentype; # catch all # CATCHALL http server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/local/nginx/html; index index.php index.html index.htm; } # CATCHALL https server { listen 443 default_server; listen [::]:443 default_server; server_name _; root /usr/local/nginx/html; ssl on; ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/keys/0000_key-certbot.pem; include /etc/nginx/cipherlist.conf; index index.php index.html index.htm; } # http -> https server { listen 80; listen [::]:80; server_name .domain.tld; return 301 https://$host$request_uri; } # www.domain.tld -> domain.tld server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.domain.tld; include /etc/nginx/cipherlist.conf; ssl on; ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/keys/0000_key-certbot.pem; location / { return 301 https://domain.tld$request_uri; } } # domain.tld server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name domain.tld; access_log /var/log/nginx/domain.tld.access.log; error_log /var/log/nginx/domain.tld.error.log; #charset koi8-r; ssl on; ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem; ssl_certificate_key /etc/letsencrypt/keys/0000_key-certbot.pem; include /etc/nginx/cipherlist.conf; #access_log logs/host.access.log main; root /usr/local/nginx/html; index index.php index.html index.htm; autoindex off; location / { #try_files $uri $uri/ /index.php?q=$uri&$args; try_files $uri $uri/ @phpmagic; } location @phpmagic { rewrite ^/(.+)$ /index.php?p=$1 last; } # pass the PHP scripts to FastCGI server listening on /run/php/php7.0-fpm.sock location ~ [^/]\.php(/|$) { fastcgi_split_path_info ^(.+?\.php)(/.*)$; if (!-f $document_root$fastcgi_script_name) { return 404; } fastcgi_param HTTP_PROXY ""; fastcgi_pass unix:/run/php/php7.0-fpm.sock; fastcgi_index index.php; include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; } # Deny access to uploads that aren’t images, videos, music, etc. location ~* ^/wp-content/uploads/.*.(html|htm|shtml|php|js|swf)$ { deny all; } # Keep nosey people from discivering categories by number location ~* /categories/([0-9]|[1-9][0-9]|[1-9][0-9][0-9])$ { return 404; } # Deny, drop, or internal locations location ~ /\. { access_log off; log_not_found off; deny all; } location ~ ~$ { access_log off; log_not_found off; deny all; } location = /robots.txt { access_log off; log_not_found off; } location ^~ favicon { access_log off; log_not_found off; } location ^~ /conf/ { internal; } # Cache static files for as long as possible location ~*.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf|cur)$ { expires max; log_not_found off; access_log off; } # CORS policy location ~* \.(eot|ttf|woff|woff2)$ { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # # Custom headers and headers various browsers *should* be OK with but aren't # add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; # # Tell client that this pre-flight info is valid for 20 days # add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } if ($request_method = 'POST') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; } if ($request_method = 'GET') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Expose-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; } } # Common sense location /xmlrpc.php { deny all; } location ~* wp-config.php { deny all; } Rate limit access to wp-login.php to block against brute force attacks. location = /wp-login.php { limit_req zone=one burst=1 nodelay; fastcgi_pass unix:/run/php/php7.0-fpm.sock; } location ~* wp-settings.php { deny all; } location ~* /wp-includes/.*.php$ { deny all; access_log off; log_not_found off; } location ~* /wp-content/.*.php$ { deny all; access_log off; log_not_found off; } # pagespeed stuff pagespeed on; pagespeed ModifyCachingHeaders on; pagespeed FileCachePath /var/ngx_pagespeed_cache; location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; } location ~ "^/pagespeed_static/" { } location ~ "^/ngx_pagespeed_beacon$" { } pagespeed EnableFilters lazyload_images; pagespeed EnableFilters insert_dns_prefetch; pagespeed EnableFilters remove_comments; pagespeed EnableFilters collapse_whitespace; pagespeed EnableFilters inline_preview_images; pagespeed LoadFromFile "https://domain.tld" "/usr/local/nginx/html/"; pagespeed SslCertDirectory /etc/letsencrypt/live/domain.tld/; pagespeed SslCertFile /etc/letsencrypt/live/domain.tld/fullchain.pem; #error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }