Skip to content

Instantly share code, notes, and snippets.

@rawsta
Created May 1, 2022 06:08
Show Gist options
  • Save rawsta/6759f45dcfdfb62feef69d6bbe5baa96 to your computer and use it in GitHub Desktop.
Save rawsta/6759f45dcfdfb62feef69d6bbe5baa96 to your computer and use it in GitHub Desktop.
Useful htaccess directives
# htaccess snippets for apache
# Don't copy&paste the whole file! - it will break your site
# Pick what you need and be careful
# HTTP authentification
AuthUserFile /path/to/.htpasswd
AuthType Basic
AuthName "Restricted Area"
Require valid-user
# htpasswd generator: https://wtools.io/generate-htpasswd-online
# cli: htpasswd -nbm user pass (cleartext output!)
# 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|ico|woff|woff2|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>
# Allow CORS for external fonts (like Google Fonts)
<IfModule mod_headers.c>
<FilesMatch "\.(eot|otf|tt[cf]|woff2?)$">
Header set Access-Control-Allow-Origin "*"
</FilesMatch>
</IfModule>
# x-powered-by is useless and can expose vulnerabilities
<IfModule mod_headers.c>
Header unset X-Powered-By
Header always unset X-Powered-By
</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>
# Paste rewrite rules after the "RewriteEngine on" directive
# 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>
# handle fbclid argument
RewriteCond %{QUERY_STRING} ^(.*?)(&?fbclid=[a-zA-Z0-9_-]+)$
RewriteRule ^(.*)$ /$1?%1 [L,NE,R=301]
# 301 redirect
Redirect 301 /old-url /new-url
# Multirule -> https + www redirect -> https://example.com
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 -> https://www.example.com
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]
# WordPress specific
# WordPress - 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>
# WordPress - 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>
# WordPress - 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>
# WordPress - block PHP in uploads ( place .htaccess in /wp-content/uploads/ )
<FilesMatch "\.php$">
order allow,deny
deny from all
</FilesMatch>
# Paste rewrite rules after the "RewriteEngine on" directive
# WordPress - block PHP in uploads - in global .htaccess
RewriteRule ^(.*)/uploads/(.*)\.php$ - [F]
# WordPress - block username harvesting
RewriteCond %{QUERY_STRING} author=
RewriteRule ^(.*)$ - [R=403,NC,L]
# WordPress - block direct POSTs
RewriteCond %{REQUEST_METHOD} POST
RewriteCond %{HTTP_REFERER} ^$
RewriteRule ^ - [F,L]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment