Recommandations .htaccess

Oct 05 2020

J'ai un site Web personnel qui est principalement utilisé pour le plaisir. Je télécharge des images, des vidéos et du texte que je souhaite partager. Un formulaire de soumission HTML accepte les questions et les soumissions de chaînes des utilisateurs, qui utilise une phpmyadmintable de base de données pour le stockage.

L'extrait ci-dessous est mon .htaccessfichier actuel .https://gtmetrix.com/ note que les redirections sont le principal responsable du ralentissement du chargement de mes pages, mais je ne sais pas comment les rationaliser.

RewriteEngine On

#REDIRECT TO SECURE HTTPS CONNECTION
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] #FORCE WWW TO NON-WWW RewriteCond %{HTTP_HOST} ^www.MYDOMAIN.com [NC] RewriteRule ^(.*)$ https://MYDOMAIN.com/$1 [L,R=301] #URL EXTENSION REMOVAL RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC] RewriteRule ^ /%1 [NC,L,R] RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^ %{REQUEST_URI}.html [NC,L] #HOTLINKING PROTECTION #NOTE: having |html| and |htm| included prevented access of the site through browser search, so i removed them. RewriteCond %{HTTP_REFERER} !^https://(www\.)?MYDOMAIN\.com(/.*)*$ [NC]
RewriteCond %{HTTP_REFERER} !^$ RewriteRule \.(css|flv|gif|ico|jpe|jpeg|jpg|js|mp3|mp4|php|png|pdf|swf|txt)$ - [F]

#CONTENT SECURITY POLICY
<FilesMatch "\.(html|php)$"> Header set Content-Security-Policy "default-src 'self'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: 'unsafe-inline'; media-src 'self' data: 'unsafe-inline'; connect-src 'self';" </FilesMatch> #REDIRECT FOR DATE PAGE Redirect /date /storage/date-202010 #REDIRECT FOR HOME PAGE Redirect /home / #CUSTOM ERROR PAGES ErrorDocument 400 /allerror.php ErrorDocument 401 /allerror.php ErrorDocument 403 /allerror.php ErrorDocument 404 /allerror.php ErrorDocument 405 /allerror.php ErrorDocument 408 /allerror.php ErrorDocument 500 /allerror.php ErrorDocument 502 /allerror.php ErrorDocument 504 /allerror.php #PREVENT DIRECTORY BROWSING Options All -Indexes #FILE CACHING #cache html and htm files for one day <FilesMatch "\.(html|htm)$">
Header set Cache-Control "max-age=43200"
</FilesMatch>
    #cache css, javascript and text files for one week
<FilesMatch "\.(js|css|txt)$"> Header set Cache-Control "max-age=604800" </FilesMatch> #cache flash and images for one month <FilesMatch "\.(flv|swf|ico|gif|jpg|jpeg|mp4|png)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
    #disable cache for script files
<FilesMatch "\.(pl|php|cgi|spl|scgi|fcgi)$"> Header unset Cache-Control </FilesMatch> #BLOCKS FILE TYPES FOR USERS <FilesMatch "\.(htaccess|htpasswd|ini|log|sh|inc|bak)$">
Order Allow,Deny
Deny from all
</FilesMatch>

MISE À JOUR

J'ai créé un nouveau poste intégrant un HSTS et plusieurs des changements recommandés par M. White. La prime a été décernée. Veuillez adresser tout autre commentaire au New Post .

Réponses

4 MrWhite Oct 15 2020 at 23:17

https://gtmetrix.com/ note que les redirections sont le principal responsable du ralentissement du chargement de mes pages

La "suggestion" de gtmetrix.com à cet égard est sans doute "incorrecte" (ou plutôt pas aussi sérieuse qu'elle l'implique), en supposant que vous liez déjà systématiquement à l'URL canonique * 1 de votre site (et que vous n'avez pas d'autres redirections dans votre code d'application). Ces redirections n'affecteront probablement qu'une «très petite fraction» des visiteurs de votre site lors de leur toute première visite.

( * 1 URL canonique étant HTTPS + non-www + pas d' .htmlextension.)

Vous avez 3 redirections externes dans le .htaccesscode que vous avez posté:

#REDIRECT TO SECURE HTTPS CONNECTION
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] #FORCE WWW TO NON-WWW RewriteCond %{HTTP_HOST} ^www.example.com [NC] RewriteRule ^(.*)$ https://example.com/$1 [L,R=301]

#URL EXTENSION REMOVAL
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]

Si vous avez implémenté HSTS, vous devez rediriger de HTTP vers HTTPS sur le même hôte, avant de canoniser le sous-domaine www - ce que vous faites ci-dessus dans la première règle. C'est une exigence du HSTS et de la "liste de préchargement". Vous ne pouvez donc pas éviter d'avoir au moins 2 redirections (pire des cas) dans ce scénario.

Cependant, si vous n'avez pas l'intention d'implémenter HSTS, vous pouvez combiner les deux premières redirections en une seule. Ce que vous pouvez faire en inversant simplement l'ordre des deux premières règles. Par exemple:

#FORCE WWW TO NON-WWW
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

#REDIRECT TO SECURE HTTPS CONNECTION
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

La première règle, qui redirige www vers non-www, redirige également vers HTTPS, il n'est donc jamais nécessaire d'exécuter la deuxième redirection. Donc, il n'y a qu'une seule redirection pour canoniser HTTPS et non-www.

J'ai également supprimé le sous-modèle de capture redondant (c'est-à-dire (.*)) dans le RewriteRule modèle "HTTP vers HTTPS" , puisque vous utilisez la REQUEST_URIvariable serveur à la place. Et changé l'autre redirection "www vers non-www" pour être cohérente. Notez que la REQUEST_URIvariable serveur contient le chemin d'accès URL complet, y compris le préfixe barre oblique, tandis que la référence arrière capturée omet le préfixe barre oblique.

Les deux règles ci-dessus pourraient être combinées en une seule règle (légèrement plus complexe), mais il n'y a aucun avantage à le faire.

Les règles pourraient également être rendues plus "génériques", sans avoir à énoncer explicitement le nom d'hôte canonique. Cependant, la façon dont vous implémentez cela et si cela est facilement possible dépend du fait que vous ayez ou non d'autres sous-domaines. Mais encore une fois, cela ne sert aucun "avantage", autre que d'être plus copiable / collable. Généralement, il est préférable d'être explicite ici - moins sujet à l'erreur.

#URL EXTENSION REMOVAL
RewriteCond %{THE_REQUEST} /([^.]+)\.html [NC]
RewriteRule ^ /%1 [NC,L,R]

Vous pouvez également éviter que la .html"redirection de suppression d'extension" ne déclenche une redirection supplémentaire en incluant d'abord cette redirection (avant les deux redirections canoniques ci-dessus) et en redirigeant directement vers HTTPS et non-www (le schéma canonique + nom d'hôte) dans le cadre de la redirection.

MISE À JOUR: Cela devrait également être une redirection 301 (permanente), pas une redirection 302 (temporaire) qu'elle est actuellement. Une redirection 301 est mise en cache par le navigateur par défaut, ce qui évite les allers-retours inutiles vers le serveur. Lorsque vous n'incluez pas explicitement le code d'état avec l' Rindicateur, la valeur par défaut est 302.

L' NCindicateur n'est pas non plus requis sur la RewriteRuledirective, car vous ne correspondez à aucun élément sensible à la casse.

Cette règle de suppression de l' .htmlextension fonctionne probablement bien pour vos URL, cependant, elle n'est pas nécessairement correcte et pourrait éventuellement être rendue plus efficace. La raison de la vérification par rapport à la THE_REQUESTvariable serveur, par opposition au RewriteRule modèle ou à la REQUEST_URIvariable serveur, est d'éviter une boucle de redirection potentielle en empêchant les demandes réécrites d'être redirigées. Cela est dû au THE_REQUESTfait que ne change pas après la réécriture de la requête - il contient la première ligne des en-têtes de requête HTTP. Cependant, THE_REQUESTcontient également la chaîne de requête, il est donc possible qu'une requête légitime qui contient .htmldans le cadre de la chaîne de requête soit incorrectement redirigée.

Par exemple, request example.com/?p1=foo.html&p2=bar(la page d'accueil avec une chaîne de requête et des paramètres d'URL contenant la valeur foo.html) et celle-ci sera incorrectement redirigée vers example.com/?p1=foo, tronquant la chaîne de requête.

L'expression régulière /([^.]+)\.htmlne correspondra pas non plus à toute URL contenant des points dans le cadre du chemin d'URL à des endroits autres que l'extension de fichier. par exemple. Une demande de /foo.bar.htmlne serait pas redirigée. Bien que cela puisse parfaitement convenir aux URL de votre site.

Pour éviter ces redirections "incorrectes", vous pouvez capturer le chemin URL du RewriteRule modèle à la place et soit utiliser une condition plus simple et vérifier THE_REQUEST(pour éviter une boucle) ou utiliser la REDIRECT_STATUSvariable d'environnement à la place, qui est toujours vide sur les demandes directes.

Par exemple:

#URL EXTENSION REMOVAL
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule (.+)\.html$ https://example.com/$1 [NC,R=301,L]

Cela capture le chemin d'URL avant l' .htmlextension de fichier en utilisant le RewriteRule modèle (qui exclut naturellement la chaîne de requête). La simple condition qui vérifie la variable d' REDIRECT_STATUSenvironnement empêche une boucle de redirection.

En réunissant les points ci-dessus, nous avons:

#URL EXTENSION REMOVAL
RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule (.+)\.html$ https://example.com/$1 [NC,R=301,L]

#FORCE WWW TO NON-WWW
RewriteCond %{HTTP_HOST} ^www\.example\.com [NC]
RewriteRule ^ https://example.com%{REQUEST_URI} [L,R=301]

#REDIRECT TO SECURE HTTPS CONNECTION
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

L' NCindicateur n'était pas requis dans la redirection "Suppression de l'extension d'URL".

Cela déclenche désormais au plus 1 redirection, que la requête arrive pour HTTP, www ou inclut l' .htmlextension. Cependant, comme indiqué, cela se fait au détriment du non-respect des exigences du HSTS.

Et il convient de noter qu'en termes réels, il peut ne pas y avoir de différence perceptible entre 1, 2 ou même 3 redirections ici. D'autant que cela n'affectera de toute façon pas la grande majorité des visiteurs.


Additionnel:

#REDIRECT FOR DATE PAGE
Redirect /date /storage/date-202010

#REDIRECT FOR HOME PAGE
Redirect /home /

Généralement, vous devriez éviter de mélanger les redirections de mod_alias ( Redirect/ RedirectMatch) et mod_rewrite ( RewriteRule). Les deux modules fonctionnent indépendamment et à des moments différents pendant la requête, malgré l'ordre apparent des directives dans le .htaccessfichier. mod_rewrite s'exécute en premier. Ainsi, vous pouvez avoir des conflits inattendus.

Notez également qu'il Redirects'agit d'une correspondance de préfixe et que tout ce qui suit la correspondance est ajouté à la fin de l'URL cible. par exemple. /date/fooserait redirigé vers /storage/date-202010/foopar la première règle. Ces redirections particulières sont également 302 redirections (temporaires). On dirait qu'ils devraient être 301 (permanents)?

Cependant, dans ce cas, peu importe que vous utilisiez Redirectou RewriteRule, mais en règle générale, si vous utilisez mod_rewrite pour certaines redirections, utilisez mod_rewrite pour toutes les redirections. Par exemple:

#REDIRECT FOR DATE PAGE
RewriteRule ^date$ /storage/date-202010 [R=301,L]

#REDIRECT FOR HOME PAGE
RewriteRule ^home$ / [R=301,L]

#BLOCKS FILE TYPES FOR USERS
<FilesMatch "\.(htaccess|htpasswd|ini|log|sh|inc|bak)$">
Order Allow,Deny
Deny from all
</FilesMatch>

Vous avez indiqué dans les commentaires que vous utilisez Apache 2.4, cependant Order, Allowque vous Denyêtes des directives Apache 2.2 et que vous êtes anciennement obsolète sur Apache 2.4. Ils fonctionnent toujours, mais uniquement à des fins de compatibilité ascendante et devraient être mis à jour dès que possible.

Notez que vous devez mettre à jour toutes les instances de votre système car les nouvelles directives ne se mélangent pas nécessairement bien.

Sur Apache 2.4, vous utiliseriez la Requiredirective à la place:

#BLOCKS FILE TYPES FOR USERS
<FilesMatch "\.(ht[ap]|ini|log|sh|inc|bak)$">
Require all denied
</FilesMatch>

Notez que la configuration du serveur Apache "devrait" déjà bloquer l'accès direct aux fichiers .htaccesset .htpasswd, mais il vaut mieux être sûr, je suppose.


ErrorDocument 500 /allerror.php

Définir 500 ErrorDocument fin dans .htaccessest probablement trop tard pour attraper la plupart des 500 réponses (erreur interne du serveur) (ce résultat de mauvaises configurations ). Vous ne pouvez probablement pas faire grand-chose à ce sujet, mais il serait préférable de définir cela plus tôt dans la configuration du serveur (ou le <VirtualHost>conteneur) afin d'être plus "utile".