Liste de contrôle de déploiement

Internet est un environnement hostile. Avant de déployer votre projet Django, il est recommandé de passer du temps à vérifier les réglages en ayant à l’esprit la sécurité, la performance et les opérations.

Django contient beaucoup de fonctionnalités liées à la sécurité. Certaines sont intégrées et toujours actives. D’autres sont facultatives car elles ne sont pas toujours adéquates ou parce qu’elles ne conviennent pas durant le développement. Par exemple, l’utilisation exclusive de HTTPS ne convient pas à tous les sites Web et ce n’est pas réaliste lors du développement local.

Les optimisations de performance sont une autre catégorie de compromis entre efficacité et commodité. Par exemple, l’utilisation de cache est utile en production, beaucoup moins lors du développement local. Les besoins en terme de signalement d’erreurs sont aussi très différents.

La liste de contrôle suivante contient des réglages qui :

  • doivent être configurés correctement pour que Django puisse garantir le niveau de sécurité attendu ;

  • sont généralement différents en fonction de chaque environnement ;

  • activent des fonctionnalités de sécurité facultatives ;

  • activent des optimisations de performance ;

  • s’occupent du signalement des erreurs.

Beaucoup de ces réglages sont sensibles et doivent être traités de manière confidentielle. Si vous publiez le code source de votre projet, une pratique courante est de publier des réglages convenant au développement, mais d’utiliser un module de réglages privés à destination de la production.

Lancer manage.py check --deploy

Certains des contrôles présentés ci-dessous peuvent être automatisés en utilisant l’option --deploy. Prenez garde de la lancer en activant le fichier de réglages de production comme décrit dans la documentation de l’option.

Se débarrasser de manage.py runserver

La commande runserver n’est pas conçue pour un système en production. Orientez-vous vers un serveur WSGI ou ASGI adapté pour la production. Vous pouvez consulter un certain nombre de choix fréquents dans serveurs WSGI ou serveurs ASGI.

Réglages critiques

SECRET_KEY

La clé secrète doit être une longue valeur aléatoire et doit rester confidentielle.

Assurez-vous que la clé utilisée en production n’est employée nulle part ailleurs et ne l’ajoutez pas dans le système de gestion de versions. Cela réduit le nombre de vecteurs par lesquels un attaquant pourrait trouver la clé.

Au lieu d’inscrire statiquement la clé secrète dans votre module de réglages, envisagez de la charger à partir d’une variable d’environnement :

import os

SECRET_KEY = os.environ["SECRET_KEY"]

ou à partir d’un fichier :

with open("/etc/secret_key.txt") as f:
    SECRET_KEY = f.read().strip()

Si vous faites une rotation des clés secrètes, vous pouvez utiliser le réglage SECRET_KEY_FALLBACKS:

import os

SECRET_KEY = os.environ["CURRENT_SECRET_KEY"]
SECRET_KEY_FALLBACKS = [
    os.environ["OLD_SECRET_KEY"],
]

Assurez-vous d’effacer les anciennes clés secrètes de SECRET_KEY_FALLBACKS au temps opportun.

DEBUG

Vous ne devez jamais activer ``DEBUG`` en production.

Vous développez certainement votre projet avec DEBUG = True, car cela offre des possibilités bien pratiques comme les traces d’appel détaillées dans votre navigateur.

Dans un environnement de production, cependant, c’est une très mauvaise idée, parce que cela révèle de nombreuses informations sur votre projet : extraits de code source, variables locales, réglages, bibliothèques utilisées, etc.

Réglages spécifiques à l’environnement

ALLOWED_HOSTS

Lorsque DEBUG = False, Django ne fonctionne pas du tout sans une valeur correcte de ALLOWED_HOSTS.

Ce réglage est obligatoire pour protéger votre site contre certaines attaques CSRF. Si vous indiquez un caractère générique, vous devez effectuer vous-même la validation de l’en-tête HTTP Host, ou sinon vous assurer que vous n’êtes pas vulnérable à cette catégorie d’attaques.

Il s’agit également de configurer le serveur Web placé devant Django pour valider l’hôte. En cas de requêtes avec des noms d’hôte incorrects, le serveur Web devrait répondre avec une page d’erreur statique ou ignorer ces requêtes au lieu de les transférer vers Django. De cette façon, cela évitera de polluer les journaux de Django avec des erreurs (ou des courriels si vous avez configuré le signalement d’erreur par ce biais). Par exemple avec nginx, il est possible de configurer le serveur afin qu’il renvoie par défaut des erreurs « 444 No Response » s’il détecte un hôte inconnu :

server {
    listen 80 default_server;
    return 444;
}

CACHES

Si vous utilisez du cache, les paramètres de connexion peuvent être différents entre le développement et la production. Par défaut, Django utilise le cache en mémoire locale, ce qui n’est pas toujours le plus approprié.

Les serveurs de cache ont souvent une faible authentification. Assurez-vous qu’ils n’acceptent de connexions que de vos serveurs d’applications.

DATABASES

Les paramètres de connexion à la base de données sont probablement différents entre le développement et la production.

Les mots de passe de base de données sont très sensibles. Vous devez les protéger aussi bien que SECRET_KEY.

Pour une sécurité maximale, assurez-vous que les serveurs de bases de données n’acceptent des connexions que de vos serveurs d’applications.

Si vous n’avez pas configuré de sauvegardes pour votre base de données, faites-le maintenant !

STATIC_ROOT et STATIC_URL

Les fichiers statiques sont servis automatiquement par le serveur de développement. En production, vous devez définir un répertoire STATIC_ROOT dans lequel collectstatic va copier les fichiers.

Voir Gestion des fichiers statiques (par ex. images, JavaScript, CSS) pour plus d’informations.

MEDIA_ROOT et MEDIA_URL

Les fichiers « média » sont téléversés par vos utilisateurs. Vous ne devez pas leur faire confiance ! Vérifiez que votre serveur Web n’essaie jamais de les interpréter. Par exemple, si un utilisateur téléverse un fichier .php, le serveur Web ne doit jamais l’exécuter.

C’est maintenant le moment favorable de vérifier votre stratégie de sauvegarde pour ces fichiers.

HTTPS

Tout site Web autorisant des utilisateurs à se connecter devrait imposer l’accès HTTPS généralisé pour éviter de transmettre des jetons d’accès en clair. Dans Django, les jetons d’accès contiennent l’identifiant et le mot de passe, le cookie de session et les jetons de réinitialisation de mot de passe (vous ne pouvez guère mieux protéger les jetons de réinitialisation de mot de passe si vous les envoyer par courriel).

La protection de zones sensibles comme les comptes des utilisateurs ou l’interface d’administration n’est pas suffisant, car le même cookie de session est utilisé à la fois pour HTTP et HTTPS. Votre serveur Web doit rediriger tout le trafic HTTP vers HTTPS et ne transmettre que les requêtes HTTPS à Django.

Après avoir configuré HTTPS, activez les réglages suivants.

Optimisations de performance

La configuration de DEBUG = False désactive plusieurs fonctionnalités qui ne sont utiles qu’en cours de développement. De plus, vous pouvez affiner les réglages suivants.

Sessions

Envisagez l’utilisation de sessions en cache pour améliorer les performances.

Si vous utilisez des sessions stockées en base de données, ref:effacez régulièrement les anciennes sessions <clearing-the-session-store> afin d’éviter de stocker des données inutiles.

CONN_MAX_AGE

L’activation des connexions persistantes à la base de données peut significativement améliorer les performances quand la connexion à la base de données constitue une part importante du temps de traitement des requêtes.

C’est un plus important sur des hôtes virtualisés dont la performance réseau est limitée.

TEMPLATES

L’activation du cache des chargeurs de gabarits améliore souvent les performances de manière très importante, car cela évite de devoir recompiler les gabarits lors de chacun de leurs rendus. Lorsque DEBUG = False, le chargeur de gabarits en cache est activé automatiquement. Voir django.template.loaders.cached.Loader pour plus d’informations.

Signalement d’erreurs

Au moment de passer votre code en production, il est censé être robuste, mais on ne peut jamais exclure des erreurs inattendues. Heureusement, Django peut capturer les erreurs et vous en avertir.

LOGGING

Analysez votre configuration de la journalisation avant de mettre votre site Web en production et contrôlez qu’elle fonctionne comme prévu dès que l’application commence à recevoir du trafic.

Consultez Journalisation pour plus de détails sur la journalisation.

ADMINS et MANAGERS

Les ADMINS sont avertis par courriel des erreurs de type 500.

Les MANAGERS sont avertis des erreurs 404. IGNORABLE_404_URLS peut aider à filtrer les signalements inopportuns.

Consultez Gestion du signalement des erreurs pour plus de détails sur le signalement d’erreurs par courriel.

Le signalement d’erreurs par courriel n’est pas adapté au fort trafic

Considérez l’emploi d’un système de surveillance d’erreurs tel que Sentry avant de voir votre boîte de réception inondée de messages. Sentry peut aussi collecter la journalisation.

Personnalisation des vues d’erreurs par défaut

Django inclut des vues et des gabarits par défaut pour plusieurs codes d’erreurs HTTP. Il peut être souhaitable de remplacer les gabarits par défaut en créant les gabarits suivants dans votre répertoire de gabarits racine : 404.html, 500.html, 403.html et 400.html. Les vues d’erreur par défaut qui utilisent ces gabarits devraient convenir à 99 % des applications Web, mais vous pouvez très bien les adapter aussi.

Back to Top