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.

Lancez 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.

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()

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.

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

Si vous utilisez Memcached, envisagez l’utilisation de sessions en cache pour améliorer les performances.

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.

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. Consultez la documentation sur les chargeurs de gabarits 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 Signalement d’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 par défaut devraient convenir à 99 % odes applications Web, mais si vous souhaitez les adapter, consultez ces instructions qui contiennent également des détails à propos des gabarits par défaut :

Options de Python

Il est fortement recommandé d’appeler le processus Python exécutant votre application Django en utilisant l’option -R ou avec la variable d’environnement PYTHONHASHSEED définie à random (aléatoire). Cette option est présente par défaut à partir de la version 3.3 de Python.

Ces options contribuent à la protection de votre site contre les attaques de déni de service (DoS) produites par des entrées soigneusement contrefaites. Une telle attaque peut augmenter de manière substantielle l’utilisation du processeur en provoquant les moins bonnes performances possibles lors de la création d’instances de dict. Voir la mise en garde oCERT n°2011-003 pour plus d’informations.

Back to Top