I prepared a list of useful .htaccess examples for my WordCamp Brno talk (2017-10-21):
| #Do not copy&paste whole file, find only interesting parts! | |
| #HTTP authentification | |
| AuthType Basic | |
| AuthName "Log in" | |
| AuthUserFile /path/to/.htpasswd | |
| Require valid-user | |
| #Security headers | |
| <IfModule mod_headers.c> | |
| Header set X-XSS-Protection "1; mode=block" | |
| Header set X-Frame-Options SAMEORIGIN | |
| Header set X-Content-Type-Options nosniff | |
| Header set Strict-Transport-Security "max-age=15768000;" env=HTTPS | |
| </IfModule> | |
| #Expires Headers – static files | |
| <IfModule mod_expires.c> | |
| <FilesMatch "\.(?i:gif|jpe?g|png|js|css|swf|ico|woff|svg)$"> | |
| ExpiresActive on | |
| ExpiresDefault "access plus 365 days" | |
| </Filesmatch> | |
| </IfModule> | |
| #Cache control – static files | |
| <IfModule mod_headers.c> | |
| <FilesMatch "\.(?i:gif|jpe?g|png|js|css|swf|ico|woff|svg)$"> | |
| Header set Cache-Control "max-age=31536000, public" | |
| </FilesMatch> | |
| </IfModule> | |
| #Gzip | |
| <IfModule mod_deflate.c> | |
| AddOutputFilterByType DEFLATE text/css application/x-javascript text/x-component text/html text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon application/javascript | |
| </IfModule> | |
| #WP – block xmlrpc.php | |
| <FilesMatch "^(xmlrpc\.php)"> | |
| order deny,allow | |
| deny from all | |
| #JetPack + other Automattic networks | |
| allow from 76.74.254.0/25 | |
| allow from 216.151.209.64/26 | |
| allow from 66.135.48.128/25 | |
| allow from 69.174.248.128/25 | |
| allow from 76.74.255.0/25 | |
| allow from 216.151.210.0/25 | |
| allow from 76.74.248.128/25 | |
| allow from 207.198.112.0/23 | |
| allow from 207.198.101.0/25 | |
| allow from 198.181.116.0/24 | |
| allow from 192.0.64.0/18 | |
| allow from 66.155.38.0/24 | |
| allow from 209.15.21.0/24 | |
| allow from 64.34.206.0/24 | |
| </FilesMatch> | |
| #WP – allow wp-login.php only from specified IP | |
| <Files wp-login.php> | |
| order deny,allow | |
| allow from x.x.x.x | |
| deny from all | |
| </Files> | |
| #WP – block whole wp-admin – .htaccess in this folder | |
| order deny,allow | |
| allow from x.x.x.x | |
| deny from all | |
| <Files admin-ajax.php> | |
| order allow,deny | |
| allow from all | |
| satisfy any | |
| </Files> | |
| <Files admin-post.php> | |
| order allow,deny | |
| allow from all | |
| satisfy any | |
| </Files> | |
| #WP – block PHP in uploads 1st method – .htaccess in /wp-content/uploads/ | |
| <FilesMatch "\.php$"> | |
| order allow,deny | |
| deny from all | |
| </FilesMatch> | |
| #Paste rewrite rules after the "RewriteEngine on" directive | |
| #WP – block PHP in uploads 2nd method – global .htaccess | |
| RewriteRule ^(.*)/uploads/(.*)\.php$ – [F] | |
| #WP – block username harvesting | |
| RewriteCond %{QUERY_STRING} author= | |
| RewriteRule ^(.*)$ – [R=403,NC,L] | |
| #WP – block direct POSTs | |
| RewriteCond %{REQUEST_METHOD} POST | |
| RewriteCond %{HTTP_REFERER} ^$ | |
| RewriteRule ^ – [F,L] | |
| #Redirect from HTTP to HTTPS and from non-www to www | |
| #non-www to www (+https) | |
| RewriteCond %{HTTP_HOST} !^www\. [NC] | |
| RewriteRule ^(.*)$ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,QSA,NE,R=301] | |
| #http to https | |
| RewriteCond %{HTTPS} !on | |
| RewriteCond %{HTTP:X-Forwarded-Proto} !=https | |
| RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,QSA,NE,R=301] | |
| #CSP header – prevent mixed content | |
| <IfModule mod_headers.c> | |
| Header set Content-Security-Policy "upgrade-insecure-requests;" | |
| </IfModule> | |
| #Deal with fbclid argument | |
| RewriteCond %{QUERY_STRING} ^(.*?)(&?fbclid=[a-zA-Z0-9_-]+)$ | |
| RewriteRule ^(.*)$ /$1?%1 [L,NE,R=301] | |
| ##GEO IP | |
| #allow country with mod_geoip 1st option | |
| <IfModule mod_geoip.c> | |
| GeoIPEnable On | |
| RewriteCond %{ENV:GEOIP_COUNTRY_CODE} !^(CZ|SK)$ | |
| RewriteRule ^(.*)$ – [F,L] | |
| </IfModule> | |
| #block country with mod_geoip 1st option | |
| <IfModule mod_geoip.c> | |
| GeoIPEnable On | |
| RewriteCond %{ENV:GEOIP_COUNTRY_CODE} ^(RU|CN)$ | |
| RewriteRule ^(.*)$ – [F,L] | |
| </IfModule> | |
| #allow country with mod_geoip 2nd option | |
| <IfModule mod_geoip.c> | |
| GeoIPEnable On | |
| SetEnvIf GEOIP_COUNTRY_CODE CZ AllowCountry | |
| SetEnvIf GEOIP_COUNTRY_CODE SK AllowCountry | |
| deny from all | |
| allow from env=AllowCountry | |
| </IfModule> | |
| #block country with mod_geoip 2nd option | |
| <IfModule mod_geoip.c> | |
| GeoIPEnable On | |
| SetEnvIf GEOIP_COUNTRY_CODE RU BlockCountry | |
| SetEnvIf GEOIP_COUNTRY_CODE CN BlockCountry | |
| deny from env=BlockCountry | |
| </IfModule> | |
| ##example – allow wp-admin only from CZ/SK – .htaccess in /wp-admin folder | |
| #GeoIPEnable On | |
| #SetEnvIf GEOIP_COUNTRY_CODE CZ AllowCountry | |
| #SetEnvIf GEOIP_COUNTRY_CODE SK AllowCountry | |
| #order deny,allow | |
| #allow from env=AllowCountry | |
| #deny from all | |
| #<Files admin-ajax.php> | |
| # order allow,deny | |
| # allow from all | |
| # satisfy any | |
| #</Files> | |
| #<Files admin-post.php> | |
| # order allow,deny | |
| # allow from all | |
| # satisfy any | |
| #</Files> | |
| # 301 redirect | |
| Redirect 301 /old-url /new-url | |
| #multirule https + www redirect – example.com variant | |
| RewriteCond %{HTTPS} !on | |
| RewriteCond %{HTTP:X-Forwarded-Proto} !=https | |
| RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*)$ [NC] | |
| RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [L,QSA,NE,R=301] | |
| RewriteCond %{HTTP_HOST} ^(?:www\.)(.*)$ [NC] | |
| RewriteRule ^(.*)$ https://%1%{REQUEST_URI} [L,QSA,NE,R=301] | |
| #multirule https + www redirect – http://www.example.com variant | |
| RewriteCond %{HTTPS} !on | |
| RewriteCond %{HTTP:X-Forwarded-Proto} !=https | |
| RewriteCond %{HTTP_HOST} ^(?:www\.)?(.*)$ [NC] | |
| RewriteRule ^(.*)$ https://www.%1%{REQUEST_URI} [L,QSA,NE,R=301] | |
| RewriteCond %{HTTP_HOST} ^(?!www\.)(.*)$ [NC] | |
| RewriteRule ^(.*)$ https://www.%1%{REQUEST_URI} [L,QSA,NE,R=301] |






Leave a Reply