Prendre un thé
Tapoter des doights
Monsieur fantôme
Quelle heure est-il ?
BazinGa's Tips & tuto IT
BazinGa's - Tips & tuto IT

HTACCESS/Config Apache – Quelques éléments de sécurisation et d’optimisation

Lorsque l’on conçoit un site internet, la question de la sécurité se pose et en premier lieu la mise en place d’un certificat HTTPS. Cependant, il est possible de faire bien plus que de simplement sécuriser la connexion. La configuration du serveur Apache (ou du fichier .htaccess pour les hébergements mutualisés) permet d’augmenter le niveau de sécurité du site web et d’optimiser sa consultation en optimisant les ressources consommées par l’utilisation de celui-ci.

Cet article condense un ensemble de règles à mettre en place pour sécuriser, mettre en cache et compresser les requêtes d’un site.

Sécurité

Au delà de la mise en place d’un certificat HTTPS, plusieurs règles permettent de vraiment sécuriser un site internet.

# Forcer la redirection vers HTTPS
<IfModule mod_rewrite.c>
	RewriteEngine On
	RewriteCond %{HTTPS} !=on
	RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</IfModule>


# Protections diverses
<ifModule mod_headers.c>
	# Indiquer aux navigateur que le site doit toujours être contacté en HTTPS
	# Durée de validité en secondes :
	#	1 heure : 3600
	#	6 heures : 21600
	#	12 heures : 43200
	#	24 heures : 86400
	#	48 heures : 172800
	#	1 semaine : 604800
	#	1 mois : 2592000
	#	6 mois : 15552000
	#	1 an : 31536000
	Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

	# Empêcher les attaques cross-site scripting
	Header set X-XSS-Protection "1; mode=block"

	# Interdire l'utilisation du site dans des iframes en dehors du domaine courant
	Header always append X-Frame-Options SAMEORIGIN

	# Interdire le sniffing du type MIME par les navigateurs
	Header set X-Content-Type-Options "nosniff"

	# Politique de sécurité du site
	# Il s'agit d'indiquer l'origine des ressources qui peuvent être utiliser par le site
	# Plus d'info ici :
	#	https://developer.mozilla.org/fr/docs/Web/HTTP/Headers/Content-Security-Policy
	#	https://content-security-policy.com/
	#	https://www.magentix.fr/blog/strategie-de-securite-du-contenu-content-security-policy.html
	Header set Content-Security-Policy " \
		upgrade-insecure-requests; \
		\
		default-src		'self'	https://*.arthurbazin.com; \
		script-src		'self'	https://*.arthurbazin.com; \
		style-src		'self'	https://*.arthurbazin.com; \
		img-src			'self'	https://*.arthurbazin.com; \
		media-src		'self'	https://*.arthurbazin.com; \
		font-src		'self'	https://*.arthurbazin.com; \
		\
		child-src		'self'	https://*.arthurbazin.com; \
		frame-src		'self'	https://*.arthurbazin.com; \
		\
		base-uri		'self'	https://*.arthurbazin.com; \
		form-action		'self'	https://*.arthurbazin.com; \
		\
		object-src		'self'	https://*.arthurbazin.com; \
		connect-src		'self'	https://*.arthurbazin.com; \
		"

	# Politique d'envoie des referrer
	Header always set Referrer-Policy "strict-origin-when-cross-origin"

</ifModule>



# Masquer les informations du serveur
ServerSignature Off

# Désactiver l'easter egg permettant d'afficher des infos sur PHP (arthurbazin.com/?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000)
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]
RewriteRule .* - [F]

# Désactiver l'affichage du contenu des répertoires
Options -Indexes

# Activation du suivi des liens symboliques
Options +FollowSymLinks

# Désactiver l'utilisation des images sur un autre site web
# Plus d'info sur l'image utilisée sur https://fakeimg.pl
<IfModule mod_rewrite.c>
	RewriteCond %{HTTP_REFERER} !^$
	RewriteCond %{HTTP_REFERER} !^http(s)?://(.*\.)?arthurbazin.(com|local) [NC]
	RewriteRule \.(jpg|jpeg|png|gif)$ "https://fakeimg.pl/800x600/0090ff/ffffff/?text=BazinGa's - https://blog.arthurbazin.com&font_size=50" [NC,R,L]
</IfModule>

Mise en cache

Afin de réduire le nombre de requêtes faites entre le navigateur et le serveur, ce dernier peut indiquer aux clients de mettre en cache les ressources du site.

# Excellente aide : https://csswizardry.com/2019/03/cache-control-for-civilians/

<IfModule mod_expires.c>

	# Définition de l'en-tête "Expires" et de la valeur "max-age" de l'en-tête "Cache-Control"
	ExpiresActive On
	ExpiresDefault "access plus 1 week"

	ExpiresByType text/html					"access plus 0 seconds"
	ExpiresByType application/xhtml+xml			"access plus 0 seconds"
	ExpiresByType text/xml					"access plus 0 seconds"
	ExpiresByType application/xml				"access plus 0 seconds"

	ExpiresByType application/rss+xml			"access plus 1 hour"
	ExpiresByType application/atom+xml			"access plus 1 hour"

	ExpiresByType text/css					"access plus 1 week"
	ExpiresByType text/javascript				"access plus 1 week"
	ExpiresByType application/javascript			"access plus 1 week"
	ExpiresByType application/x-javascript			"access plus 1 week"
	ExpiresByType text/json					"access plus 1 week"
	ExpiresByType application/json				"access plus 1 week"

	ExpiresByType font/ttf					"access plus 1 month"
	ExpiresByType application/x-font-ttf			"access plus 1 month"
	ExpiresByType font/woff					"access plus 1 month"
	ExpiresByType application/x-font-woff			"access plus 1 month"
	ExpiresByType font/woff2				"access plus 1 month"
	ExpiresByType application/x-font-woff2			"access plus 1 month"
	ExpiresByType font/opentype				"access plus 1 month"
	ExpiresByType application/vnd.ms-fontobject		"access plus 1 month"

	ExpiresByType image/jpg					"access plus 1 month"
	ExpiresByType image/jpeg				"access plus 1 month"
	ExpiresByType image/gif					"access plus 1 month"
	ExpiresByType image/png					"access plus 1 month"
	ExpiresByType image/webp				"access plus 1 month"
	ExpiresByType image/svg+xml				"access plus 1 month"
	ExpiresByType image/x-icon				"access plus 1 month"
	ExpiresByType image/ico					"access plus 1 month"
	ExpiresByType image/icon				"access plus 1 month"
	
	ExpiresByType application/pdf				"access plus 1 month"

	ExpiresByType video/ogg					"access plus 1 month"
	ExpiresByType video/mp4					"access plus 1 month"
	ExpiresByType video/webm				"access plus 1 month"

	ExpiresByType audio/ogg					"access plus 1 month"
	ExpiresByType audio/mp3					"access plus 1 month"

</IfModule>

<ifModule mod_headers.c> 
	
	# Directive de gestion du cache
	# On surcharge l'en-tête "Cache-Control" défini précédemment
	# "private" : les fichiers ne peuvent être mis en cache que par le client
	# "public" : les fichiers peuvent être mis en cache par les intermédiaires
	# "no-store" : pas de cache
	# "no-cache" : mise en cache avec requête de validation à chaque appel
	# "must-revalidate, max-age=xx" : mise en cache avec requête de validation après xx seconde
	# "stale-while-revalidate=xx" : si le fichier en cache est périmé, on peut encore l'utiliser pendant xx seconde, le temps de renouveler le cache
	# "stale-if-error=xx" : si le renouvellement du fichier en cache entraine une erreur 5xx, on peut encore utiliser le fichier en cache pendant xx seconde, le temps de le renouveler.

	# Durée de cache en secondes :
	#	1 heure : 3600
	#	6 heures : 21600
	#	12 heures : 43200
	#	24 heures : 86400
	#	48 heures : 172800
	#	1 semaine : 604800
	#	1 mois : 2592000
	#	6 mois : 15552000
	#	1 an : 31536000
	
	# les fichiers dynamiques ne sont pas mis en cache
	<FilesMatch "\.(pl|cgi|spl|scgi|fcgi)$">
		Header set Cache-Control "private, no-store"
	</FilesMatch>

	<filesMatch "\.(xhtml|html|xml|php)$">
		Header set Cache-Control "private, no-cache"
	</filesMatch>

	<filesMatch "\.(css|js|json)$">
		Header set Cache-Control "public, must-revalidate, max-age=604800"
	</filesMatch>

	<filesMatch "\.(eot|ttf|woff|woff2)$">
		Header set Cache-Control "public, must-revalidate, max-age=2592000"
	</filesMatch>

	<filesMatch "\.(jpeg|jpg|gif|png|webp|svg|ico)$">  
		Header set Cache-Control "public, must-revalidate, max-age=2592000"
	</filesMatch>

	<filesMatch "\.(pdf)$">  
		Header set Cache-Control "public, must-revalidate, max-age=2592000"
	</filesMatch>

	<filesMatch "\.(ogg|mp4|webm)$">  
		Header set Cache-Control "public, must-revalidate, max-age=2592000"
	</filesMatch>

	<filesMatch "\.(ogg|mp3)$">  
		Header set Cache-Control "public, must-revalidate, max-age=2592000"
	</filesMatch>

</ifModule>

# Suppression des ETAG
# Pour éviter des requêtes de revalidation
Header unset ETag
FileETag None

Compression

Pour accélérer les échanges client-serveur, il est possible de mettre en place une compression des données.

<IfModule mod_deflate.c> 

	# Création d'un nouveau filtre de sortie Apache
	FilterDeclare	COMPRESS

	# Ajout des directives au filtre
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/plain'"

	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/html'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/xhtml'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/xml'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/xhtml+xml'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/xml'"

	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/rss+xml'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/atom+xml'"

	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/css'"

	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/javascript'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/javascript'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/x-javascript'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/json'"

	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'text/x-component'"
	
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/vnd.ms-fontobject'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'application/x-font-ttf'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'font/opentype'"

	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'image/x-icon'"
	FilterProvider	COMPRESS	DEFLATE	"%{Content_Type} = 'image/svg+xml'"

	# Chainage des filtre à la sortie
	FilterChain	+COMPRESS
	
	# Validation de la mise à jour des en-têtes HTTP suite à l'utilisation du filtre
	FilterProtocol	COMPRESS	DEFLATE	change=yes;byteranges=no

	# N'utiliser que certaines compression pour les navigateurs incompatibles
	BrowserMatch ^Mozilla/4 gzip-only-text/html 
	BrowserMatch ^Mozilla/4\.0[678] no-gzip 
	BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
	BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html 

	# Nee pas compresser les images
	SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary 

	# Les proxies doivent transmettre le bon contenu
	<IfModule mod_headers.c>
		Header append Vary User-Agent env=!dont-vary
	</IfModule>

</IfModule>

Sécurisation dédiées à WordPress

Il est possible d’ajouter quelques règles dédiées à WordPress.

# Protéger le fichier wp-config.php
<files wp-config.php>
	order allow,deny
	deny from all
</files>

# Protéger les fichiers .htaccess et .htpasswds
<Files ~ "^.*\.([Hh][Tt][AaPp])">
	order allow,deny
	deny from all
	satisfy all
</Files>

# Éviter le spam de commentaires
<IfModule mod_rewrite.c>
	RewriteCond %{REQUEST_METHOD} POST
	RewriteCond %{REQUEST_URI} .wp-comments-post\.php*
	RewriteCond %{HTTP_REFERER} !.blog.arthurbazin.com.* [OR]
	RewriteCond %{HTTP_USER_AGENT} ^$
	RewriteRule (.*) ^http://%{REMOTE_ADDR}/$ [R=301,L]
</IfModule>

# Éviter que l'on découvre l'identifiant d'un auteur
<IfModule mod_rewrite.c>
	RewriteCond %{QUERY_STRING} ^author=([0-9]*)
	RewriteRule .* - [F]
</IfModule>

# Bloquer l'utilisation de certains scripts
<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>


Cet article vous a plu ?

N'hésitez pas à le partager, il interessera surement certains de vos contacts.

Les thèmes suivants contiennent des articles en lien avec celui-ci, allez faire un tour :

IT apachecachehstshttpsserveur

50%