====== 2. SSL et HTTPS ====== {{tag>ssl https apache openssl crypto}} //par julien - octobre 2005// ===== 1 - Introduction ===== Cet article décris comment mettre en place un accés HTTPS avec Apache 2. Nous n'aborderons pas la configuration d'Apache pour autre chose que HTTPS. L'objectif est qu'à la fin de cette opération, votre serveur soit capable d'accepter une connection HTTPS sur le port 443, de négocier une session TLS et d'afficher un contenu quelconque. ===== 2 - Apache2 et mod_ssl ===== Apache2, l'incontournable, utilise mod_ssl pour HTTPS. Le module se base sur OpenSSL pour les outils cryptographiques. Il faut l'activer dans la config d'Apache2 : zerhuel:/etc/apache2/mods-available# ls -al |grep ssl -rw-r--r-- 1 root root 3545 2005-09-05 13:16 ssl.conf -rw-r--r-- 1 root root 58 2005-09-05 13:16 ssl.load Perso, je travaille sur debian donc pour l'install d'Apache2 c'est "apt-get" et le chemin de config est /etc/apache2. Dans ce répertoire, le dossier mods-available contient ssl.load avec la ligne qui permet de lancer le module : # cat ssl.load LoadModule ssl_module /usr/lib/apache2/modules/mod_ssl.so et le fichier ssl.conf qui contient la configuration du module ssl, que nous verrons juste aprés. Dans le fichier apache2.conf on spécifie que tout le répertoire mods-enable est chargé au lancement: # cat /etc/apache2/apache2.conf |grep mods-enable Include /etc/apache2/mods-enabled/*.load Include /etc/apache2/mods-enabled/*.conf => ceci est fait par défaut donc pour lancer un module, on se contente de faire un lien symbolique des deux fichiers qui sont dans mods-available vers mods-enable. zerhuel:/etc/apache2/mods-enabled# ls -al |grep ssl [...]root 26 2005-10-16 01:34 ssl.conf -> ../mods-available/ssl.conf [...]root 26 2005-10-16 01:34 ssl.load -> ../mods-available/ssl.load Bien ! On peut attaquer la configuration du module ssl. Commencons par faire un backup puis on nettoie le fichier: zerhuel:/etc/apache2/mods-available# mv ssl.conf ssl.conf.old zerhuel:/etc/apache2/mods-available# awk '! (/^ *#/ || /^$/) { print $0 \ }' ssl.conf.old > ssl.conf //cette derniere commande tiens sur une seule ligne normalement :) awk est un processeur de texte, pratique pour faire des selections // Entrons dans le fichier pour l'éditer. La ligne vraiment importante est SSLCipherSuite car elle définit les différents algorithmes utilisés. voir ABSOLUMENT ce lien: http://httpd.apache.org/docs/2.0/mod/mod_ssl.html#sslciphersuite et voici donc les algos qu'il faut conserver: SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM C'est important ! si vous êtes laxistes, un pirate pourra forcer l'établissement d'une connection SSLv2 qui comporte de nombreuse failles reconnues, ce que vous ne voulez pas. Ces choix sont sûrs depuis plusieurs années. Voici les algorithmes qui, grace a la ligne ci-dessus, pourront etre utilisés: # openssl ciphers -v 'HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM' DHE-RSA-AES256-SHA SSLv3 Kx=DH Au=RSA Enc=AES(256) Mac=SHA1 DHE-DSS-AES256-SHA SSLv3 Kx=DH Au=DSS Enc=AES(256) Mac=SHA1 AES256-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(256) Mac=SHA1 EDH-RSA-DES-CBC3-SHA SSLv3 Kx=DH Au=RSA Enc=3DES(168) Mac=SHA1 EDH-DSS-DES-CBC3-SHA SSLv3 Kx=DH Au=DSS Enc=3DES(168) Mac=SHA1 DES-CBC3-SHA SSLv3 Kx=RSA Au=RSA Enc=3DES(168) Mac=SHA1 DES-CBC3-MD5 SSLv2 Kx=RSA Au=RSA Enc=3DES(168) Mac=MD5 DHE-RSA-AES128-SHA SSLv3 Kx=DH Au=RSA Enc=AES(128) Mac=SHA1 DHE-DSS-AES128-SHA SSLv3 Kx=DH Au=DSS Enc=AES(128) Mac=SHA1 AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 DHE-DSS-RC4-SHA SSLv3 Kx=DH Au=DSS Enc=RC4(128) Mac=SHA1 RC4-SHA SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=SHA1 RC4-MD5 SSLv3 Kx=RSA Au=RSA Enc=RC4(128) Mac=MD5 RC2-CBC-MD5 SSLv2 Kx=RSA Au=RSA Enc=RC2(128) Mac=MD5 RC4-MD5 SSLv2 Kx=RSA Au=RSA Enc=RC4(128) Mac=MD5 Les colonnes sont: - le nom de la suite - le numéro de version (imprécis ici, en fait il s'agit de TLSv1) - l'algorithme d'échange de clé (Kx=) - l'algorithme asymétrique d'authentification (Au=) - l'algorithme de chiffrement symétrique (Enc=) - l'algorithme d'empreinte (Mac=) Ajoutons également à ce fichier le chemin de notre certificat autosigné: SSLCertificateFile /etc/apache2/ssl/apache.pem On peut désormais fermer le fichier ssl.conf. Maintenant, il nous faut créer un virtual host qui va appeler notre site par défaut mais avec une connection ssl. Recopions les paramétres du virtual host classique: zerhuel:apache2# cat sites-available/default>sites-available/default-ssl Il faut modifier le nom du virtual host, pourquoi pas *:443, et ajouter les lignes suivante juste aprés la déclaration du vhost: SSLEngine on ErrorLog /var/log/apache2/error-ssl.log CustomLog /var/log/apache2/access-ssl.log combined et on link le virtual host ssl vers le répertoire sites-enabled: zerhuel:~#ln -s /etc/apache2/sites-available/default-ssl \ /etc/apache2/sites-enabled/default-ssl; Un dernier point pour la config d'apache2 est le fichier ports.conf. Il est obligatoire de lui indiquer d'écouter sur le port 443, le port TLS. zerhuel:~# echo 'Listen 443'>>/etc/apache2/ports.conf zerhuel:~# cat /etc/apache2/ports.conf Listen 80 Listen 443 Je ne crois pas avoir oublié quelque chose, si c'est le cas faites le moi savoir sur le forum :) ===== 3 - Certificat autosigné ===== Apache2 fournit un outil trés pratique qui se nomme 'apache2-ssl-certificate'. Il suffit de le lancer et un script de génération d'un certificat SSL autosigné se lance... pratique! Le probleme est que ce script n'existe que sous Debian et Ubuntu (merci a CalCmAn de me l'avoir fait remarquer) donc j'ai réécris un script fortement inspiré mais qui devrais fonctionner sur toute les distribs. #cat gen_cert_autosigned.sh ----------------------------------------------------------------------- #! /bin/sh -e echo '+--------------------------------------------------+' echo '|Linuxwall.info: creation d un certificat autosigné|' echo '| |' echo '|by switcher - oct.2005 |' echo '+--------------------------------------------------+' echo echo 'Pour un usage privé uniquement, dans le cas contraire' echo 'utilisez un certificat émis par une autorité de certification' echo echo echo 'Quel est le chemin de fichier sssleay.cnf ?' echo '[ex:/usr/share/apache2/ssleay.cnf]' read CONF echo echo 'A quel endroit voulez vous stocker votre certificat ?' echo '[ex:/etc/apache2/ssl/] ATTENTION AU "/" DE FIN DE CHEMIN ' read PWD echo echo 'Donnez un nom a votre certificat [ex:apache.pem]' read NOM echo echo 'Quel est la durée de validité du certificat en jours [ex:750]' read DAYS # export RANDFILE=/dev/random # openssl req -config $CONF -new -x509 -nodes -out $PWD$NOM \ -keyout $PWD$NOM -days $DAYS # chmod 600 $PWD$NOM # ln -sf $PWD$NOM $PWD`/usr/bin/openssl x509 -noout -hash < $PWD$NOM`.0 echo echo echo 'Certificat autosigné créé à l emplacement' $PWD$NOM echo 'en cas de pb, postez sur le forum de www.linuxwall.info' ----------------------------------------------------------------------- Bon ba c'est un script classique, il vous suffit de le copier/coller et de rendre le fichier executable et vous le lancez en root. Evidemment, ne prenez que ce qui se trouve ENTRE les lignes de tirets :p # ./gen_cert_autosigned.sh +--------------------------------------------------+ |Linuxwall.info: creation d un certificat autosigné| | | |by switcher - oct.2005 | +--------------------------------------------------+ | Pour un usage privé uniquement, dans le cas contraire utilisez un certificat émis par une autorité de certification | | Quel est le chemin de fichier sssleay.cnf ? [ex:/usr/share/apache2/ssleay.cnf] /usr/share/apache2/ssleay.cnf | A quel endroit voulez vous stocker votre certificat ? [ex:/etc/apache2/ssl/] ATTENTION AU "/" DE FIN DE CHEMIN /etc/apache2/ssl/ | Donnez un nom a votre certificat [ex:apache.pem] apache.pem | Quel est la durée de validité du certificat en jours [ex:750] 3650 Generating a 1024 bit RSA private key ....++++++ .............................................................++++++ writing new private key to '/etc/apache2/ssl/apache.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [GB]:FR State or Province Name (full name) [Some-State]:2sevres Locality Name (eg, city) []:Niort Organization Name (eg, company; recommended) []:Linuxwall.info Organizational Unit Name (eg, section) []:security department server name (eg. ssl.domain.tld; required!!!) []:localhost Email Address []:julien@microgate.fr | | Certificat autosigné créé à l emplacement /etc/apache2/ssl/apache.pem Les 2 premiéres questions sont importantes, ce sont les chemins utilisés par le script, puis la 3eme est le nom du certificat et enfin la durée de validité. Ensuite, le certificat en lui meme pose 7 questions. Vous pouvez mettre ce qu'il vous plait SAUF pour le champ 'server name' qui doit etre l'url de votre site web, si vous ne voulez pas avoir une erreur lors de la connection TLS. Le certificat autosigné est écris dans un format compris par apache2 mais pas par vous, a la différence du certificat vu dans le premier chapitre. ===== 4 - HTTPS (sniff avec ethereal) ===== Maintenant que la configuration est terminée, on va regarder ce que ca donne. Relancez apache2 et assurez vous qu'il démarre sans aucun autre message que: zerhuel:/etc/apache2# /etc/init.d/apache2 start Starting web server: Apache2. Sinon, vérifiez la config. A priori il n'y a pas d'erreur dans ce que j'ai écris mais j'en mettrais quand meme pas ma main a couper :) Admettons que tout fonctionne bien, vous pouvez désormais accéder à votre site via l'adresse: https://localhost et Ô magie on vous propose un certificat !!! Faites vous plaisir et allez voir ce qu'il à dans le ventre, ce n'est pas si obscur que ca. Maintenant que celà fonctionne, et pour les plus 3l33t d'entre nous, on va s'interesser à ce que nous ressors ethereal lors de l'établissement de la connection https... Âmes sensibles s'abstenir ! Bien, allons-y. Le fichier ethereal est dispo sur le site à l'adresse www.linuxwall.info/ressources/dossiers/ssl_pki/sniff_https.ethereal Il n'y a que 32 trames, ce qui correspond à une ouverture et fermeture de session https en local. 1,2,3. Ces trames sont le handshake TCP, rien d'interessant pour nous A ce sujet, les trames 3,5,7,10,12,16,19,23,25 et 28 sont des ACK TCP, n'y pretez pas attention. 4.Le client hello (qui utilise le format de client hello établit par la v2 de ssl) établit le début de connection du client vers le serveur 6. Le serveur répond avec la version (TLSv1), la suite d'algorithme choisie (TLS_DHE_RSA_WITH_AES_256_CBC_SHA) mais aussi le certificat du serveur et une clé publique pour l'échange des clés. Pour ceux qui ont lu "1.les bases", ca correspondant aux messages 2,3,4 et 5 du TLS Handshake Protocol... autrement, il chome pas le serveur ! 8.Le client enchaine avec Client Key Exchange (voir "les bases"), passe en mode chiffré avec le message Change Cipher Spec et fini avec un Encrypted Handshake Message pour bien terminer avec un chiffrement. 10.Le serveur change lui aussi ses propriétés de chiffrement et envoi le Encrypted Handshake Message pour finaliser la session handshake. 11->27. Ce sont des messages Application Data, autrement dit des données applicatives chiffrés par TLS. Sans TLS, vous verriez dans ces trames du code HTML, PHP, MySQL, etc.... 29 & 31. Encrypted Alert: utilisé pour terminer la session TLS, les deux parties se désengagent sur l'initiative du client. 32. RST: drapeau TCP pour terminer la session. ===== 5 - Conclusion ===== Et voilà, c'est un bon début dans la maitrise de HTTPS. Maintenant ce qu'il vous manque c'est une approche plus globale de ce que l'on peut faire avec TLS, autrement dit, les Public Key Infrastructure [PKI]. Pour celà, rendez-vous dans le dossier suivant. ======================= Switcher - Octobre 2005 switcher{a}linuxwall.info~~DISCUSSION~~