Problème de client et/ou serveur web?

Durant le développement d’une application sous C++Builder j’ai frappé un mur assez solide. Pendant presque qu’un mois il y a eu un problème que je n’ai su résoudre. Maintenant j’ai la solution et je vais vous la partager.

L’application en question est un client HTTP qui utilise les composants TIdHTTP et TIdSSLIOHandlerSocketOpenSSL. Elle possède la possibilité de se connecter à plusieurs serveur web dont certains qui utilisent une connexion sécurisée. Les serveurs fournissent un service à l’aide d’un API JSON.

La plupart de mes tests se faisaient avec un serveur Windows Server 2012 R2 qui utilise un certificat SSL généré gratuitement par Let’s Encrypt. Le certificat est renouvelé automatiquement par l’intermédiaire de l’application Windows ACME Simple, anciennement connu sous le nom letsencrypt-win-simple.

Le développement de l’application allait bon train, jusqu’au moment où j’ai commencé à recevoir l’exception suivante lors de l’utilisation de la méthode Get:

Project app.exe raised exception class EIdSocketError with message ‘Socket Error # 10054 Connection reset by peer.’.

Bien évidemment j’ai pensé que j’avais changé quelque chose dans mon code. Alors j’ai tenté d’utiliser le code de soumissions antérieures. J’utilise toujours Git, même pour mes projets personnels de petite envergure. Dans ce cas, cela aurait pu me sauver la vie, mais non, mon code qui fonctionnait ne fonctionne plus!

Je n’utilisais pas les derniers fichiers DLL de OpenSSL, alors j’ai téléchargé la dernière version. Au moment d’écrire ces lignes la version 1.0.2o était la version LTS la plus à jour. Malheureusement ceci ne provoqua aucun changement de comportement.

Il est important de mentionner que le problème survient seulement avec mon serveur Windows Server 2012 R2 et que l’API répond correctement sur celui-ci avec Chrome et Firefox. Donc, mon serveur fonctionne avec certains clients et mon application fonctionne avec tous les autres serveurs testés! Est-ce un problème de client ou de serveur?

Étant donné que je voulais continuer de développer mon application j’ai décidé d’utiliser un autre serveur pour faire mes tests. La bonne nouvelle, c’est que mon application pouvait progresser, la mauvaise c’est qu’il est possible que certains utilisateurs éprouvent le même problème. Pendant presque un mois ce problème est resté dans ma tête.

L’application tirant à sa fin, je n’avais plus qu’un seul problème à régler. Aux grand maux, les grands moyens, je décide d’utiliser Wireshark pour regarder ce qui se trame lors de la connexion. La seule chose que j’observe est qu’après une requête HTTPS (Client Hello) au serveur, celui-ci semble se déconnecter.

Je me dis alors que c’est peut-être une mise à jour manquante sur le serveur! Alors je fais toutes mes mises à jour Windows, même celles facultatives. J’en profite même pour désactivé TLS version 1.0. Je redémarre le serveur et malheureusement, ceci ne règle rien. C’était quand même une bonne idée de fixer les trous de sécurités sur le serveur.

Par la suite, je vais dans la console de IIS et pour la première fois j’y vois une alerte qui attire mon attention:

No default SSL site has been created. To support browsers without SNI capabilities, it is recommended to create a default SSL site.

Je commence donc à lire un peu sur le sujet et je me rappelle que dans l’outil SSL Server Test de SSL Labs il y avait une bannière bleue avec le texte suivant:

This site works only in browsers with SNI support.

Ma lecture m’amène à comprendre que Server Name Indication (SNI) fait partie du Client Hello. Tiens, cela me rappelle ce que j’ai vu dans Wireshark. C’est le client qui doit supporter cette extension. Dans mon cas, le client est la bibliothèque Indy. Est-ce qu’il y a des problèmes connus avec SNI dans Indy? Le support SNI a été introduit dans la soumission 5321 du 11 janvier 2016. J’utilise RAD Studio XE8 qui date de 2015. Pour être certain, je regarde aussi le fichier Idglobal.hpp où l’on trouve l’information sur la version de Indy utilisé:

#define gsIdVersionMajor 10
#define gsIdVersionMinor 6
#define gsIdVersionRelease 2
#define gsIdVersionBuild 5263

Eh bien, la version de Indy que j’utilise ne supporte pas SNI!

Pour faire un test rapide, je désactive SNI sur mon serveur:

Require Server Name Indication
La case à cocher Require Server Name Indication

Tout fonctionne!

En conclusion, je présume que ce qui s’est passé durant le développement de l’application est que le serveur sur Windows Server 2012 R2 a dû renouveler le certificat SSL et que la configuration du serveur à changer. D’ailleurs lorsque l’on regarde l’historique de soumission du logiciel Windows ACME Simple, plusieurs messages sont en lien avec SNI. J’ai fait une mise à jour à la version 1.9.10.1 et j’espère que lors du prochain renouvellement il n’y aura pas de problèmes. S’il y en a, au moins je sais où regarder en premier.

Désactivé TLS 1.0 sur Windows Server

Selon le PCI Security Standards Council il serait recommandé de migrer du protocole Transport Layer Security (TLS) version 1.0 vers une version plus récente et cela pour le 30 juin 2018. Présentement, sur mon site web qui roule sous Windows Server 2012 R2, TLS 1.0 est encore disponible.

Dans un article précédent j’avais expliqué comment augmenter la sécurité d’un site web. Celui-ci sera similaire, sauf qu’au lieu d’aller éditer le registre de Windows directement, le logiciel IIS Crypto sera utilisé. Cela va grandement simplifier la tâche.

Il suffit d’ouvrir l’application et de décocher TLS 1.0 dans la section Protocols:

IIS Crypto 2.0
IIS Crypto 2.0 avec la case à cocher TLS 1.0 vide

Par la suite il faut cliquer sur le bouton Apply et redémarrer le serveur.

Pour vérifier que tout a bien fonctionné, on peut utiliser l’outil SSL Server Test de SSL Labs:

No TLS 1.0
TLS 1.0 n’est plus disponible

Voilà, maintenant votre serveur devrait être plus sécuritaire.

Augmenter la sécurité d’un site web utilisant SSL

Dernièrement je me suis fais présenter l’outil SSL Server Test de SSL Labs. C’est une application en ligne qui permet de tester la sécurité d’une site web. J’avais récemment installé un certificat SSL sur le serveur d’un ami. Il s’agit d’un certificat généré gratuitement par Let’s Encrypt. Donc, je croyais bien obtenir une bonne note. Eh bien… non! J’ai obtenu la note de B.

Voici les deux problèmes qui me limitaient à cette cote.

  • This server supports weak Diffie-Hellman (DH) key exchange parameters. Grade capped to B.
  • This server accepts RC4 cipher, but only with older browsers. Grade capped to B.

Le site web est hébergé sur Windows Server 2012 R2. Donc les prochaines étapes pour régler ces problèmes de sécurité ont seulement été testées avec cette version de Windows. Si vous les appliquez, voici ce qui pourrait arriver:

Cote B vers A-
Cote B vers A-

A- ce n’est pas A ou même A+, mais c’est un bon départ.

Tous ces problèmes peuvent se régler dans l’Éditeur du Registre. On peut le démarrer avec la commande regedit.exe

Pour régler le problème avec Diffie-Hellman on doit aller dans la clef suivante:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SChannel\KeyExchangeAlgorithms
Si elle n’existe pas on doit créer la sous-clef Diffie-Hellman
Dans la clef Diffie-Hellman, on doit créer une valeur DWORD nommé Enabled dont la donnée est 0.

Maintenant passons à l’algorithme de chiffrement RC4 (Rivest Cipher 4) qui est désuet. On doit aller dans la clef suivante:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers
Il va ensuite falloir créer les trois sous-clefs suivantes: RC4 128/128, RC4 40/128 et RC4 56/128.
Pour chacune de ces clefs, on doit créer une valeur DWORD nommé Enabled dont la donnée est 0.

Registry Editor - SCHANNEL key
Éditeur du Registre – clef SCHANNEL

Vous pouvez maintenant fermer l’Éditeur du Registre et redémarrer votre serveur pour appliquer les modifications.

Si vous désirez annuler ces changements il suffit de mettre la valeur Enabled à 0xffffffff. Vous pouvez aussi simplement supprimer la valeur Enabled.

J’espère que cet article vous aidera à augmenter la sécurité de votre site en évitant d’exposer des méthodologies faibles ou insécures.