Skip to content

Instantly share code, notes, and snippets.

@ivanmonteiro
Created October 10, 2020 00:52
Show Gist options
  • Select an option

  • Save ivanmonteiro/82683fc41880a8799cf7bd3a53004db1 to your computer and use it in GitHub Desktop.

Select an option

Save ivanmonteiro/82683fc41880a8799cf7bd3a53004db1 to your computer and use it in GitHub Desktop.
Best practice secure NGINX configuration for WordPress
# From blog post https://www.getpagespeed.com/server-setup/nginx/best-practice-secure-nginx-configuration-for-wordpress
server {
server_name example.com;
root /srv/www/example.com/public;
security_headers on;
# do not load WordPress when redirecting /index.php to /
location = /index.php {
return 301 /;
}
# do not load WordPress when redirecting /wp-admin to to /wp-admin/
location = /wp-admin {
return 301 /wp-admin/;
}
location / {
# any URI without extension is routed through PHP-FPM (WordPress controller)
location ~ ^[^.]*$ {
length_hiding on;
fastcgi_param SCRIPT_FILENAME $document_root/index.php;
include includes/php-example.com.conf;
}
# allow only a handful of PHP files in root directory to be interpreted
# wp-cron.php ommited on purpose as it should *not* be web accessible, see proper setup
# https://www.getpagespeed.com/web-apps/wordpress/wordpress-cron-optimization
location ~ ^/wp-(?:comments-post|links-opml|login|mail|signup|trackback)\.php$ {
length_hiding on;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include includes/php-example.com.conf;
}
# other PHP files "do not exist"
location ~ \.php$ {
return 404;
}
}
location = /xmlrpc.php {
# allows JetPack servers only
allow 192.0.0.0/16;
deny all;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include includes/php-example.com.conf;
}
location /wp-admin/ {
index index.html index.php;
location = /wp-admin/admin-ajax.php {
# this location often spits json, which will be broken if length hiding is used
# so no length hiding here
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include includes/php-example.com.conf;
}
# numerous files under wp-admin are allowed to be interpreted
# no fancy filenames allowed (lowercase with hyphens are OK)
# only /wp-admin/foo.php or /wp-admin/{network,user}/foo.php allowed
location ~ ^/wp-admin/(?:network/|user/)?[\w-]+\.php$ {
length_hiding on;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include includes/php-example.com.conf;
}
}
location /wp-content/ {
# contents under wp-content are typically highly cacheable
immutable on;
# hide and do not interpret internal plugin or user uploaded scripts
location ~ \.php$ {
return 404;
}
}
# hide any hidden files
location ~ /\. {
deny all;
}
# hide any backup or SQL dump files
location ~ ^.+\.(sql|bak|php~|php#|php.save|php.swp|php.swo)$ {
return 404;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment