Skip to content

Instantly share code, notes, and snippets.

@seoagentur-hamburg
Last active January 30, 2023 10:58
Show Gist options
  • Star 49 You must be signed in to star a gist
  • Fork 17 You must be signed in to fork a gist
  • Save seoagentur-hamburg/ad6cb1f190279f9eca7d to your computer and use it in GitHub Desktop.
Save seoagentur-hamburg/ad6cb1f190279f9eca7d to your computer and use it in GitHub Desktop.
Die optimale .htaccess-Datei für mehr Speed und Sicherheit
# ----------------------------------------------------------------------
# | Komprimierung und Caching |
# ----------------------------------------------------------------------
# Serve resources with far-future expires headers.
#
# (!) If you don't control versioning with filename-based
# cache busting, you should consider lowering the cache times
# to something like one week.
#
# https://httpd.apache.org/docs/current/mod/mod_expires.html
<IfModule mod_expires.c>
ExpiresActive on
ExpiresDefault "access plus 1 month"
# CSS
ExpiresByType text/css "access plus 1 year"
# Data interchange
ExpiresByType application/atom+xml "access plus 1 hour"
ExpiresByType application/rdf+xml "access plus 1 hour"
ExpiresByType application/rss+xml "access plus 1 hour"
ExpiresByType application/json "access plus 0 seconds"
ExpiresByType application/ld+json "access plus 0 seconds"
ExpiresByType application/schema+json "access plus 0 seconds"
ExpiresByType application/vnd.geo+json "access plus 0 seconds"
ExpiresByType application/xml "access plus 0 seconds"
ExpiresByType text/xml "access plus 0 seconds"
# Favicon (cannot be renamed!) and cursor images
ExpiresByType image/vnd.microsoft.icon "access plus 1 week"
ExpiresByType image/x-icon "access plus 1 week"
# HTML - Behält die Website eine Stunde im Cache, neues wird erst nach Ablauf einer Stunde
# angezeigt. Wenn nicht gewuenscht, bei 3600 eine Null eintragen
ExpiresByType text/html "access plus 3600 seconds"
# JavaScript
ExpiresByType application/javascript "access plus 1 year"
ExpiresByType application/x-javascript "access plus 1 year"
ExpiresByType text/javascript "access plus 1 year"
# Manifest files
ExpiresByType application/manifest+json "access plus 1 week"
ExpiresByType application/x-web-app-manifest+json "access plus 0 seconds"
ExpiresByType text/cache-manifest "access plus 0 seconds"
# Media files
ExpiresByType audio/ogg "access plus 1 month"
ExpiresByType image/bmp "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"
ExpiresByType image/webp "access plus 1 month"
ExpiresByType video/mp4 "access plus 1 month"
ExpiresByType video/ogg "access plus 1 month"
ExpiresByType video/webm "access plus 1 month"
# Web fonts
# Embedded OpenType (EOT)
ExpiresByType application/vnd.ms-fontobject "access plus 1 month"
ExpiresByType font/eot "access plus 1 month"
# OpenType
ExpiresByType font/opentype "access plus 1 month"
# TrueType
ExpiresByType application/x-font-ttf "access plus 1 month"
# Web Open Font Format (WOFF) 1.0
ExpiresByType application/font-woff "access plus 1 month"
ExpiresByType application/x-font-woff "access plus 1 month"
ExpiresByType font/woff "access plus 1 month"
# Web Open Font Format (WOFF) 2.0
ExpiresByType application/font-woff2 "access plus 1 month"
# Other
ExpiresByType text/x-cross-domain-policy "access plus 1 week"
</IfModule>
<IfModule mod_deflate.c>
# Insert filters / compress text, html, javascript, css, xml:
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/vtt
AddOutputFilterByType DEFLATE text/x-component
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/js
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/x-javascript
AddOutputFilterByType DEFLATE application/x-httpd-php
AddOutputFilterByType DEFLATE application/x-httpd-fastphp
AddOutputFilterByType DEFLATE application/atom+xml
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/ld+json
AddOutputFilterByType DEFLATE application/vnd.ms-fontobject
AddOutputFilterByType DEFLATE application/x-font-ttf
AddOutputFilterByType DEFLATE application/x-web-app-manifest+json
AddOutputFilterByType DEFLATE font/opentype
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE image/x-icon
# Exception: Images
SetEnvIfNoCase REQUEST_URI \.(?:gif|jpg|jpeg|png|svg)$ no-gzip dont-vary
# Drop problematic browsers
BrowserMatch ^Mozilla/4 gzip-only-text/html
BrowserMatch ^Mozilla/4\.0[678] no-gzip
BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
# Make sure proxies don't deliver the wrong content
Header append Vary User-Agent env=!dont-vary
</IfModule>
#Alternative caching using Apache's "mod_headers", if it's installed.
#Caching of common files - ENABLED
<IfModule mod_headers.c>
<FilesMatch "\.(ico|pdf|flv|swf|js|css|gif|png|jpg|jpeg|txt)$">
Header set Cache-Control "max-age=2592000, public"
</FilesMatch>
</IfModule>
<IfModule mod_headers.c>
<FilesMatch "\.(js|css|xml|gz)$">
Header append Vary Accept-Encoding
</FilesMatch>
</IfModule>
# Set Keep Alive Header
<IfModule mod_headers.c>
Header set Connection keep-alive
</IfModule>
# If your server don't support ETags deactivate with "None" (and remove header)
<IfModule mod_expires.c>
<IfModule mod_headers.c>
Header unset ETag
</IfModule>
FileETag None
</IfModule>
# ----------------------------------------------------------------------
# | 6g Firewall für Sicherheit - HIER NICHTS AENDERN, ANSONSTEN IST DIE WEBSITE ANGREIFBAR
# ----------------------------------------------------------------------
# 6G FIREWALL/BLACKLIST
# @ https://perishablepress.com/6g/
# 6G:[QUERY STRINGS]
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} (eval\() [NC,OR]
RewriteCond %{QUERY_STRING} (127\.0\.0\.1) [NC,OR]
RewriteCond %{QUERY_STRING} ([a-z0-9]{2000}) [NC,OR]
RewriteCond %{QUERY_STRING} (javascript:)(.*)(;) [NC,OR]
RewriteCond %{QUERY_STRING} (base64_encode)(.*)(\() [NC,OR]
RewriteCond %{QUERY_STRING} (GLOBALS|REQUEST)(=|\[|%) [NC,OR]
RewriteCond %{QUERY_STRING} (<|%3C)(.*)script(.*)(>|%3) [NC,OR]
RewriteCond %{QUERY_STRING} (\\|\.\.\.|\.\./|~|`|<|>|\|) [NC,OR]
RewriteCond %{QUERY_STRING} (boot\.ini|etc/passwd|self/environ) [NC,OR]
RewriteCond %{QUERY_STRING} (thumbs?(_editor|open)?|tim(thumb)?)\.php [NC,OR]
RewriteCond %{QUERY_STRING} (\'|\")(.*)(drop|insert|md5|select|union) [NC]
RewriteRule .* - [F]
</IfModule>
# 6G:[REQUEST METHOD]
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_METHOD} ^(connect|debug|delete|move|put|trace|track) [NC]
RewriteRule .* - [F]
</IfModule>
# 6G:[REFERRERS]
<IfModule mod_rewrite.c>
RewriteCond %{HTTP_REFERER} ([a-z0-9]{2000}) [NC,OR]
RewriteCond %{HTTP_REFERER} (semalt.com|todaperfeita) [NC]
RewriteRule .* - [F]
</IfModule>
# 6G:[REQUEST STRINGS]
<IfModule mod_alias.c>
RedirectMatch 403 (?i)([a-z0-9]{2000})
RedirectMatch 403 (?i)(https?|ftp|php):/
RedirectMatch 403 (?i)(base64_encode)(.*)(\()
RedirectMatch 403 (?i)(=\\\'|=\\%27|/\\\'/?)\.
RedirectMatch 403 (?i)/(\$(\&)?|\*|\"|\.|,|&|&amp;?)/?$
RedirectMatch 403 (?i)(\{0\}|\(/\(|\.\.\.|\+\+\+|\\\"\\\")
RedirectMatch 403 (?i)(~|`|<|>|:|;|,|%|\\|\s|\{|\}|\[|\]|\|)
RedirectMatch 403 (?i)/(=|\$&|_mm|cgi-|etc/passwd|muieblack)
RedirectMatch 403 (?i)(&pws=0|_vti_|\(null\)|\{\$itemURL\}|echo(.*)kae|etc/passwd|eval\(|self/environ)
RedirectMatch 403 (?i)\.(aspx?|bash|bak?|cfg|cgi|dll|exe|git|hg|ini|jsp|log|mdb|out|sql|svn|swp|tar|rar|rdf)$
RedirectMatch 403 (?i)/(^$|(wp-)?config|mobiquo|phpinfo|shell|sqlpatch|thumb|thumb_editor|thumbopen|timthumb|webshell)\.php
</IfModule>
# 6G:[USER AGENTS]
<IfModule mod_setenvif.c>
SetEnvIfNoCase User-Agent ([a-z0-9]{2000}) bad_bot
SetEnvIfNoCase User-Agent (archive.org|binlar|casper|checkpriv|choppy|clshttp|cmsworld|diavol|dotbot|extract|feedfinder|flicky|g00g1e|harvest|heritrix|httrack|kmccrew|loader|miner|nikto|nutch|planetwork|postrank|purebot|pycurl|python|seekerspider|siclab|skygrid|sqlmap|sucker|turnit|vikspider|winhttp|xxxyy|youda|zmeu|zune) bad_bot
<limit GET POST PUT>
Order Allow,Deny
Allow from All
Deny from env=bad_bot
</limit>
</IfModule>
# 6G:[BAD IPS]
<Limit GET HEAD OPTIONS POST PUT>
Order Allow,Deny
Allow from All
# uncomment/edit/repeat next line to block IPs
# Deny from 123.456.789
</Limit>
# ----------------------------------------------------------------------
# | Zeichensatz setzen
# ----------------------------------------------------------------------
AddDefaultCharset UTF-8
# ----------------------------------------------------------------------
# Wichtige WordPress-Dateien gegen den Zugriff von außen blocken
# ----------------------------------------------------------------------
# Kein Zugriff auf die install.php
<files install.php>
Order allow,deny
Deny from all
</files>
# Kein Zugriff auf die wp-config.php
<files wp-config.php>
Order allow,deny
Deny from all
</files>
# Kein Zugriff auf die readme.html
<files readme.html>
Order Allow,Deny
Deny from all
Satisfy all
</Files>
# Kein Zugriff auf die liesmich.html für die DE Edition
<Files liesmich.html>
Order Allow,Deny
Deny from all
Satisfy all
</Files>
# Kein Zugriff auf das Error-Log
<files error_log>
Order allow,deny
Deny from all
</files>
#Zugriff auf .htaccess und .htpasswd verbieten. Wenn keine .htpasswd benutzt wird, kann der Code dafür entfernt werden.
<FilesMatch "(\.htaccess|\.htpasswd)">
Order deny,allow
Deny from all
</FilesMatch>
# Den Zugriff auf den Include-Ordner verbieten
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^wp-admin/includes/ - [F,L]
RewriteRule !^wp-includes/ - [S=3]
RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>
# ----------------------------------------------------------------------
# Schutz des Administrator-Bereichs. Wenn der .htaccess/.htpasswd Schutz
# genutzt werden soll, auskommentieren UND PFAD ANPASSEN
# ----------------------------------------------------------------------
#<Files wp-login.php>
#AuthName "Admin-Bereich"
#AuthType Basic
#AuthUserFile dein/pfad/zur/.htpasswd
#require valid-user
#</Files>
#Full Path Disclosure abschalten - unterdrueckt die Anzeige des vollstaendigen Fehlerpfads
php_flag display_errors Off
# ----------------------------------------------------------------------
# Hotlinking verbieten (verhindert, dass andere Deine Bilder von Deinem Server nutzen
# WICHTIG: Auskommentieren und deine Domain einfuegen
# ----------------------------------------------------------------------
#<IfModule mod_rewrite.c>
#RewriteEngine on
#RewriteCond %{HTTP_REFERER} !^$
#RewriteCond %{HTTP_REFERER} !^https://(www\.)?democraticpost\.de(/.*)?$ [NC]
#RewriteRule \.(jpg|jpeg|gif||png)$ - [F]
#</ifModule>
# ----------------------------------------------------------------------
# Das Sicherheitsrisiko XML-RPC Schnittstelle komplett abschalten
# ----------------------------------------------------------------------
<Files xmlrpc.php>
Order Deny,Allow
Deny from all
</Files>
# ----------------------------------------------------------------------
# | WordPress Rewrite Rules - HIER NICHTS AENDERN, ODER WORDPRESS FUNKTIONIERT NICHT MEHR
# ----------------------------------------------------------------------
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
@tim99-1977
Copy link

not sure if these missing:
ExpiresByType image/jpg
ExpiresByType application/pdf
ExpiresByType application/x-shockwave-flash
?

And this line removes all pictures from page:
RewriteCond %{QUERY_STRING} (|...|../|~|`|<|>||) [NC,OR]

@seoagentur-hamburg
Copy link
Author

Hi,

this .htaccess ist tested on several WordPress-Websites. The file is running without any errors on tons of wordpress sites. If you get an error, it is not the fault of the file.

@ratoli
Copy link

ratoli commented Sep 5, 2016

Hi,
what do you think about to disable the ETag header?
Take a look at http://www.smart-webentwicklung.de/2012/10/website-beschleunigen-3-browser-caching/

@dennishpunkt
Copy link

Hi,

thanks for the great work! Just one litte thing: What's the reason to disable gzip for .svg in Line 113? svg as an xml-based format is highly compressible.

@AloeVera-Sandra
Copy link

Hello, how do I get my 2 subdomains integrated in line 13?
Main domain: https://luxemburg.com
Subdomains: https://de.mondorf.com
Subdomains: https://fr.mondorf.com
Thank you, for the great effort.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment