Nginx avec Certificat SSL Autosigné
La nature humaine étant ce qu’elle est, particulièrement sur internet, il est de plus en plus indispensable de pouvoir chiffrer ses communications et authentifier le serveur avec lequel on échange. Le protocole SSL répond à ce besoin mais il nécessite de disposer au préalables de certificats.
Il faut savoir qu’il existe deux type de certificats SSL. Ceux qui sont signés par une autorité de certification (CA) comme Verisigns ou Thawte, minimum 50€ par an ou plus, et ceux auto-signés et gratuits. Le signataire étant censé être un tiers de confiance garantissant la validité du certificat, on comprend que cela peut poser problème dans le cas des certificats auto-signés. Ceci dit, pour un usage personnel, vous pourrez raisonnablement supposer, sauf à être schizophrène, que vous pouvez faire confiance à vous même et au certificat que vous avez auto-signés.
Je propose donc, dans ce post, un script qui permet de générer rapidement une clé privée RSA de 2048 bits et un certificat auto-signé. Je donne aussi quelques explications qui, une fois le certificat créé, permettront de le mettre en place sur votre serveur web préféré (nginx).
2048 bits sinon rien
J’utilise une clé de 2048 bits, ce qui est, à l’heure actuelle, le minimum recommandé pour un certificat SSL. Bien sûr, on peut toujours utiliser des clés plus grandes (4096 bits etc.), mais il s’agit de calcul matriciel et la charge cpu peut facilement être multipliée par 8-12 quand la taille de la clé double ce qui posera problème pour des serveurs à fort trafic.
Environnement
OS : Debian 7.5 stable (Wheezy) (64bits)
Nginx : nginx/1.2.1
Le Script
Comme d’habitude, copiez/collez le script à l’aide de nano dans un fichier (type nom_du_script.sh) sur votre serveur et passez un « chmod a+x » pour le rendre exécutable. A partir de là, tapez à la ligne de commande « nom_du_script.sh certificate 730 » pour créer un certificat valide 730 jours soit 2 ans.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #!/bin/bash # genere un certificat de 2048 bits if [ "x$1" = "x" ] then echo -e "usage: create_cert [file] [n]" echo -e "Will create a server key [file].key and a server certificate [file].crt valid for [n] days" exit 0 else NAME="$1" fi if [ "x$2" = "x" ] ; then TIME="365" ; else TIME="$2" ; fi # genere une cle prive echo -e "\nGenerating server key\n" if ( ! openssl genrsa -out "$NAME.key" 2048 >> /dev/null 2>&1 ) ; then echo -e "Error" ; exit 1 ; fi # cree un csr avec la cle privee echo -e "\n\nGenerating certificate request\n" openssl req -new -key "$NAME.key" -out "$NAME.csr" # cree le certificat echo -e "\n\nGenerating certificate\n" openssl x509 -req -days "$TIME" -in "$NAME.csr" -signkey "$NAME.key" -out "$NAME.crt" rm "$NAME.csr" echo -e "\n$NAME.key: votre cle privee\n$NAME.crt: votre certificat serveur" exit 0 |
Configuration Nginx avec SSL
Une fois armé de votre clé privée et certificat, copiez les là où il faut dans l’arborescence de votre serveur. Il ne reste plus qu’à configurer Nginx. Je me suis inspiré pour cette configuration des recommandations de Nginx et de celles de Mozilla. Il faudra par contre rajouter à la suite le reste de la configuration de votre serveur web.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | server { listen 443 ssl; server_name www.mondomaine.com; # certs sent to the client in SERVER HELLO are concatenated in ssl_certificate ssl_certificate /chemin/vers/votre_certificat_serveur_auto_signe.crt; ssl_certificate_key /chemin/vers/la_cle_privee.key; # Diffie-Hellman parameter for DHE ciphersuites, recommended 2048 bits # ssl_dhparam /path/to/dhparam.pem; ssl_session_timeout 5m; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:AES128:AES256:RC4-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ... } |
A remarquer que, dans un usage personnel, la configuration de Mozilla est un peu excessive. Il s’agit de permettre l’accès au maximum de clients quitte à utiliser des ciphers ou des protocoles moins sécurisés. Par exemple, si vous n’avez pas de soucis de compatibilité, déactivez le SSLv3 et TLSv1. Typiquement, le SSLv3 est conservé pour les clients internet explorer 6. Aussi, par soucis de simplicité, j’ai désactivé le paramètre « Diffie-Hellman » mais il fourni réellement un gain de sécurité. Pour plus d’information, aller lire cette page sur le « hardening » de configuration SSL.
Il ne vous reste plus maintenant qu’à taper https://www.mondomaine.com/ dans votre navigateur préféré. L’avertissement de sécurité est normal, les navigateurs sont configurés pour ne reconnaître sans problème que les certificats signés par des CA reconnus (Verisigns, Thawte, etc.)
Un Dernier Mot
Une clé privé n’a d’intérêt que si elle reste privée. Il est donc important de la générer sur le serveur même et qu’elle ne soit accessible que par le root (chown root. et chmod 600). Bien évidemment, mettez à jour le serveur avant de procéder et régénérez régulièrement de nouveaux couples de clés/certificats. Un certificat « fort » aujourd’hui sera probablement trop « faible » d’ici 2 ou 3 ans, souvenez-vous de Heartbleed.