Last active
February 27, 2023 23:39
-
-
Save andybeak/d44f87528a2ed94f9e7a to your computer and use it in GitHub Desktop.
An nginx config for Wordpress #nginx #config #wordpress
This file contains hidden or 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
# Read http://codex.wordpress.org/Nginx | |
# http://wiki.nginx.org/Pitfalls | |
# http://wiki.nginx.org/QuickStart | |
# http://www.queryadmin.com/854/secure-wordpress-nginx/ | |
# http://tautt.com/best-nginx-configuration-for-security/ | |
# https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html | |
# | |
# Generate your key with: openssl dhparam -out /etc/nginx/ssl/dhparam.pem 2048 | |
# Generate certificate: sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt | |
server { | |
server_name www.example.com; | |
listen [::]:8080; | |
root /home/web/sites/default/html/; | |
index index.php; | |
access_log /home/web/sites/default/logs/access.log combined; | |
error_log /home/web/sites/default/logs/error.log warn; | |
include /home/web/sites/default/html/nginx.conf; | |
add_header X-Content-Type-Options "nosniff"; | |
add_header X-XSS-Protection "1; mode=block"; | |
if ($server_protocol ~* "HTTP/1.0") { | |
return 444; | |
} | |
location / { | |
# refer to https://www.proteansec.com/linux/naxsi/ | |
# include /etc/nginx/naxsi.rules; | |
# include the "?$args" part so non-default permalinks doesn't break when using query string | |
try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args ; | |
# if you're not using w3tc then comment the line above and uncomment the line below | |
# try_files $uri $uri/ /index.php?$args; | |
} | |
location /wp-admin/ { | |
return 301 https://$server_name$request_uri; | |
} | |
location /mystery-login { | |
return 301 https://$server_name$request_uri; | |
} | |
# Prevent any potentially-executable files in the uploads directory from being executed | |
location ~* /uploads/ { | |
location ~ \.php {return 403;} | |
} | |
# Do not log favicon.ico requests | |
location = /favicon.ico { | |
log_not_found off; | |
access_log off; | |
} | |
# Do not log robots.txt requests | |
location = /robots.txt { | |
allow all; | |
log_not_found off; | |
access_log off; | |
} | |
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ { | |
expires max; | |
log_not_found off; | |
} | |
include global/w3tc.conf; | |
# Common deny or internal locations, to help prevent access to not-public areas | |
location ~* wp-admin/includes { deny all; } | |
location ~* wp-includes/theme-compat/ { deny all; } | |
location ~* wp-includes/js/tinymce/langs/.*\.php { deny all; } | |
location /wp-content/ { internal; } | |
location /wp-includes/ { internal; } | |
location ~* wp-config.php { deny all; } | |
# Rewrite rules for Wordpress SEO by Yoast | |
rewrite ^/sitemap_index\.xml$ /index.php?sitemap=1 last; | |
rewrite ^/([^/]+?)-sitemap([0-9]+)?\.xml$ /index.php?sitemap=$1&sitemap_n=$2; | |
# Add trailing slash to */wp-admin requests | |
rewrite /wp-admin$ $scheme://$host$uri/ permanent; | |
# Redirect 403 errors to 404 error to fool attackers | |
error_page 403 = 404; | |
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac). | |
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban) | |
location ~ /\. { | |
deny all; | |
} | |
location ~ \.php$ { | |
fastcgi_split_path_info ^(.+?\.php)(/.*)$; | |
if (!-f $document_root$fastcgi_script_name) { | |
return 404; | |
} | |
fastcgi_keep_conn on; | |
fastcgi_pass 127.0.0.1:9000; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
include fastcgi_params; | |
} | |
} | |
server { | |
server_name example.com; | |
listen 8080; | |
return 301 $scheme://www.example.com$request_uri; | |
} | |
server { | |
server_name www.example.com; | |
listen 443 ssl; | |
server_tokens off; | |
add_header X-Frame-Options SAMEORIGIN; | |
add_header X-Content-Type-Options nosniff; | |
add_header X-XSS-Protection "1; mode=block"; | |
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://ssl.google-analytics.com https://assets.zendesk.com https://connect.facebook.net; img-src 'self' https://ssl.google-analytics.com https://s-static.ak.facebook.com https://assets.zendesk.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://assets.zendesk.com; font-src 'self' https://themes.googleusercontent.com; frame-src https://assets.zendesk.com https://www.facebook.com https://s-static.ak.facebook.com https://tautt.zendesk.com; object-src 'none'"; | |
root /home/web/sites/default/html/; | |
index index.php; | |
access_log /home/web/sites/default/logs/access_ssl.log combined; | |
error_log /home/web/sites/default/logs/error_ssl.log warn; | |
# enable session resumption to improve https performance | |
# http://vincent.bernat.im/en/blog/2011-ssl-session-reuse-rfc5077.html | |
ssl_session_cache shared:SSL:50m; | |
ssl_session_timeout 5m; | |
# Diffie-Hellman parameter for DHE ciphersuites, recommended at least 2048 bits | |
# generate with openssl dhparam -out dhparam.pem 4096 | |
ssl_dhparam /etc/nginx/ssl/dhparam.pem; | |
# see https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html | |
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH'; | |
ssl_protocols TLSv1.2; | |
ssl_prefer_server_ciphers on; | |
keepalive_timeout 60; | |
# config to enable HSTS(HTTP Strict Transport Security) https://developer.mozilla.org/en-US/docs/Security/HTTP_Strict_Transport_Security | |
# to avoid ssl stripping https://en.wikipedia.org/wiki/SSL_stripping#SSL_stripping | |
add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; | |
ssl_certificate /etc/nginx/ssl/nginx.crt; | |
ssl_certificate_key /etc/nginx/ssl/nginx.key; | |
location / { | |
# include the "?$args" part so non-default permalinks doesn't break when using query string | |
try_files /wp-content/w3tc/pgcache/$cache_uri/_index.html $uri $uri/ /index.php?$args ; | |
} | |
# Add trailing slash to */wp-admin requests | |
rewrite /wp-admin$ $scheme://$host$uri/ permanent; | |
include /home/web/sites/default/html/nginx.conf; | |
rewrite ^(/)?mystery-login/?$ /wp-login.php?$query_string break; | |
location ~ \.php$ { | |
fastcgi_split_path_info ^(.+?\.php)(/.*)$; | |
if (!-f $document_root$fastcgi_script_name) { | |
return 404; | |
} | |
fastcgi_keep_conn on; | |
fastcgi_pass 127.0.0.1:9000; | |
fastcgi_index index.php; | |
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; | |
include fastcgi_params; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment