WordPress Ständig aktualisiert für beste Ergebnisse

Die perfekte .htaccess für WordPress – PageSpeed und Sicherheit [03/2019]

Die perfekte .htaccess für WordPress - PageSpeed und Sicherheit

Die perfekte .htaccess für dein WordPress sorgt für einen enormen Performanceschub und ein hohes Sicherheitslevel. Setze meine über sieben Jahre perfektionierte .htaccess Datei für dein WordPress-Tuning ein und freue dich über beste Ergebnisse!

Mehr als sechs Jahre Erfahrung sind in meine perfekte .htaccess Datei eingeflossen und sie wurde von Jahr zu Jahr stets verbessert und überarbeitet. 2018 sind die Bereiche Hotlink Protection und der HTTP Schutz für den Adminbereich dazugekommen.

In 02 / 2019 habe ich die 6G-Firewall auf die neue Version 7G aktualisiert. Zusätzlich kamen in 2019 noch die Bereiche „Blocking the »ReallyLongRequest« Bandit“ und der neue experimentelle Header EXPECT-CT dazu.

Letztes Update: 27.02.2019

  • Dazugekommen: Ultimate Hotlink Protection in 2018
  • Dazugekommen: Adminbereich mit HTTP Schutz versehen in 2018
  • Aktualisiert 02 / 2019: 6G Firewall auf 7G Firewall
  • Aktualisiert: Strict Transport Security Header mit korrektem »max-age« Eintrag – Update 25.07.2018
  • Dazugekommen: Referrer-Policy Header am 05.06.2018
  • Dazugekommen: Block Nuisance Requests – am 18.09.2018
  • Dazugekommen in 2019: Der Schutz gegen den »ReallyLongRequest« Bot
  • Dazugekommen in 2019: Der experimentelle Security Header EXPECT-CT

Du magst dich vielleicht wundern, dass die Datei nicht gerade ein Leichtgewicht ist. Doch das Laden dieser Datei dauert nur einen Wimpernschlag. Der Effekt auf deine Website hingegen ist enorm. Ohne weitere Optimierungen wird dein WordPress schon deutlich schneller werden, weil alle wichtigen Bereiche komprimiert und gecacht werden.

Alle optionalen Elemente sind mit Rauten (#) auskommentiert, zur Nutzung diese bitte entfernen.

Die perfekte .htaccess Datei teilt sich in 13 einzelne Bereiche auf:

  • HTTP zu HTTPS Umleitung
  • CORS aktivieren für bestimmte Dateitypen
  • Block Nuisance Requests (Lästige Anfragen blocken) – neu 18.09.2018
  • Dateien komprimieren und cachen
  • Die 7G-Firewall von Jeff Starr gegen die Einschleusung von Schadcode – aktualisiert 02 / 2019
  • Das Blocken von WordPress-Dateien gegen Zugriff von außen
  • Hotlink Protection gegen das Verlinken Deiner Bilder auf anderen Websites – 2018
  • Blocking the »ReallyLongRequest« Bandit – Neu in 2019
  • Das Schützen des Adminbereichs mittels HTTP – 2018
  • Das Blocken des Sicherheitsrisikos XML-RPC
  • Der Referrer Header – 05.06.2018
  • Die HTTP-Security-Header – aktualisiert 25.01.2019
  • Die WordPress Standard-Regeln
Bitte beachten: Wenn Du diese Datei oder Auszüge daraus verwenden möchtest, dann nutze bitte das Gist am Ende des Artikels. Beim Kopieren des Codes aus meinem Code-Highlighter-Plugin schleichen sich ab und an Fehler ein.
Direkt zum kompletten Gist springen »

Die perfekte .htaccess, die einzelnen Bereiche

1 – Garantierte HTTP zu HTTPS Umleitung

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTPS} !=on
  RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</IfModule>

Dieser Code sorgt im Gegensatz zu anderen Schnipseln für eine garantierte Weiterleitung aller HTTP-Anfragen auf die HTTPS-Version. In der .htaccess ist dieser Bereich auskommentiert, wenn du den Code nutzen möchtest, entferne die Rauten vor den einzelnen Elementen. Falls es zu Problemen mit diesem Code kommt, existiert bereits irgendwo in Deiner Installation eine Umleitung von HTTP auf HTTPS.

Mehr zum Thema: Garantierte Weiterleitung von HTTP zu HTTPS

2 – CORS aktivieren für bestimmte Dateitypen

Was genau ist CORS?

Cross-Origin Resource Sharing (CORS) ist ein Mechanismus, der Webbrowsern oder auch anderen Webclients Cross-Origin-Requests ermöglicht. … CORS ist ein Kompromiss zugunsten größerer Flexibilität im Internet unter Berücksichtigung möglichst hoher Sicherheitsmaßnahmen.

CORS ist ein wichtiger Beitrag zu einer Sicherheitsstrategie in Verbindung mit einer Content Security Policy. Solltest Du diese Strategie einsetzen, dann ist dieser Teil bereits in meiner Datei enthalten.

<IfModule mod_headers.c>
    <FilesMatch "\.(ttf|ttc|otf|eot|woff|woff2|font.css|css|js|gif|png|jpe?g|svg|svgz|ico|webp)$">
        Header set Access-Control-Allow-Origin "*"
    </FilesMatch>
</IfModule>

Nähere Informationen zur HTTP-Sicherheit:

Dr.Web: HTTP Security-Header: So machst du deine Website sicher

Die perfekte .htaccess für WordPress - PageSpeed und Sicherheit

Eine Website umfasst vieles. Eine perfekte .htaccess gehört dazu.

3 – Block Nuisance Requests (lästige Anfragen blocken)

Manche Bots suchen sehr emsig nichtexistente Dateien auf Deinem Server / Webhosting und blockieren auf diese Weise die Ressourcen des Hostings. Der böswillige Datenverkehr spamt zudem die Fehlerprotokolle des Servers zu, sodass eigentliche Probleme durch diese Anfragen an nichtexistente Dateien kaum mehr gefunden werden.

Auf günstigen Shared-Hostings können diese Anfragen durchaus Deine Website in die Knie zwingen und sehr langsam machen. Daher: gleich blockieren.

Achtung: Kommentiere diesen Code-Block nur aus, wenn Du kein Let’s Encrypt HTTPS-Zertifikat für Deine Website nutzt. Let’s Encrypt benötig Zugriff zu .well-known.

In der vollständigen .htaccess Datei weiter unten ist dieser Block daher mit Rauten (#) auskommentiert.

# ----------------------------------------------------------------------
# | BLOCK NUISANCE REQUESTS - New in 2018  
#   https://perishablepress.com/block-nuisance-requests
# ----------------------------------------------------------------------

# Comment it out, if you don't use Let's Encrypt, because Let's Encrypt ist using .well-known
# Wenn Du Let's Encrypt nutzt, kannst Du das nicht verwenden, weil Let's Encrypt .well-known nutzt.
<IfModule mod_alias.c>
	RedirectMatch 403 (?i)\.php\.suspected
	RedirectMatch 403 (?i)\.(git|well-known)
	RedirectMatch 403 (?i)apple-app-site-association
	RedirectMatch 403 (?i)/autodiscover/autodiscover.xml
</IfModule>

4 – Dateien komprimieren und cachen

Dieser Bereich ist der umfassendste. Doch jede einzelne Zeile Code ist für die Performance deiner Website wichtig. Jede Dateiart wird komprimiert an den Browser ausgeliefert und in diesem optimal in den Cache aufgenommen. Auch wenn du Plugins wie zum Beispiel Autoptimize und Cache Enabler einsetzt, muss dieser Abschnitt sein, denn er ergänzt diese Plugins für noch mehr Speed.

<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/font-woff2
AddOutputFilterByType DEFLATE application/x-font-woff
AddOutputFilterByType DEFLATE application/x-web-app-manifest+json font/woff
AddOutputFilterByType DEFLATE font/woff 
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>

<IfModule mod_headers.c>
<FilesMatch ".(js|css|xml|gz|html|woff|woff2|ttf)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>

5 – 7G-Firewall gegen die Einschleusung von Schadcode

Dieser Abschnitt sorgt für echte Sicherheit. Immer wieder weisen Plugins und Themes eklatante Sicherheitslücken auf, durch die man Schadcode in eine Website einschleusen könnte. Diese Firewall schiebt dem einen Riegel vor und blockt die gängigen Methoden der Einschleusung.

# ----------------------------------------------------------------------
# | 7G Firewall for Security - Do not change this part @Update 2019 / 2
# ----------------------------------------------------------------------
# 7G FIREWALL v1.0 20190124
# @ https://perishablepress.com/7g-firewall/

# 7G:[CORE]
ServerSignature Off
Options -Indexes
RewriteEngine On
RewriteBase /

# 7G:[QUERY STRING]
<IfModule mod_rewrite.c>	
	RewriteCond %{REQUEST_URI} !(7g_log.php) [NC]	
	RewriteCond %{QUERY_STRING} ([a-z0-9]{2000,}) [NC,OR]
	RewriteCond %{QUERY_STRING} (/|%2f)(:|%3a)(/|%2f) [NC,OR]
	RewriteCond %{QUERY_STRING} (/|%2f)(\*|%2a)(\*|%2a)(/|%2f) [NC,OR]
	RewriteCond %{QUERY_STRING} (~|`|<|>|\^|\|\\|0x00|%00|%0d%0a) [NC,OR]
	RewriteCond %{QUERY_STRING} (cmd|command)(=|%3d)(chdir|mkdir)(.*)(x20) [NC,OR]
	RewriteCond %{QUERY_STRING} (fck|ckfinder|fullclick|ckfinder|fckeditor) [NC,OR]
	RewriteCond %{QUERY_STRING} (thumbs?(_editor|open)?|tim(thumbs?)?)((\.|%2e)php) [NC,OR]
	RewriteCond %{QUERY_STRING} (absolute_|base|root_)(dir|path)(=|%3d)(ftp|https?) [NC,OR]
	RewriteCond %{QUERY_STRING} (localhost|loopback|127(\.|%2e)0(\.|%2e)0(\.|%2e)1) [NC,OR]
	RewriteCond %{QUERY_STRING} (\.|20)(get|the)(_|%5f)(permalink|posts_page_url)(\(|%28) [NC,OR]
	RewriteCond %{QUERY_STRING} (s)?(ftp|http|inurl|php)(s)?(:(/|%2f|%u2215)(/|%2f|%u2215)) [NC,OR]
	RewriteCond %{QUERY_STRING} (/|%2f)((wp-)?(config)(uration)?)((\.|%2e)inc)?((\.|%2e)php) [NC,OR]
	RewriteCond %{QUERY_STRING} (globals|mosconfig([a-z_]{1,22})|request)(=|[|%[a-z0-9]{0,2}) [NC,OR]
	RewriteCond %{QUERY_STRING} ((boot|win)((\.|%2e)ini)|etc(/|%2f)passwd|self(/|%2f)environ) [NC,OR]
	RewriteCond %{QUERY_STRING} (((/|%2f){3,3})|((\.|%2e){3,3})|((\.|%2e){2,2})(/|%2f|%u2215)) [NC,OR]
	RewriteCond %{QUERY_STRING} (benchmark|char|exec|fopen|function|html)(.*)(\(|%28)(.*)(\)|%29) [NC,OR]
	RewriteCond %{QUERY_STRING} (php)([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}) [NC,OR]
	RewriteCond %{QUERY_STRING} (e|%65|%45)(v|%76|%56)(a|%61|%31)(l|%6c|%4c)(.*)(\(|%28)(.*)(\)|%29) [NC,OR]
	RewriteCond %{QUERY_STRING} (/|%2f)(=|%3d|$&|_mm|cgi(\.|-)|inurl(:|%3a)(/|%2f)|(mod|path)(=|%3d)(\.|%2e)) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|%3c)(.*)(e|%65|%45)(m|%6d|%4d)(b|%62|%42)(e|%65|%45)(d|%64|%44)(.*)(>|%3e) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|%3c)(.*)(i|%69|%49)(f|%66|%46)(r|%72|%52)(a|%61|%41)(m|%6d|%4d)(e|%65|%45)(.*)(>|%3e) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|%3c)(.*)(o|%4f|%6f)(b|%62|%42)(j|%4a|%6a)(e|%65|%45)(c|%63|%43)(t|%74|%54)(.*)(>|%3e) [NC,OR]
	RewriteCond %{QUERY_STRING} (<|%3c)(.*)(s|%73|%53)(c|%63|%43)(r|%72|%52)(i|%69|%49)(p|%70|%50)(t|%74|%54)(.*)(>|%3e) [NC,OR]
	RewriteCond %{QUERY_STRING} (\+|%2b|%20)(d|%64|%44)(e|%65|%45)(l|%6c|%4c)(e|%65|%45)(t|%74|%54)(e|%65|%45)(\+|%2b|%20) [NC,OR]
	RewriteCond %{QUERY_STRING} (\+|%2b|%20)(i|%69|%49)(n|%6e|%4e)(s|%73|%53)(e|%65|%45)(r|%72|%52)(t|%74|%54)(\+|%2b|%20) [NC,OR]
	RewriteCond %{QUERY_STRING} (\+|%2b|%20)(s|%73|%53)(e|%65|%45)(l|%6c|%4c)(e|%65|%45)(c|%63|%43)(t|%74|%54)(\+|%2b|%20) [NC,OR]
	RewriteCond %{QUERY_STRING} (\+|%2b|%20)(u|%75|%55)(p|%70|%50)(d|%64|%44)(a|%61|%41)(t|%74|%54)(e|%65|%45)(\+|%2b|%20) [NC,OR]
	RewriteCond %{QUERY_STRING} (\\x00|(\"|%22|\'|%27)?0(\"|%22|\'|%27)?(=|%3d)(\"|%22|\'|%27)?0|cast(\(|%28)0x|or%201(=|%3d)1) [NC,OR]
	RewriteCond %{QUERY_STRING} (g|%67|%47)(l|%6c|%4c)(o|%6f|%4f)(b|%62|%42)(a|%61|%41)(l|%6c|%4c)(s|%73|%53)(=|[|%[0-9A-Z]{0,2}) [NC,OR]
	RewriteCond %{QUERY_STRING} (_|%5f)(r|%72|%52)(e|%65|%45)(q|%71|%51)(u|%75|%55)(e|%65|%45)(s|%73|%53)(t|%74|%54)(=|[|%[0-9A-Z]{0,2}) [NC,OR]
	RewriteCond %{QUERY_STRING} (j|%6a|%4a)(a|%61|%41)(v|%76|%56)(a|%61|%31)(s|%73|%53)(c|%63|%43)(r|%72|%52)(i|%69|%49)(p|%70|%50)(t|%74|%54)(:|%3a)(.*)(;|%3b) [NC,OR]
	RewriteCond %{QUERY_STRING} (b|%62|%42)(a|%61|%41)(s|%73|%53)(e|%65|%45)(6|%36)(4|%34)(_|%5f)(e|%65|%45|d|%64|%44)(e|%65|%45|n|%6e|%4e)(c|%63|%43)(o|%6f|%4f)(d|%64|%44)(e|%65|%45)(.*)(\()(.*)(\)) [NC,OR]
	RewriteCond %{QUERY_STRING} (allow_url_(fopen|include)|auto_prepend_file|blexbot|browsersploit|(c99|php)shell|curltest|disable_functions?|document_root|elastix|encodeuricom|exec|exploit|fclose|fgets|fputs|fread|fsbuff|fsockopen|gethostbyname|grablogin|hmei7|input_file|load_file|null|open_basedir|outfile|passthru|popen|proc_open|quickbrute|remoteview|revslider|root_path|safe_mode|shell_exec|site((.){0,2})copier|sux0r|system|trojan|wget|xertive) [NC,OR]
	RewriteCond %{QUERY_STRING} (;|<|>|\'|\"|\)|%0a|%0d|%22|%27|%3c|%3e|%00)(.*)(/\*|alter|base64|benchmark|cast|char|concat|convert|create|encode|declare|delete|drop|insert|md5|order|request|script|select|set|union|update) [NC,OR]
	RewriteCond %{QUERY_STRING} ((\+|%2b)(concat|delete|get|select|union)(\+|%2b)) [NC,OR]
	RewriteCond %{QUERY_STRING} (union)(.*)(select)(.*)(\(|%28) [NC,OR]
	RewriteCond %{QUERY_STRING} (concat)(.*)(\(|%28) [NC]	
	RewriteRule . - [F,L]	
	# RewriteRule . /7g_log.php?log [L,NE,E=7G_QUERY_STRING:%1___%2___%3]	
</IfModule>

# 7G:[REQUEST URI]
<IfModule mod_rewrite.c>	
	RewriteCond %{REQUEST_URI} !(7g_log.php) [NC]	
	RewriteCond %{REQUEST_URI} ([a-z0-9]{2000,}) [NC,OR]
	RewriteCond %{REQUEST_URI} (=?\\(\'|%27)/?)(\.) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(\*|\"|\'|\.|,|&|&?)/?$ [NC,OR]
	RewriteCond %{REQUEST_URI} (\.)(php)(\()?([0-9]+)(\))?(/)?$ [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(vbulletin|boards|vbforum)(/)? [NC,OR]
	RewriteCond %{REQUEST_URI} (\^|~|`|<|>|,|%|\\|\{|\}|\[|\]|\|) [NC,OR]
	RewriteCond %{REQUEST_URI} (\{0\}|\"?0\"?=\"?0|\(/\(|\.\.\.|\+\+\+|\\\") [NC,OR]
	RewriteCond %{REQUEST_URI} (thumbs?(_editor|open)?|tim(thumbs?)?)(\.php) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(fck|ckfinder|fullclick|ckfinder|fckeditor) [NC,OR]
	RewriteCond %{REQUEST_URI} (\.|20)(get|the)(_)(permalink|posts_page_url)(\() [NC,OR]
	RewriteCond %{REQUEST_URI} (///|\?\?|/&&|/\*(.*)\*/|/:/|\\\\|0x00|%00|%0d%0a) [NC,OR]
	RewriteCond %{REQUEST_URI} (/%7e)(root|ftp|bin|nobody|named|guest|logs|sshd)(/) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(etc|var)(/)(hidden|secret|shadow|ninja|passwd|tmp)(/)?$ [NC,OR]
	RewriteCond %{REQUEST_URI} (s)?(ftp|http|inurl|php)(s)?(:(/|%2f|%u2215)(/|%2f|%u2215)) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(=|\$&?|&?(pws|rk)=0|_mm|_vti_|cgi(\.|-)?|(=|/|;|,)nt\.) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(127\.0\.0\.1|localhost|loopback|makefile|pingserver|wwwroot)(/)? [NC,OR]
	RewriteCond %{REQUEST_URI} (\.)(conf(ig)?|ds_store|htaccess|htpasswd|init?|mysql-select-db)(/)?$ [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(bin)(/)(cc|chmod|chsh|cpp|echo|id|kill|mail|nasm|perl|ping|ps|python|tclsh)(/)?$ [NC,OR]
	RewriteCond %{REQUEST_URI} (\(null\)|\{\$itemURL\}|cAsT\(0x|echo(.*)kae|etc/passwd|eval\(|self/environ|\+union\+all\+select) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(awstats|(c99|php|web)shell|document_root|error_log|listinfo|muieblack|remoteview|site((.){0,2})copier|sqlpatch|sux0r) [NC,OR]
	RewriteCond %{REQUEST_URI} (/)((php|web)?shell|conf(ig)?|crossdomain|fileditor|locus7|nstview|php(get|remoteview|writer)|r57|remview|sshphp|storm7|webadmin)(.*)(\.|\() [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(author-panel|bitrix|class|database|(db|mysql)-?admin|filemanager|htdocs|httpdocs|https?|mailman|mailto|manage|msoffice|mysql|php|_?php-?my-?admin(.*)|revslider|sql|system|tmp|undefined|usage|var|vhosts|webmaster|www)(/) [NC,OR]
	RewriteCond %{REQUEST_URI} (base64_(en|de)code|benchmark|child_terminate|e?chr|eval|exec|function|fwrite|(f|p)open|html|leak|passthru|p?fsockopen|phpinfo|posix_(kill|mkfifo|setpgid|setsid|setuid)|proc_(close|get_status|nice|open|terminate)|(shell_)?exec|system)(.*)(\()(.*)(\)) [NC,OR]
	RewriteCond %{REQUEST_URI} (\.)(7z|ab4|afm|aspx?|bash|ba?k?|bz2|cfg|cfml?|cgi|conf(ig)?|ctl|dat|db|dll|eml|et2|exe|fec|fla|gz|hg|inc|ini|inv|jsp|log|lqd|mbf|mdb|mmw|mny|old|one|out|passwd|pdb|pl|psd|pst|ptdb|pwd|py|qbb|qdf|rar|rdf|sdb|sql|sh|soa|swf|swl|swp|stx|tar|tax|tgz|tls|tmd|wow|zip|zlib)$ [NC,OR]
	RewriteCond %{REQUEST_URI} (/)(^$|00.temp00|0day|3xp|70bex?|admin_events|bkht|(php|web)?shell|configbak|curltest|db|dompdf|filenetworks|hmei7|index\.php/index\.php/index|install|jahat|kcrew|keywordspy|mobiquo|mysql|nessus|php-?info|racrew|revslider|setup|sql|ucp|webconfig|(wp-)?conf(ig)?(uration)?|xertive)(\.php) [NC]	
	RewriteRule . - [F,L]	
	# RewriteRule . /7g_log.php?log [L,NE,E=7G_REQUEST_URI:%1___%2___%3]	
</IfModule>

# 7G:[USER AGENT]
<IfModule mod_rewrite.c>	
	RewriteCond %{REQUEST_URI} !(7g_log.php) [NC]	
	RewriteCond %{HTTP_USER_AGENT} ([a-z0-9]{2000,}) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (<|%0a|%0d|%27|%3c|%3e|%00|0x00) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} ((c99|php|web)shell|remoteview|site((.){0,2})copier) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (base64_decode|bin/bash|disconnect|eval|lwp-download|unserialize|\\\x22) [NC,OR]
	RewriteCond %{HTTP_USER_AGENT} (360Spider|acapbot|acoonbot|ahrefs|alexibot|archive.org|asterias|attackbot|backdorbot|becomebot|binlar|blackwidow|blekkobot|blexbot|blowfish|bullseye|bunnys|butterfly|careerbot|casper|checkpriv|cheesebot|cherrypick|chinaclaw|choppy|clshttp|cmsworld|copernic|copyrightcheck|cosmos|crescent|cy_cho|datacha|demon|diavol|discobot|dittospyder|dotbot|dotnetdotcom|dumbot|emailcollector|emailsiphon|emailwolf|exabot|extract|eyenetie|feedfinder|flaming|flashget|flicky|foobot|g00g1e|getright|gigabot|go-ahead-got|gozilla|grabnet|grafula|harvest|heritrix|httrack|icarus6j|jetbot|jetcar|jikespider|kmccrew|leechftp|libweb|linkextractor|linkscan|linkwalker|loader|miner|mj12bot|majestic|mechanize|morfeus|moveoverbot|netmechanic|netspider|nicerspro|nikto|ninja|nutch|octopus|pagegrabber|planetwork|postrank|proximic|purebot|pycurl|python|queryn|queryseeker|radian6|radiation|realdownload|rogerbot|scooter|seekerspider|semalt|seznambot|siclab|sindice|sistrix|sitebot|siteexplorer|sitesnagger|skygrid|smartdownload|snoopy|sosospider|spankbot|spbot|sqlmap|stackrambler|stripper|sucker|surftbot|sux0r|suzukacz|suzuran|takeout|teleport|telesoft|true_robots|turingos|turnit|vampire|vikspider|voideye|webleacher|webreaper|webstripper|webvac|webviewer|webwhacker|winhttp|wwwoffle|woxbot|xaldon|xxxyy|yamanalab|yioopbot|youda|zeus|zmeu|zune|zyborg) [NC]	
	RewriteRule . - [F,L]	
	# RewriteRule . /7g_log.php?log [L,NE,E=7G_USER_AGENT:%1]	
</IfModule>

# 7G:[REMOTE HOST]
<IfModule mod_rewrite.c>	
	RewriteCond %{REQUEST_URI} !(7g_log.php) [NC]	
	RewriteCond %{REMOTE_HOST} (163data|amazonaws|colocrossing|crimea|g00g1e|justhost|kanagawa|loopia|masterhost|onlinehome|poneytel|sprintdatacenter|reverse.softlayer|safenet|ttnet|woodpecker|wowrack) [NC]	
	RewriteRule . - [F,L]	
	# RewriteRule . /7g_log.php?log [L,NE,E=7G_REMOTE_HOST:%1]	
</IfModule>

# 7G:[HTTP REFERRER]
<IfModule mod_rewrite.c>	
	RewriteCond %{REQUEST_URI} !(7g_log.php) [NC]	
	RewriteCond %{HTTP_REFERER} (semalt.com|todaperfeita) [NC,OR]
	RewriteCond %{HTTP_REFERER} (ambien|blue\spill|cialis|cocaine|ejaculat|erectile|erections|hoodia|huronriveracres|impotence|levitra|libido|lipitor|phentermin|pro[sz]ac|sandyauer|tramadol|troyhamby|ultram|unicauca|valium|viagra|vicodin|xanax|ypxaieo) [NC]
	RewriteRule . - [F,L]	
	# RewriteRule . /7g_log.php?log [L,NE,E=7G_HTTP_REFERRER:%1]	
</IfModule>

# 7G:[REQUEST METHOD]
<IfModule mod_rewrite.c>	
	RewriteCond %{REQUEST_URI} !(7g_log.php) [NC]	
	RewriteCond %{REQUEST_METHOD} ^(connect|debug|delete|move|put|trace|track) [NC]	
	RewriteRule . - [F,L]	
	# RewriteRule . /7g_log.php?log [L,NE,E=7G_REQUEST_METHOD:%1]	
</IfModule>
In einigen Konfigurationen kann es zu Problemen mit dem TinyMCE-Editor von WordPress kommen. Sollte dies bei Dir der Fall sein, dann tausche die 7G-Firewall gegen die folgende 6G-Firewall aus. Danach funktioniert wieder alles reibungslos.

Falls Probleme im Backend auftauchen: Wechsle zur 6G-Firewall

6 – WordPress-Dateien gegen Zugriff blocken

Dieser Bereich sperrt den Zugriff von außen auf so extrem wichtige und sensible Dateien wie die wp-config.php, die install.php und den sehr gefährdeten wp-includes Ordner.

# No access to the install.php
<files install.php>
Order allow,deny
Deny from all
</files>
 
# No access to the wp-config.php 
<files wp-config.php>
Order allow,deny
Deny from all
</files>
 
# No access to the readme.html
<files readme.html>
 Order Allow,Deny
 Deny from all
 Satisfy all
</Files>
 
# No access to the liesmich.html for DE Edition
<Files liesmich.html>
 Order Allow,Deny
 Deny from all
 Satisfy all
</Files>
 
# No error log access 
<files error_log>
Order allow,deny
Deny from all
</files>

#No access to the .htaccess und .htpasswd
<FilesMatch "(\.htaccess|\.htpasswd)">
  Order deny,allow
  Deny from all
</FilesMatch>

# Block access to includes folder
<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>

7 – Hotlink Protection gegen Bildklau

Das Hotlinking verhindert, dass Deine Bilder auf anderen Websites verlinkt werden können und somit die Ressourcen Deines Webhostings negativ beeinflussen. Mit diesem Schutz werden Deine Bilder nur dort angezeigt, wo sie es auch sollen. Auf Deiner Website. Du musst nur das Wort »domain« in Zeile 6 gegen Deine Domain tauschen. Bei mir steht dort andreas-hecht.

<IfModule mod_rewrite.c>
 RewriteEngine on
 RewriteCond %{HTTP_REFERER}     !^$
 RewriteCond %{REQUEST_FILENAME} -f
 RewriteCond %{REQUEST_FILENAME} \.(gif|jpe?g?|png)$           [NC]
 RewriteCond %{HTTP_REFERER}     !^https?://([^.]+\.)?domain\. [NC]
 RewriteRule \.(gif|jpe?g?|png)$                             - [F,NC,L]
</ifModule>

8 – Schutz gegen den »ReallyLongRequest« Banditen

Der »ReallyLongRequest« Bandit ist eine recht neue Bedrohung, die nicht direkt schädlich ist, sondern den Server mit gigantisch vielen Anfragen „erschlagen“ will. Das kann unter Umständen dazu führen, dass Deine Website extrem langsam wird oder nicht mehr erreichbar ist.

»ReallyLongRequest« Bandit heißt der Bot deshalb, weil die gigantisch langen Anfragen alle mit »YesThisIsAReallyLongRequest…« beginnen. Um den Server zu entlasten, blockieren wir diese nutzlosen Anfragen.

<IfModule mod_rewrite.c>
    RewriteCond %{REQUEST_METHOD} .* [NC]
    RewriteCond %{THE_REQUEST}  (YesThisIsAReallyLongRequest|ScanningForResearchPurpose) [NC,OR]
    RewriteCond %{QUERY_STRING} (YesThisIsAReallyLongRequest|ScanningForResearchPurpose) [NC]
    RewriteRule .* - [F,L]
</IfModule>

9 – Schütze Deinen Adminbereich mittels HTTP-Veriegelung

Mit der Kombination aus .htaccess und .htpasswd erzeugst Du einen sehr wirksamen Schutz gegen das Hacking Deines Adminbereichs. Du musst nur den Pfad zu Deiner .htpasswd anpassen.

# If you want to use it, comment it out and set your path to .htpasswd
#<Files wp-login.php>
#AuthName "Admin-Bereich"
#AuthType Basic
#AuthUserFile /usr/local/www/apache24/your-path/your-domain.com/.htpasswd 
#require valid-user
#</Files>

10 – Die XML-RPC Datei sperren

Die XML-RPC Datei ist zusammen mit dem Adminbereich von WordPress das beliebteste Angriffsziel.

Die Schnittstelle ist ein nützliches Werkzeug für die Verwaltung von Inhalten. Sie dient dazu, dass man mittels der Desktop– und der Smartphone-Apps die Website verwalten und Artikel verfassen kann. Ebenso kümmert sie sich um Pingbacks. Die Pingback-API ermöglicht eine Art »Vernetzung« zwischen den Blogs und dient gleichzeitig als Schnittstelle, um WordPress über externe Programmen verwalten zu können.

Genau diese Funktionen sorgen für teilweise wesentlich heftigere Angriffsorgien als auf den Adminbereich selbst. Denn auch über die Schnittstelle haben Angreifer dann vollen Zugriff auf die Website.

### @see https://digwp.com/2009/06/xmlrpc-php-security/

#<Files xmlrpc.php>
# Order Deny,Allow
# Deny from all
#</Files>

Mehr zum Thema: WordPress-Sicherheit: Die XML-RPC-Schnittstelle abschalten

11 – Der Referrer Header für mehr Datenschutz

Wenn Du auf einen Link klickst, sendet Dein Browser den Header HTTP Referrer an den Webserver, auf dem sich die Zielwebseite befindet. Der Header enthält die vollständige URL der Seite, von der Du gekommen bist. So können Websites sehen, wo der Traffic herkommt. Der Header wird auch gesendet, wenn externe Ressourcen (z. B. Bilder, Schriftarten, JS und CSS) geladen werden.

Der Referrer-Header ist ein Albtraum für die Privatsphäre, da Websites und Dienste Dich über das Internet verfolgen und Deine Surfgewohnheiten (und somit möglicherweise private, vertrauliche Informationen) erkennen können, insbesondere in Verbindung mit Cookies.

Angenommen, Du bist bei Facebook angemeldet. Du besuchst eine Seite mit der URL http://www.some-hospital.com/some-medical-condition. Auf dieser Seite klickst Du auf einen Link zu Deinem Facebook-Profil. Dein Browser sendet dann Referrer: http://www.some-hospital.com/some-medical-condition zu www.facebook.com, zusammen mit Deinen Facebook-Cookies, so dass Facebook Deine Identität mit dieser bestimmten Seite verknüpfen kann.

Das Problem wird noch verschlimmert durch die Tatsache, dass viele Webseiten Ressourcen wie Bilder und Skripte von Dutzenden von Drittanbietern laden, indem sie alle Informationen an sie senden, wobei der typische Besucher keine Ahnung hat, dass dies geschieht.

Gut ist, dass dieser datenschutzrechtliche SuperGau unterbunden werden kann durch den einfachen Befehl an den Browser, keinen Referrer zu senden.

## No-Referrer-Header
<IfModule mod_headers.c>
    Header set Referrer-Policy "no-referrer"
</IfModule>

12 – Die HTTP-Security-Header – Update 2019

Jedes Mal, wenn ein Browser eine Seite von einem Webserver anfordert, antwortet der Server mit der Auslieferung der Seite und sendet einen HTTP-Response-Header mit dem Inhalt. Diese Header können nicht nur alltägliche Dinge wie den Zeichensatz enthalten, sondern auch sicherheitsrelevante Einstellungen senden.

Hierfür nutzt man die sogenannten HTTP-Response-Header, mit denen man das Verhalten eines Browsers steuern kann. Ein Strict-Transport-Security-Header würde dem Browser zum Beispiel die Anweisung erteilen, nur über HTTPS zu kommunizieren.

### @see https://scotthelme.co.uk/hardening-your-http-response-headers

## X-FRAME-OPTIONS-Header
<IfModule mod_headers.c>
    Header set X-Frame-Options "sameorigin"
</IfModule>

## X-XSS-PROTECTION-Header
<IfModule mod_headers.c>
    Header set X-XSS-Protection "1; mode=block"
</IfModule>

## X-Content-Type-Options-Header
<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
</IfModule>

## Strict-Transport-Security-Header - wenn Du HTTPS nutzt, kommentiere den Block aus  ### Subdomains mit HTTPS Version ###
#<IfModule mod_headers.c>
#   Header set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
#</IfModule>

Der neue Expect-CT Header

Dieser neue Header wird zurzeit nur von Google Chrome unterstützt. Zudem befindet er sich noch im Status IETF Experimental. Trotzdem habe ich den Header bereits integriert, weil die Idee hinter diesem Header hervorragend ist. Denn wenn eine Webseite den Expect-CT Header ausgibt, wird Google Chrome überprüfen, ob ein Zertifikat für diese Webseite in den öffentlichen Certificate Transparency Logs enthalten ist.

Das verhindert, dass falsche Zertifikate unbemerkt für die betreffende Website verwendet werden können. Eine Man-in-the-middle Attacke ist dadurch nicht mehr so einfach möglich.

Folgende Einstellungen setzt der Header zurzeit:

  • enforce: Signalisiert dem Browser, dass Certificate-Transparency durchgesetzt werden soll. Falsche Zertifikate (keine Übereinstimmung in den Certificate-Transparency-Logs) führen zu einem Abbruch der Verbindung.
  • max-age: Der Browser speichert die empfangene Richtlinie für 6 Stunden (21600 Sekunden) in seinem Cache. Ist die Zeit abgelaufen, wird der Browser erneut eine CT-Richtlinie (bei einer Webseite) anfragen.
<IfModule mod_headers.c>
   Header set Expect-CT "enforce, max-age=21600"	
</IfModule>

13 – Die WordPress Standard Regeln

Dies sind die Standard-Regeln, die jede WordPress-Website während der Installation anlegt. Wenn Du eine Multisite nutzt, oder sich dein WordPress in einem Unterordner befindet, müssen diese Regeln angepasst werden.

# 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

Die komplette .htaccess als Gist

Andreas Hecht

Andreas Hecht

Er entwickelt WordPress-Websites und bietet dir einen Website Sicherheit Service und einen Performance Service für deine Website. Außerdem ist er Spezialist für Onpage SEO und bringt Deine Website in die Top-Suchergebnisse von Google.

Das könnte auch interessant sein...

138 Kommentare Kommentar hinzufügen

  1. Hallo Andreas,
    ich danke für die Neuerungen der perfekten .htaccess für WordPress. Schon vorher habe ich deine Snippets verwendet, die auf Dr.Web publiziert wurden. Was ich bisher nicht in der .htaccess hatte, waren die CORS, XML-RPC und die HTTP Security Header. Gerade habe ich die .htaccess angepasst und alles läuft einwandfrei. Dann auch noch ein dickes DANKE für dein E-Book WordPress Performance. Das habe ich im April gekauft, aber leider konnte ich aus Zeitmangel noch nicht alles umsetzen/testen.

    Viele Grüße
    Guido

  2. Der ist echt gut! Anstatt den WordPress mit Plugins zu versauen! Bringt garantiert super Page Speed. Danke dir!

  3. Hallo Andreas,

    also nachdem ich deine htaccess komplett 1zu1 übernommen habe, in der Hoffnung keine Plugins mehr fürs Caching und Security zu benötigen, war weder mein Back, noch mein Frontend erreichbar..?!
    Es hieß dann immer „Umleitungsfehler“…

    Grüße,
    Daniel

    • Update: Ich habe alle Bereiche einzeln hinzugefügt und es liegt tatsächlich an Punkt 1 und Punkt 4.

      Füge ich die garantierte Umleitung hinzu, sagt er mir „unendliche Umleitung“.

      Füge ich die 6g Firewall hinzu, sagt er mir „no permission“

      • Hi Daniel,

        danke für Deine wichtige Info! Die Umleitung läuft mit allen Servern, allerdings nur, wenn keine andere Umleitung der Domain aktiv ist. Das Problem hatte ich auch vor kurzem. Ich werde also die .htaccess etwas überarbeiten und einen Kommentar hinzufügen. Das die 6G-Firewall nicht funktioniert, höre ich jedoch zum ersten Mal. Da ist dann eine Direktive des Hosters aktiv, denn für die Firewall sagt er Dir einfach nur: Keine Berechtigung.

  4. Hallo,
    vielen Dank für die Arbeit und das Teilen.
    Allerdings fehlt mir ein wichtiger Hinweis zu Punkt 4, der 6G-Firewall.
    Da diese mir den Zugriff auf den WP Login verweigerte, habe ich etwas recherchiert und herausgefunden, dass der Code angeblich vor den WordPress eigenen Anweisungen (# BEGINN WORDPRESS … # END WORDPRESS) einzufügen ist.
    Doch auch dies brachte mir den Login nicht wieder, weshalb ich folgenden Code verwendet habe:
    https://lars-mielke.de/6067/umfassender-webseitenschutz-mit-der-6g-firewall-fuer-htaccess/
    Damit lief dann wieder alles.
    Lieben Gruß,

    -Björn

  5. Irre guter Artikel. Ich werde die htaccess ausprobieren.
    Eine Frage aber dennoch: Warum haben deine Artikel keine „sprechende URL“, sondern eine Nummer?

  6. Die Zeile ‚RedirectMatch 403 (?i)/(\$(\&)?|\*|\“|\.|,|&|&?)/?$‘ aus dem Bereich Request Strings der Firewall sorgt bei mir für ein ‚Forbidden You don’t have permission to access / on this server.‘

    Woran kann das liegen? Und wie – außer dem Auskommentieren – könnte man das evtl. beheben?

  7. Bei mir werden Hintergrundbilder und teilweise die CSS nicht mehr dargestellt (https://www.naturfotografie-kruse.de), wenn ich Deine Datei verwende. Leider kenne ich mich zu wenig aus, um nun jeden einzelnen blog durchzugehen, der evtl- den Fehler beheben könnte 🙁

  8. Hallo Andreas,
    eine ganz tolle Arbeit. Habe alles übernommen nur
    Protect your WordPress Login with HTTP Authentification und
    Ultimate hotlink protection auskommentiert, letzeres weil ich nicht weiß wie ich die Webadresse eingeben muss 🙁
    Es funktioniert alles wunderbar, nur die Google Reklame die ich im Header und Footer untergebracht habe werden nicht angezeigt.
    Vielleicht kannst Du mir sagen an was es liegen könnte.
    Gruß Helmut

    • Hallo Helmut,

      die Hotlink-Protection ist einfach. In Zeile 6 findest Du das Wort »domain«, das tauscht Du aus gegen Deine Domain. Ich hatte das dort genau beschrieben, was da bei mir steht. Die Google-Reklame könnte entweder an CORS oder an den Security Headern liegen. Kommentiere es einfach nach und nach mal aus…

    • Hallo Andreas,
      vielen Dank für die schnelle Antwort. Habe die htaccess in drei Blogs eingebaut und war ganz happy.
      Inzwischen hat sich ein Problem eingestellt. Meinen Blog schreibe ich mit Blogdesk. Heute konnte ich den letzten Bericht nich hochladen, es wurde ein 403 Fehler gemeldet.
      Hatte die komplette htaccess übernommen, nur Ultimate hotlink protection war deaktiviert.
      Jetzt habe ich nur noch The original WordPress Rewrite Rules in Betrieb und das Hochladen funktioniert wieder. Es wäre schön wenn Du mir einen Tip geben könntest an was es liegen könnte.

      Gruß Helmut

      • Hallo Helmut,

        das wird am dem Bereich »XML-RPC« liegen. Da das ein Sicherheitsrisiko ist, funktionieren die Anwendungen dieser Art nicht mehr. Schreibe also die Artikel entweder direkt in WordPress oder kommentiere den Bereich aus.

        • Hallo Andreas,
          vielen Dank für die schnelle Antwort, das war es. Habe XML-RPC auskommentiert.
          Mit WordPress direkt schreiben ist so eine Sache, bin halt Blogdesk gewöhnt. In meinem Blog sind immer sehr viele Bilder und ich bilde mir ein das ich das mit Blogdesk besser erledigen kann. Werde aber wieder einmal einen Versuch mit WordPress machen.

          Vielen Dank für deine Mühe
          Helmut

        • Schön, dass ich helfen konnte…

  9. Hallo Andreas,
    vor kurzem habe ich mir den Adminbereich mittels HTTP-Veriegelung per .htaccess und .htpasswd geschützt. Es funktioniert bestens, nur können aber meine „normalen“ Besucher PW-geschützte Seiten nicht mehr betreten, weil sie jetzt auch das vorgeschaltene Eingabeformular für die HTTP-Veriegelung sehen. Habe ich etwas vergessen?

    Im voraud danke für die schnelle AW.

    LG, Bildermann

    • Hallo!

      Wenn Du wie in meiner .htaccess nur die wp-login.php mit einem HTTP-Schutz versiehst, dann sollten normale User auf Passwortgeschützte Bereiche zugreifen können. Wenn nicht, schau Dir mal das SecSign ID Plugin näher an.

      • @ Andreas

        Danke für die schnelle AW.

        […] …sollten normale User auf Passwortgeschützte Bereiche zugreifen können […]
        Leider ist das nicht der Fall, sondern wie von mir oben beschrieben. Könnte es eventuell an der Serverkonfiguration meines Providers liegen?

        Hier mal probehalber eine mit dem „supersicherem“ PW

        Test

        gesicherte Testseite zur Illustration: https://bildermann.de/test/

        LG, Bildermann

  10. @ Adreas
    […] Dann solltest Du meinen Tipp mit SecSign mal ausprobieren. […]
    Danke. Gibt es denn als Abhilfe kein code-snippet? Dazu hatte ich bisher die ursprünglich von Sergej Müller entwickelte Zwei-Faktor-Authentifizierung „2-Step-Verification-master“ verwendet, welche ohne einem Smartphone auskommt und ein fünf Minuten gültiges PW an die bei der Registrierung hinterlegte E-Mailadresse sendet.

    LG, Bildermann
    Tipp: „2-Step-Verification-master“ liegt auf GitHub zum Herunterladen…

  11. Hallo Andreas, leider funktioniert noch immer nicht alles. Wenn ich einen der letzten Beiträge anklicke, kommt Error 404 Datei oder Verzeichnis nicht gefunden. The requested URL was not found.
    Auf zwei meiner Seiten passiert das. Bin Sicher das Du weißt an was das liegen könnte.
    Gruß Helmut

    • Hi,

      also erstens: die .htaccess aus dem Gist unten verwenden, nicht aus den Code-Snippets. Zweitens: keine anderen Teile in der .htaccess verwenden außer denen, die drin sind. Und zwar solange, bis es funktioniert. Drittens: Gehe zu »Einstellungen => Permalinks« und speichere Deine Permalinks so wie sie sind nochmals ab. <= WICHTIG! Funktioniert es immer noch nicht, stimmt mit der Serverkonfiguration etwas nicht. Die .htaccess läuft problemlos auf über hundert Websites.

      • Hallo Andreas,
        vielen Dank für deine Mühe und Geduld. Das ich immer so spät antworte liegt an der Zeitverschiebung, ich lebe in Thailand. Jetzt funktioniert es, vielleicht hat das Speicher der Permalinks geholfen, es kann aber sein das der Provider gerade an dem Server was gemacht hat. Ich habe von Anfang an die htaccess aus dem Gist benutzt und auch nichts anderes eingefügt.
        Gruß Helmut

  12. Hi Andreas,

    echt klasse Sache, dass du hier eine sichere und gut durchdachte .htaccess bereitstellst.
    Nach Übernahme deiner Vorlage und entsprechenden Anpassungen (Domain, auch die Permalink Struktur Anpassung) funktionieren leider meine Bilder nicht mehr, also all die *.jpg, *.png,…werden nicht angezeigt.
    So wie ich das sehe, versucht der Server nun, diese auch „gesichert“ also per https zu übertragen, was scheinbar nicht funktioniert.
    Kannst Du mir ggf. weiterhelfen? Vielen Dank im Voraus!

    Grüße
    Alex

    • Hi Alex,

      das kann meiner Meinung nach nur mit dem Block »Ultimate Hotlink Protection« zu tun haben. Kommentiere den einfach mal aus und schau, was passiert. Wenn es funktioniert, muss im Code https gegen http ausgetauscht werden. Und bitte: nimm den Code nur aus dem Gist, mein Plugin scheint etwas bei der Anzeige des Codes zu ändern.

      • Hi Andreas,

        danke für den Hinweis mit dem Block, das war der richtige Anstoß.
        Der Fehler lag allerdings auf meiner Seite, ich hatte aus Gewohnheit die Domain mit TLD Qualifier eingetragen und dann hat es nicht geklappt, ohne dann schon 😉
        Nun klappt der Aufruf der Seite super schnell und dazu noch gut gesichert, klasse, vielen Dank und weiter so!!!

  13. Hilfe. Hallo Andreas ich bin es schon wieder.
    Ich möchte gern Ultimate hotlink protection aktivieren komme aber mit der Eingabe der Domain nicht zurecht. Habe alle möglichen Versionen probiert, entweder werden keine Bilder im Blog angezeigt oder man kann sie wie bisher kopieren.
    Könntest Du mir freundlicherweise hier !^https?://([^.]+\.)?domain\. [NC] eine normale domain ohne www eintragen?
    Für deine Mühe bedanke ich mich im Voraus
    Gruß Helmut

  14. Hi Andreas,

    ich habe den Code aus dem Gist zu entnommen und der .htaccess hinzugefügt. Allerdings sagt GTmetrix und Google Pagespeed keinen Unterschied. Es ist quasi alles beim alten. Hast du einen Tipp?

    Gruß Benni

  15. Hi Andreas,
    vielen Dank für deine tolle Arbeit. Würde es nicht auch Sinn machen die Zugriffe auf die author Abfrage zu blocken. Habe hier immer wieder sehr viele logs.

    RewriteCond %{QUERY_STRING} .*author=(.+.?) [NC]
    RewriteRule (.*) /blog/?author= [NC,L,R=301]

    Gruss
    Christian

    • Hi Christian,

      bei einem Mehr-Autoren-Blog ergibt das mit Sicherheit Sinn. Wenn nur ein einziger Autor vorhanden ist, dann lassen sich mit Yoast SEO die Autoren-Archive abschalten. SEO => Darstellung in Suchergebnissen => Autorenarchive deaktivieren. Dann erfolgt bei Aufruf der Autoren-ID eine 301-Weiterleitung auf die Startseite.

  16. Hallo Andreas,
    erst einmal vielen Dank dafür, dass du die Früchte deiner .htacces-Arbeit hier veröffentlichst. So in dieser praxisorientierten Art habe ich das vorher noch nicht gesehen, und ich habe es auf meiner eigenen Website mit Erfolg umgesetzt (siehe https://pmueller.de/sicherer-und-schnellerer/).

    Insgesamt läuft alles supergut, aber in Abschnitt 9 hat der HSTS-Header Probleme verursacht:

    Header set Strict-Transport-Security „max-age=15552000; includeSubDomains; preload“

    Ich habe unverschlüsselte Subdomains im Einsatz, und der Parameter includeSubDomains hat bewirkt, dass man nach einem Aufruf der verschlüsselten Hauptdomain die unverschlüsselten Subdomains nicht mehr aufrufen konnte. Die Browser haben versucht, HTTPS zu erzwingen und als das nicht klappte, die Subdomains als unsicher geblockt.

    Sicherlich ein Edge Case, aber nach einer Entfernung von includeSubDomains funktioniert alles wieder. Fange ich mir dadurch andere Nachteile ein? Gibt’s vielleicht noch eine elegantere Lösung?

  17. Hi,
    danke für diese tolle Zusammenstellung!
    Bin da nicht ganz so tief drin, daher meine Frage:

    Macht es Sinn ab Zeile 265 noch folgende Listen zu implementieren?
    http://www.wizcrafts.net/htaccess-blocklists.html (unten auf der Seite)
    https://pastebin.com/BPRv4TDd (davon Zeile 36-47)
    oder wäre das über das Ziel hinaus geschossen?
    Bzw. gibt es evtl. eine „bessere“ Blockliste die hier geigneter wäre?
    Zweck ist eigentlich so viele Bots wie möglich (jedoch nicht Google/Bing) aus zu schließen.
    VG

  18. Hi,
    sorry, noch etwas, was ich eben vergessen habe:
    Oftmals greifen ja bei WordPress verschieden Tools auf die /wp-admin/admin-ajax.php zu. Wenn ich also die /wp-admin/ komplett blocke, kommt der Passwort-Dialog dann auch manchmal im normalen Frontend hoch.
    Meine Fragen nun;
    1. Muss ich zwei .htaccess-Dateien erzeugen (eine im root, eine im /wp-admin/ für den Schutz der /wp-admin/ oder reicht eine?
    2. Sollte man die Ausnahme der ajax-datei in den Passwortschutz integrieren, oder davor bzw. darunter separat einfügen?
    VG

    • Hi Mike,

      die /wp-admin/ nicht blocken! und die Ajax erst recht nicht. Wenn Du noch keine Probleme hast, mit dem Blocken bekommst Du sie garantiert. Dann integriere lieber die Blockliste unverändert in die .htaccess.

      • Sorry ich meinte auch eigentlich den Passwortschutz für die wp-login.php… da hat mir mal jemand gesagt, daß das immer nur in Verbindung mit der Freigabe der Ajax ginge, aber vielleicht war das falsch…

  19. Hallo Andreas,
    danke für die tolle Vorlage.
    Ich wollt mal fragen, ob die Zeilen 162 – 166 überflüssig sind, da die Dateiendungen (js|css|xml|gz) ebenfalls in der FilesMatch Abfrage in Zeile 181 – 185 (js|css|xml|gz|html|woff|woff2|ttf) enthalten sind und es sonst keine weitere Unterschiede gibt.

  20. Hallo Andreas,
    ich habe deine tolle .htaccess-Vorlage eingebunden. Da ich momentan noch an der Seite arbeite, ist diese mittels Passwortabfrage gesichert. Allerdings wird seit der Nutzung der 6G Firewall-Regeln kein Passwort mehr abgefragt und die Seite ist direkt zugänglich.
    Das Problem sind die Zeilen, wo ein Anführungszeichen \“ enthalten ist (Nr.: 207, 230, 231). Laut PhpStorm sind diese Zeilen angeblich fehlerhaft (illegal/unsupported escape sequence), obwohl ein Backslash davor steht.

    Hast du evtl. eine Idee wie dieses Problem behoben werden kann?

    Gruß
    Alex

  21. Ganz wunderbarer Artikel – vielen Dank!

    Zu der Geschichte mit dem Bilderklau (hotlinking) würde ich gern ein paar Gedanken hierlassen. Wenn man Produkte verkauft, wird man möglicherweise (sicher!) wollen, dass Google & Co. diese auch in Form der Produktbilder indizieren und in den Ergebnissen anzeigen können. Man passt also ein paar Zeilen an und schon können mögliche Kunden über die entsprechenden Bildersuchen zur eigenen Webseite gelangen. Der Rest der Welt („Content-Diebe“) bleibt außen vor – fast.
    Warum nur fast? Da draußen hat es merkwürdige Seiten (häufig in Form von Blogs) mit zum Teil kuriosen Domain-Namen, die offensichtlich nur den Zweck haben, wild durcheinander Bilder zu irgendwelchen Stichworten aufzulisten. Ein paar davon haben Bilder von meiner Seite per direkter Verlinkung eingebunden. Das hat mich schon immer geärgert und die paar Zeilen in der .htaccess kamen mir damals wie gerufen. Ich habe es so gelöst, dass ich ein sogenanntes „Hotlink-Bild“ anstatt der originalen Bilddatei ausliefern lasse. Funktioniert soweit.
    Wenn man wie ich jedoch ohne Referrer unterwegs ist, bringt das alles natürlich nichts – das Original Bild wird anstandslos innerhalb der „fremden Umgebung“ angezeigt. Aber auch den Agents, die einen Referrer senden, kann das Bild auf der fremden Seite angezeigt werden. Nämlich dann, wenn der User von der Ergebnisseite einer Suchmaschine kommend das Bild bereits im Cache hat.

    • Hi Mario,

      perfekt ist die Hotlinking-Lösung natürlich nicht. Sie soll ja auch nur verhindern, dass man Deine Bilder direkt mit Deinen Bildlinks einbindet.

      • Andreas, bitte nicht als (schlecht gemeinte) Kritik auffassen – Dein Artikel hier sollte für 99,9 Prozent der Webseitenbetreiber als Pflichtlektüre gelten.

        Datenklau ist seit den Urzeiten des Web ein Thema und wird es (leider) immer bleiben. Ich denke, Sir Tim (Berners-Lee) hat schlicht nicht mit dem Menschen an sich und seinen guten und weniger guten Eigenschaften gerechnet.

        Freue mich auf weitere spannende Beiträge!

  22. Hallo,
    ich habe fast alles übernommen, aber nach èberprüfung bsplw. durch Observatory oder webkoll erhalte ich keine besseren Bewertungen. Dann noch die Frage: bei mir stand zuerst die php Info (bin bei 1und1) bleibt die ganz Anfang? Das habe ich nämlich so gemacht,
    Danke für eine Info
    Claudia

    • Hi Claudia,

      keine besseren Bewertungen zu bekommen heißt nicht, nichts Wertvolles für die Sicherheit der Website getan zu haben. Davon abgesehen ist die .htaccess nur ein Baustein im Bereich der Absicherung von WordPress.

      Und bitte lösche die info.php wieder von Deinem Server nach Gebrauch. Sie ist ein Sicherheitsrisiko.

  23. Hallo Andreas
    ich danke Dir sehr für Deine perfekte .htaccess.
    Beim versuch mit dem Mysqldumper per Perl-Cronscript automatische backups zu erstellen habe ich folgende Fehlermeldung:
    You don’t have permission to access /cgi-bin/crondump.pl on this server.
    Hast du eine Idee wie ich dies lösen könnte?
    Lieben Dank
    Detlef

  24. Hallo Andreas,
    danke für deine Antwort.
    Denke auch, dass es an den von Dir genannten Stellen liegen könnte, habe aber von der Materie so gut wie keine Ahnung.
    Nehme ich an den 4 Stellen „cgi-“ und „cgi“ einfach raus, oder gibt es einen eleganteren Weg?
    RedirectMatch 403 (?i)/(=|\$&|_mm|cgi-|etc/passwd|muieblack)
    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)/(=|\$&|_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)$

  25. Hallo Andreas,
    Deine htaccess ist wirklich Klasse. Sie funktioniert einwandfrei bei:
    https://oldtimer-veranstaltung.de/
    aber nicht bei
    https://oldtimer-veranstaltung.de/kalender/ etc.
    Bei dieser Webseite werden alle Links beim Anklicken auf die 404.php Seite von WP geleitet.
    Wie kann ich das Problem lösen?
    Beste Grüße
    Michael

  26. Hallo Andreas,

    herzlichen Dank für Deinen Tipp. Die RewriteBase musste in diesem Fall auf /kalender/ geändert werden.

  27. Hallo Andreas,

    ich habe eine Frage zu 1 – Garantierte HTTP zu HTTPS Umleitung:

    Ich habe den Code eingebaut, damit aber kein Ergebnis erzielt. Links wie „http://www.bauernhof.net/category/tiere/“ rufen die Startseite des Auftritts auf.

    Ich weiß nicht wo der Fehler liegt bzw. ich ansetzen kann. Vielleicht hast du ja einen Tip, wo ich nachschauen muss. Ich verwende zum Caching das Plugin WP-Rocket, dass auch in die htacsess schreibt.

    Vielen Dank

    • Hallo Bernhard,

      zur Fehlersuche würde ich definitiv WP-Rocket deaktivieren. Danach kannst Du es nochmal testen. Wenn es nicht funktioniert, kann da auch irgendwo ein 301-Redirect für genau diese URL existieren. Ich vermute das ganz stark, weil andere Links von http auf https bei dir funktionieren.

  28. Hallo Andreas,

    Danke natürlich erst mal für die tolle Arbeit!
    Ich musste meinen Blok komplett neu aufsetzen und habe gleich mal deine htaccess verwendet, musste jedoch feststellen, dass nun keine Bilder mehr an mobile Endgeräte ausgeliefert werden.

    Blockt die htaccess irgendwie den Zugriff auf die responsive option meines Avada themes?

    Wenn ich die htaccess nicht verwende, bekomme ich Bilder geladen.

    Bitte um Hilfe 😀

    Danke schon mal

    • Hi Daniel,

      es kann auch sein, dass Du den No-Referrer-Header auskommentieren musst. Probiere es aus. Es liegt auf jeden Fall nicht an der .htaccess Datei, denn die läuft fehlerfrei auf mittlerweile über 380 Websites. Könnte in Deinem Fall auch ein Kompatibilitätsproblem mit einem Plugin sein, darauf tippe ich mal ganz stark.

      Z.B. Ein Caching-Plugin oder ähnliches.

  29. Hallo Andreas, super Anleitung!

    Habe einige Sicherheitselemente bei mir eingebaut. Bei den Performance-Elementen habe ich festgestellt dass die sich die Komprimierungseinstellungen nicht so gut mit dem WP-Plugin WP-Rocket vertragen. Da ist bei mir die Ladezeit sogar gestiegen. Werde aber in Kürze auch mal einen Versuch ohne WP-Rocket und nur mit den htaccess-Einstellungen machen. Mal sehen was dann tatsächlich schneller ist. Wäre ja um so besser wenn man noch ohne Plugin die gleiche oder sogar eine bessere Performance erreichen kann 🙂

  30. Genau diese Kombination hatte ich schonmal – war auf meiner Seite mit Pingdom gemessen mehr als 20% langsamer als WP-Rocket…

    (Hängt vielleicht auch davon ab was man an Skripten etc. auf seiner Seite hat, bin da eher schlank unterwegs)

    Werde dem Ganzen aber demnächst an einem regnerischen Wochenende nochmal eine Chance geben, entwickelt sich ja alles weiter. 🙂

  31. Hallo Andreas,

    danke für den tollen Artikel! Leider habe ich das Problem, dass Google PageSpeed immer noch behauptet ich sollte die .css und .js Dateien komprimieren!?

    Hast Du zufällig eine Idee wo es hackt??

    Danke für Deine Hilfe!
    Manfred

  32. Die .htacccesa ist echt Super. Vielen Dank hierfür.
    Leider scheint sie aber Blogger Software wie MarsEdit auszuschliessen obwohl ich das
    xmlrpc ausgeklammert habe.
    Eine Idee?

  33. Guten Tag,
    vielen Dank, dass ich diese hervorragende htaccess veröffentlicht haben!
    Vieles habe ich noch nicht gewusst und werde es nun einsetzen.
    Ein paar Fragen habe ich dazu jedoch:
    bei den folgenden drei Zeilen gibt es Unterschiede bevor die verschiedenen Dateitypen aufgezählt werden. Also ich meine bei manchen steht ein \ vor der Auflistung, bei einer Zeile nicht und bei einer anderen Zeile sind es gleich zwei \ .
    Ist es egal, ob kein \ oder ein \ oder gleich zwei \\ ?
    Bisher war mein Wissensstand, dass WOFF2-Dateien schon komprimiert sind und nicht mehr mit GZIP komprimiert werden müssen bzw. dass das sinnlos ist. Ist das korrekt?

  34. Hallo Andreas,
    tolle Arbeit, danke für diesen Beitrag! Bei mir scheint der Abschnitt „Ultimate hotlink protection“ nicht zu funktionieren. Meine Domain lautet „https://monz.photos“. Ich habe nun „monz.photos“ eingetragen. Wahrscheinlich passt die verwendete Regex ehjer für *.de-Domains? Ich bekomme keine Bilder mehr angezeigt, wenn dieser Absatz drin ist 😉 Hast Du eine Idee?

  35. Vielen Dank für die Aktualisierung. Zwei kleine Hinweise und eine Frage:
    Zeile 36 – ein „t“ zu viel 😉
    … because Let’s Encrypt ist using .well-known => is using

    Zeile 351 falsche Zeilennummer
    IMPORTANT: Change »?domain\« in line 332 to your domain name
    steht in Zeile 361, da wurde wohl nachträglich noch was eingefügt
    ——
    Ich möchte ein Redirect von statischen URLs wie *.html zu WordPress-URLs einrichten (also einfach nur ein / statt .html) und nicht alle Seiten einzeln per Redirect 301 auflisten. Der folgenden Schnippsel, den ich bei Stack Overflow gefunden habe, erweitert den Standard-WordPress. Ist das deiner Meinung nach okay? Und harmoniert das mit deiner .htaccess?

    # BEGIN WordPress

    RewriteEngine On
    RewriteBase /
    RewriteRule (.+)\.html?$ http://www.example.com/$1/ [R=301,L]
    RewriteRule ^index\.php$ – [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]

    # END WordPress

    Danke für deine Expertenblick auf den Schnippsel 😉

  36. Hallo Andreas,

    danke für die gute Zusammenfassung!
    Eine Frage und einen Vorschlag hab ich:
    Warum ist archive.org für dich als User Agent Bot problematisch? Das ist doch ein guter Dienst…

    Und ein Vorschlag als Zusatzoption für die Headers als Erinnerung als Terry Prattchet 🙂
    vgl. u.a. https://nerdcore.de/2015/03/14/gnu-terry-pratchett-http-header/

    header set X-Clacks-Overhead „GNU Terry Pratchett“

  37. Hat jemand schon Erfahrung mit bmbfotos.com gesammelt ? meine Fotos werden einfach nicht entfernt! über 10 meiner Webseiten werden dort angezeigt
    Image Traffic Verlust -60% schrecklich!

    LG: Frank

  38. Ich habe diese htaccess Datei nun auf meinem Blog laufen. Sieht bislang recht schick aus alles und läuft schneller. Ist denn da eigentlich mein Cache-Plugin überflüssig? Danke schon mal und VG

  39. WOWW
    Ich danke dir, ich war auf der Suche für ein Problem, da eine Webseite von Mexiko aus nicht erreichbar war (403 Forbidden). Immer noch ohne Erfolg. Jedoch habe mir erlaubt ein paar Teile deiner Vorlage zu nutzen und jetzt saußt die Page auch in anderen Ländern wo teils noch 3G Verbindung als perfekt angesehen werden darf, super flott durchs Netzt. Das eine „noch“ nicht gelöst, aber was anderes dafür optimiert.
    Danke Dir dafür.

  40. Ich verfolge deine spitzenmäßige .htaccess-Vorlage seit Jahren und bin wirklich froh darum! Gerade in Verbindung mit Autoptimize und Cache Enabler eine super Performance-Turbo!

    Eine Frage habe ich jedoch: Warum fehlt in Abschnitt „4 – Dateien komprimieren und cachen“ im Bereich Media Files „jpg“? Sollte das nicht unter Zeile 44 als
    ExpiresByType image/jpg „access plus 1 month“
    stehen?

    Noch ist jpg ja das am weitesten verbreitete Bildformat. 🙂

    • Moin,

      nein, da soll exakt stehen, was da steht:-) Das umfasst neben .jpeg auch .jpg Dateien.

      • Interessant, dann wird quasi JPG, jpeg, jpg usw. als ein Summs betrachtet?
        Dachte nur weil mir Google Pagespeed Insights im Bereich „Statische Inhalte mit einer effizienten Cache-Richtlinie bereitstellen“ immer noch diverse jpg-Bilder anmäkelt.
        Gleiches gilt für woff2-Schriften. Fehlt da vielleicht in Zeile 72 nicht das hier:
        ExpiresByType font/woff2 „access plus 1 month“

        • Vielleicht schaust Du einfach mal in die .htaccess Datei am Ende des Artikels hinein, wie von mir im Beitrag empfohlen? Bitte also zuerst lesen und dann was dazu sagen.

  41. Genervt? Ok, da steht zwar der Absatz

    Header append Vary: Accept-Encoding

    aber das ist jetzt nicht die Antwort auf meine Frage bzw. eine Erklärung, warum sich Google Google Pagespeed Insights im Bereich “Statische Inhalte mit einer effizienten Cache-Richtlinie bereitstellen” immer noch über Woff2-Dateien beschwert, aber gut. Frag ich halt jemand anders.

  42. Der Artikel auf Dr. Web über die HTTP security header Ist schon etwas älter. Wie wäre es mit einem Update für diesen Artikel oder auch einen neuen Artikel, in welchem auch über CORS aktivieren informiert wird, also wann man das ganze braucht bzw. wann dies sinnvoll ist und auch mit dem neuen header Feature-Policy ?

    • Hi Franz,

      den Artikel auf Dr. Web werde ich so schnell wohl nicht updaten. Warum man das Ganze braucht steht ja schon in diesem Artikel. Header die in meiner .htaccess nicht enthalten sind, sind zu kompliziert zu implementieren und bringen dafür letztendlich nicht ausreichend zusätzliche Sicherheit.

      • Recht herzlichen Dank für Ihre Antwort!
        Habe anscheinend ein Verständnisproblem.
        In einer Content Security Policy lege ich doch fest, welche Dateitypen von welchen Domains geladen werden dürfen. Wieso braucht man dann auch noch den Abschnitt Aktivierung der CORS bzw. wieso wird dadurch die Sicherheit erhöht, wenn dabei alle Quellen oder domains zugelassen werden???
        Und Kommt der Abschnitt mit den CORS in der .htaccess Vor oder nach der CSP?

        • Moin,

          CORS ist einfach eine wichtige Ergänzung zur Content Security Policy. Oder: Ein Kompromiss, wenn man die Content Security Policy nicht festlegen will, weil diese extrem kompliziert zu erstellen ist. Macht man dort einen Fehler, funktionieren Updates nicht mehr richtig usw… Der Pflegeaufwand ist also größer als der Sicherheitsgewinn.

  43. Dankeschön Herr Hecht für ihre erneute Erklärung.
    Wenn ich nun eine voll und ganz funktionierende Content security Policy habe, dann brauche ich das mit den CORS nicht???

  44. Hi Andreas,

    In meiner alten htaccess war schon irgendwie totales Chaos :D.
    Da hat mir das echt geholfen!

    weiter so
    Viele Grüße

  45. Vielen Dank für die tolle .htaccess! Ich habe auch die Aktualisierungen im Auge behalten und bei mir immer wieder erneuert. Läuuuft. Klasse, dass du dir die Mühe machst, dich mit dieser komplizierten Materie so detailliert auseinanderzusetzen und dein Wissen in dieser Form weiterzugeben.

  46. Lieber Andreas, ich hab bitte eine Frage. Wenn ich für eine neue Seite ein gutes WordPress Hosting, wie Kinsta oder Raidboxes benutze, brauche ich trotzdem viel an der .htaccess zu ändern? Ich habe nämlich wenig Ahnung und es wäre nicht schlecht, wenn ich mir etwas Arbeit ersparen könnte.
    Viele Grüße
    Franko

  47. Bei der Verwendung des Plugins „All-in-One Event Calendar“ kann es im Frontend beim Durchblättern des Kalenders zu einem 403 kommen. Auf der Suche Suche nach dem Grund wurde ich hier fündig:
    https://www.academiathemes.com/2018/all-in-one-event-calendar-something-went-wrong-while-fetching-events-403-forbidden/
    Auch bei mir half es, die Zeile „RedirectMatch 403 (?i)(~|`||:|;|,|%|\\|\s|\{|\}|\[|\]|\|)“ auszukommentieren.

  48. Hallo,

    vielen, vielen Dank für die sehr ausführliche htaccess Datei! 🙂

    Ich habe jedoch eine Frage zum cache-enabler. Und zwar erstellt dieser mir ebenfalls Rules in die .htaccess Datei. Kann ich diese zusätzlich, am Ende der Datei einfügen? Oder überschreiben sich hier die einen oder anderen Rules?

    Beispielsweise folgendes würde dann doppelt auftauchen (in deinen htaccess rules und in denen vom cache-enabler. Sollte ich hier alles was doppelt ist entfernen?

    RewriteEngine On
    RewriteBase /

    Ebenfalls bin ich mit folgender Zeile etwas unsicher. In deinen rules steht:
    RewriteRule . /index.php [L]

    In denen vom cache-enabler:
    RewriteRule . /index.php [END]

    Hier die gesamte Auflistung der Rules vom Cache Enabler.

    # BEGIN Cache Enabler

    RewriteEngine On
    RewriteBase /

    # set blog sub path
    SetEnvIf Request_URI „^(.*)$“ SUB_PATH=/wp-content/cache/cache-enabler/

    # set Cache Enabler path
    SetEnvIf Request_URI „^(.*)$“ CE_PATH=$1
    SetEnvIf Request_URI „^(/)index.php$“ CE_PATH=$1

    # webp HTML file
    RewriteCond %{ENV:CE_PATH} /$
    RewriteCond %{ENV:CE_PATH} !^/wp-admin/.*
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteCond %{QUERY_STRING} =““
    RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteCond %{HTTP:Accept} image/webp
    RewriteCond %{DOCUMENT_ROOT}%{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index-webp.html.gz -f
    RewriteRule ^(.*) %{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index-webp.html.gz [L]

    # gzip HTML file
    RewriteCond %{ENV:CE_PATH} /$
    RewriteCond %{ENV:CE_PATH} !^/wp-admin/.*
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteCond %{QUERY_STRING} =““
    RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
    RewriteCond %{HTTP:Accept-Encoding} gzip
    RewriteCond %{DOCUMENT_ROOT}%{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index.html.gz -f
    RewriteRule ^(.*) %{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index.html.gz [L]

    AddType text/html .gz
    AddEncoding gzip .gz

    # webp HTML file
    RewriteCond %{ENV:CE_PATH} /$
    RewriteCond %{ENV:CE_PATH} !^/wp-admin/.*
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteCond %{QUERY_STRING} =““
    RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
    RewriteCond %{HTTP:Accept} image/webp
    RewriteCond %{DOCUMENT_ROOT}%{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index-webp.html -f
    RewriteRule ^(.*) %{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index-webp.html [L]

    # default HTML file
    RewriteCond %{ENV:CE_PATH} /$
    RewriteCond %{ENV:CE_PATH} !^/wp-admin/.*
    RewriteCond %{REQUEST_METHOD} !=POST
    RewriteCond %{QUERY_STRING} =““
    RewriteCond %{HTTP_COOKIE} !(wp-postpass|wordpress_logged_in|comment_author)_
    RewriteCond %{DOCUMENT_ROOT}%{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index.html -f
    RewriteRule ^(.*) %{ENV:SUB_PATH}%{HTTP_HOST}%{ENV:CE_PATH}index.html [L]

    # wp override
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [END]

    # END Cache Enabler

    • Hallo Nissa,

      ich höre zum ersten Mal, dass Cache Enabler Regeln in der .htaccess Datei erstellt. Da scheint etwas mit der Konfiguration nicht zu stimmen. Oder hast Du die selbst hinzugefügt? Wie auch immer, die kannst Du löschen, wenn Du meine KOMPLETTE .htaccess verwendest. Meine Konfiguration sieht so aus:
      Cache Enabler Einstellungen

  49. Danke!

    Dann hat ggf mein hoster diese Regeln erstellt. Jedenfalls sind die oben genannten Rules nicht sinnvoll, könnten sogar die gesamte Konfiguration durcheinander bringen?

    Wegen des Settings bezüglich WebP mit Optimus. Ich habe diese deaktiviert und nutze stattdessen imagify. Was ist deiner Meinung nach sinnvoller?

  50. Danke nochmals!

    Mir ist gerade aufgefallen dass wenn ich mein backend über http://www.beispiel.com/wp-admin

    aufrufe, diese zu folgender URL weitergeleitet wird:

    https://www.www.beispiel.com/wp-admin

    Das Problem besteht nur in der Kombination, bei der http://www. am Anfang sowie /wp-admin am Ende der URL steht.

    Da ich generell das www in meiner Domain nutze, habe ich dafür lediglich folgende Zeile bearbeitet:

    RewriteRule ^ https://www.%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

    Ich vermute dass dies so nicht funktioniert und ggf. auch weitere Zeilen bearbeitet / eingefügt werden müssen?

    Ebenfalls möchte ich gerne erreichen dass jede URL auf https://www. weitergeleitet wird, sprich auch wenn links zu images direkt per http:// oder http://www. oder https:// geöffnet werden.

    Dies hatte ich zuvor mit anderen Rules hinbekommen, funktioniert aber in der Zusammenstellung mit deinen htaccess Rules leider nicht 🙁

    Übrigens, ich gehe davon aus, dass es sich bei folgender Zeile um blockierte user agents handelt? Genügt es hier |ahrefs| zu entfernen um den crawler wieder zu zulassen?

    RewriteCond %{HTTP_USER_AGENT} (360Spider|acapbot|acoonbot|ahrefs| ….

    Nochmals vielen Dank im Voraus!

    • Hi,

      nicht im Code der Datei herumfummeln. Das geht immer schief. Der betreffende Code-Teil ist nur zur definitiven Umleitung von http auf https da. Die von Dir gewünschte Domain stellst Du unter »Einstellungen => Allgemein« ein. Zudem noch in den Einstellungen Deines Webhosters. Das war es dann.

  51. Hallo,

    leider wird jedoch die URL dann nicht zwingend über https://www. aufgerufen sondern auch über https:// (was zum duplicate content führt). Beispielsweise wenn eine Image URL ohne www. im browser geöffnet wird.

    Habe es nun mit Hilfe folgenden Rules hinbekommen, jedoch scheint sich dies sehr auf die Performance auszuwirken.
    Ich vermute es sind zuviele Abfragen welche gemacht werden? Möglicherweise kann man diese Rule irgendwie zusammenfassen?

    Ansonsten habe ich keine Möglichkeit gefunden zwingend https://www. verwenden zu können ohne eine solche Rule zu erstellen? Da hilft leider auch das hinterlegen der https://www. in den Einstellungen nicht.

    # ———————————————————————-
    # FORCE USING https://WWW.
    # ———————————————————————-

    RewriteEngine On
    RewriteCond %{HTTPS} =off [OR]
    RewriteCond %{HTTP_HOST} !^www. [OR]
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index.(html|php)
    RewriteCond %{HTTP_HOST} ^(www.)?(.+)$
    RewriteRule ^(index.(html|php))|(.*)$ https://www.%2/$3 [R=301,L]

  52. Hi,

    ich habe deinen Kommentar gelesen, jedoch wüsste ich nicht dass in den Einstellungen des Webhosters eine force www option gäbe.

    Die URL Ansich ist dort bereits mit https://www. hinterlegt.

    Das weiterleiten auf https://www. funktioniert ja auch wenn die domain ganz gewöhnlich geöffnet wird in allen varianten. (mit und ohne www, mit und ohne https).

    Jedoch bei einer direkten Eingabe einer Bild URL in die Browser Adressleiste, funktioniert dies leider nicht.

    http://domain.com/bild.jpg -> https://domain.com/bild.jpg
    https://domain.com/bild.jpg -> https://domain.com/bild.jpg

    Nur folgende variante wird zum gewünschten Ziel weitergeleitet:
    http://www.domain.com/bild.jpg -> https://www.domain.com/bild.jpg

    Oder verursacht dies kein Duplicate Content wenn sowohl mit und ohne www links/bilder geöffnet werden können?

    Übrigens scheint eine der Rules auch Schwierigkeiten mit Javascript zu verursachen.
    Die sidebar im backlink ist nicht mehr fixiert und bewegt sich beim scrollen nicht mit.

    Ebenfalls tauchen keine untermenus beim mouse over effect auf.
    Auch sucuri meldet dass zugriffe zu manchen .js dateien geblockt sei.

    /wp-content/plugins/revslider/public/assets/js/jquery.themepunch.revolution.min.js
    Unable to scan the page. 403 Forbidden

    /wp-content/plugins/revslider/public/assets/js/jquery.themepunch.tools.min.js
    Unable to scan the page. 403 Forbidden

    Habe bereits die Rules angeschaut konnte aber auf anhieb nichts finden, welches diese blockiert.

    Bevor ich nun jede Zeile einzeln entferne bis ich den Fehler finde, wäre ich dir sehr dankbar mir da kurz weiterzuhelfen, sofern dir der Fehler bekannt ist.

    Vielen Dank im Voraus und sorry wegen des Langen Textes, aber ich wollte dies gerne genauer Erläutern bezüglich des „force https with www“.

  53. Hallo,

    ich wollte dir gerne mitteilen dass ich nun nach schrittweisem einfügen der htaccess zeilen den Übeltäter für die im wp-admin nicht-fixierte sidebar sowie der fehlenden mouse over effekte gefunden habe:

    RewriteCond %{QUERY_STRING} (globals|mosconfig([a-z_]{1,22})|request)(=|[|%[a-z0-9]{0,2}) [NC,OR]

    Kannst du mir mehr dazu sagen was genau dieser Befehl tut, und weshalb dieser die Darstellung zerstört?

    Bei einer frischen wordpress installation passiert dies übrigens nicht. Heisst es muss mit irgendeinem Plugin oder einer Konfiguration in Konflikt geraten.

  54. Hallo Andreas, guten Abend Herr Hecht,
    vielen Dank für diese tolle .htaccess . Ich habe eine kleine Frage. Wie kann ich über die .htaccess eine Verbindung zu Gravatar.com verbieten ? Es gibt zwar viele Möglichkeiten Gravatare zu unterbinden/verbieten usw, ich kenne diese Möglichkeiten fast alle. Ich habe aber einen Code-Schnipsel “ #profile-header .background-avatar “ gefunden, der trotz aller mir bekannten Möglichkeiten Gravatare in meine Seite einbindet. Die für mich einfachste Möglichkeit diese zu verhindern wäre über die .htaccess. Kannst du mir mit einem einfachen Code-Schnipsel weiter helfen ? Vielen Dank im Voraus ! gtx, Olli

    • Hi Olli,

      warum so kompliziert? Log Dich in WP ein und gehe zu »Einstellungen => Diskussion«. Da kannst Du die Avatare komplett abschalten.
      Avatare abschlaten in WordPress

      • Hallo Anderas,
        erst mal Danke für deine Antwort. Genau diese Lösungsansätze meinte ich, als ich schrieb, ich kenne fast alle. Und genau diese Möglichkeit bringt rein gar nichts. Es werden dann nur die Gravatare ausgeblendet. Die Verbindung zu, und der Datenabgleich mit, Gravatar.com findet trotzdem statt. Und genau das will ich verhindern. Nur das Abschalten, wie du es beschreibst, verhindert nicht den Datenabgleich. Auch die bekannten PlugIns, die Gravatare ausschalten sollen, blenden nur die Bilderchen aus. Die eigentliche Verbindung zu Gravatar.com läuft aber weiter. Ich habe dich schon gezielt nach einer .htaccess Möglichkeit gefragt. WordPress nimmt mit so vielen Diensten im Hintergrund Verbindung auf, ohne das wir wissen mit welchen. Woher weiß ein PlugIn, dass es ein Update gibt? Das mag ja nett und komfortabel sein. Aber Kontrolle ist etwas anderes. Ich will die Verbindung zu Gravatar.com verhindern.

  55. Hey Andreas,
    nochmals vielen Dank an dieser Stelle für deine hammermäßige .htaccess.
    Allerdings wunder ich mich dass die Pingdom Tools das fehlende gzip anmeckern:
    F45 Compress components with gzip
    Das wird doch in der htaccess aktiviert, oder?

  56. Lieber Herr Hecht,

    danke für die geleistete Arbeit und das Sie Ihre Datei auch noch gratis der Community zur Verfügung stellen. Ich hätte ein/zwei Fragen: Kann ich Ihre .htaccess Datei auch in Kombination mit dem Plugin „WP Rocket“ verwenden oder kommt es zu Problemen? Bzw. gibt es ein Plugin (z.B. Sicherheitsplugins wie iTheme Security) welches ich auf keinen Fall zusammen mit Ihrer Datei verwenden sollte?

    Beste Grüße

  57. Vielen Dank für Ihre schnelle Antwort.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Do NOT follow this link or you will be banned from the site!
Pinnen
Teilen
Teilen