Sans doute un peu influencé par cette (vieille) campagne “HTTPS Now” ou par le projet “HTTPS Everywhere”, j’ai entamé une migration de HTTP vers HTTPS sur l’ensemble de mes sites. Et cela inclut même ceux qui sont purement personnels, tel que celui-ci.

PRISM n’y est pour rien, rassurez-vous, d’autant que ça ne devrait pas vraiment gêner les oreilles de la NSA plus que ça. Ma démarche s’inscrit dans un contexte bien plus concret, terre-à-terre, quotidien, etc. : l’usage mobile et l’intégrité du contenu.

Non, je n’ai pas (entièrement) perdu la raison.

Il est évident qu’il n’est pas véritablement question de confidentialité des données échangées lorsque vous et moi consultons ce site. Je ne vous demande pas (encore ?) vos informations de carte bancaire, ni quoi que ce soit de personnel. Mais je veux être sûr que vous recevrez et lirez bien ce que je publie et non une version altérée en chemin, à notre insu, soit par votre opérateur de réseau cellulaire, soit par le relai WiFi gratuit que vous êtes en train d’utiliser.

N’étant expert ni en chiffrement, ni en sécurité, je me suis contenté de faire confiance aux documentations et articles divers disponibles sur le Web pour établir la configuration de mon serveur Nginx (une liste non exhaustive est disponible en fin de billet). Au final, obtenir quelque chose d’acceptable est relativement simple et ne nécessite pas d’être un apprenti sorcier.

NB : l’ensemble des directives de configuration mentionnées par la suite prennent place dans un bloc

server {
}

Commençons par le strict minimum

À savoir activer le support de SSL dans la configuration de votre serveur (en partant, bien évidemment, du principe que vous avez fait le nécessaire pour récupérer un certificat SSL).

Si vous utilisez un package précompilé obtenu soit depuis les dépôts de votre distribution, soit depuis le dépôt officiel du projet Nginx, le support de SSL est déjà embarqué. Il suffit donc d’indiquer que nous souhaitons l’utiliser et configurer notre hôte en conséquence.

listen 443 ssl;
ssl on;
ssl_certificate /le/chemin/vers/votre.pem;
ssl_certificate_key /le/chemin/vers/votre.key;

En prenant soin d’avoir assuré une chaine de certificats correcte, cf. “Configuring HTTPS servers - SSL certificate chains”.

Assurons-nous de ne pas pisser dans un violon

Le but étant de servir le site par HTTPS et HTTPS seulement (ou presque…), autant l’indiquer clairement aux navigateurs. Une redirection initiale de l’ensemble du trafic HTTP vers une distribution par HTTPS se fera à l’aide d’une simple règle de réécriture (que je ne mentionne pas ici). Pour les navigateurs “modernes”, le recours à HTTP Strict Transport Security est mis en place. Comme mon but est principalement de ne pas voir mon contenu sauvagement altéré ou détourné, l’ajout d’en-tête X-Frame-Options adéquat ira de pair.

add_header Strict-Transport-Security max-age=31536000;
add_header X-Frame-Options DENY;

Essayons d’accélérer ce petit monde

J’espère que vous avez bien gardé à l’esprit que mon but n’étant de faire de ce site un pseudo Fort Knox. Si certains qualifient la surcharge induite par HTTPS comparée à HTTP de “mythe”, elle me parait tout de même bien réelle, surtout lorsqu’on emploie les algorithmes de chiffrement les plus aboutis. Le moment est donc venu de faire quelques compromis, histoire de garantir des temps de réponse satisfaisants.

Pour cela, il faut tailler un peu dans la masse des chiffrements négociés

ssl_prefer_server_ciphers on;
ssl_ciphers AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:RC4:HIGH:!MD5:!aNULL:!EDH;

et faire en sorte de limiter les renégociations et leur impact.

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

Et si, comme moi, votre Nginx embarque le support de SPDY et dispose de la version OpenSSL “qui-va-bien”, ça ne coûte rien de l’activer. Dès lors, la directive listen précédemment traitée devient :

listen 443 ssl spdy;

Nous y sommes

Le compromis obtenu semble faire ce que j’attends de lui : fournir un certain niveau de confiance, sans pénaliser outre mesure les performances et les temps d’accès.

Quand j’évoque le “niveau de confiance”, je parle simplement d’une mise en œuvre fiable de HTTPS, que je teste (bêtement ?) grâce au service “SSL Server Test“.

Avec la configuration retenue, si mon modeste carnet n’obtiendra jamais la médaille d’or du chiffrement absolu, il s’en sort néanmoins avec les honneurs.

Une poignée de liens pour la route

Si le sujet vous intéresse, je vous livre quelques points de départ, en vrac.

Pour la configuration HTTPS de Nginx :

Des tutoriels assez complets et bien pratiques :

Pour aller un peu plus loin :