Skip to content

Instantly share code, notes, and snippets.

@andybeak
Last active February 27, 2023 23:39
Show Gist options
  • Save andybeak/d44f87528a2ed94f9e7a to your computer and use it in GitHub Desktop.
Save andybeak/d44f87528a2ed94f9e7a to your computer and use it in GitHub Desktop.
An nginx config for Wordpress #nginx #config #wordpress
# 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