My rewrite rules for WordPress:
#https://www.hongkiat.com/blog/nginx-rules-for-wordpress-security/
location ~* /xmlrpc.php$ {
allow 172.0.1.1;
deny all;
}
if ($request_method !~ GET|POST$ ) {
return 444;
}
location ~* /(?:uploads|files|wp-content|wp-includes|akismet)/..php$ {
deny all;
access_log off;
log_not_found off;
}
location ~ /.(svn|git)/ {
deny all;
access_log off;
log_not_found off;
}
location ~ /.ht {
deny all;
access_log off;
log_not_found off;
}
location ~ /.user.ini {
deny all;
access_log off;
log_not_found off;
}
#Hide the nginx version.
server_tokens off;
#Hide the PHP version.
fastcgi_hide_header X-Powered-By;
proxy_hide_header X-Powered-By;
add_header X-Frame-Options SAMEORIGIN;
add_header Strict-Transport-Security "max-age=31536000";
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
#https://www.hongkiat.com/blog/nginx-rules-for-wordpress-security/
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}