HTTP et SSL ne se marient pas parfaitement. En effet, lorsqu'une session HTTP 1.1 démarre, le client envoie une directive HTTP qui précise le nom du serveur interrogé, ceci permet au serveur de répondre en utilisant le contexte d'un serveur virtuel. Cette opération est réalisée une fois la session HTTP initialisée.
Dans l'empilement de couche HTTPS (HTTP sur SSL), la session SSL doit être initialisée avant tout échange HTTP ; le serveur doit donc présenter son certificat, celui-ci doit contenir le nom du serveur.
Comment peut-il choisir le certificat qu'il doit présenter lors de la session SSL si le nom du serveur n'est déterminé que lors des échanges HTTP ?
C'est la raison pour laquelle si des serveurs virtuels ont des noms différents, on ne peut utiliser les hosts virtuels de HTTP 1.1. La solution consiste à affecter autant d'adresses IP différentes que de serveurs virtuels avec des noms différents ; c'est l'adresse IP appelée qui permet de choisir le certificat à présenter dans la session SSL.
Pour installer un certificat serveur délivré par TCS dans IIS (ou tout autre serveur nécessitant un fichier PKCS#12), il faut ajouter la confiance dans l'ac-racine et l'ac-serveur et ajouter le certificat et la clef privée du serveur. Ces opérations peuvent être effectuées en utilisant un fichier au format PKCS#12.
Construisez ce fichier à l'aide d'OpenSSL, dont il existe une version pour Windows, avec la commande suivante (le mot de passe demandé sert à protéger le fichier créé) :
openssl pkcs12 -export -in mon_serveur.crt -inkey mon_serveur.key -certfile cachain.txt -out mon_serveur.p12
en utilisant les fichiers suivants que vous avez reçus :
Allez ensuite dans le magasin de certificats d'IIS, cliquez sur le bouton “ajouter un certificat” et choisissez le fichier mon_serveur.p12 créé précédemment : le certificat et sa clef privée, ainsi que la confiance dans les ac-serveur et ac-racine sont rajoutés.
Vous pouvez vous inspirer de cette documentation du LIP6.
Voici les docs de openldap les plus précises : http://www.openldap.org/pub/
Paramétrer /etc/syslog.conf :
local4.debug /var/log/ldap/slapd.log
Voir à l'URL : http://www.dm.unibo.it/~donatini/linux/ldap/
% adduser --group --system --no-create-home --gecos "Slapd Server" --disabled-password --disabled-login slapd % vi /etc/default/slapd # to change SLAPD_USER=slapd and SLAPD_GROUP=slapd % chown slapd.slapd /var/run/slapd /var/lib/ldap /espace1/bdb-logs/ % chmod 700 /var/lib/slapd /espace1/bdb-logs/ % chmod 640 /etc/ldap/slapd.conf % chgr slapd /etc/ldap/slapd.conf
Tout est à l'URL : http://www.openldap.org/pub/ksoper/OpenLDAP_TLS_howto.html, choisir la section 4.2 et pas 4.1.
Sous Debian les programmes ne sont pas dans /usr/share/ssl/misc/, mais dans /usr/lib/ssl/misc/
On crée donc un couple clé publique-privée pour l'autorité de certification ou CA, que l'on garde sur un support sécurisé et inaccessible au réseau. Avec la clé privé de la CA, on va signer les certificats des machines et utilisateurs (par machine) utilisant l'annuaire. La clé publique de la CA permettra de vérifier que ces certificats ont bien été signé par la CA.
Dans /etc/ldap/slapd.conf :
# CA signed certificate and server cert entries: TLSCipherSuite HIGH:MEDIUM:+SSLv2 TLSCACertificateFile /etc/ssl/certs/cacert.pem TLSCertificateFile /etc/ssl/certs/servercrt.pem TLSCertificateKeyFile /etc/ssl/private/serverkey.pem # Use the following if client authentication is required TLSVerifyClient demand # ... or not desired at all #TLSVerifyClient never
Ici on indique que l'identité du client devra être validée avec la directive :
- TLSVerifyClient demand
Dans le fichier /etc/ldap/ldap.conf :
# Afin que le client puisse valider l'identité du serveur, on doit le fournir la clé publique # du CA avec laquelle il pourra établir que le certificat du serveur a bien été signé par # la clé privée de cette même CA. TLS_CACERT /etc/ssl/certs/cacert.pem # On demande également au client de toujours valider l'identité du serveur. TLS_REQCERT demand
Pour que le serveur puisse valider l'identité du client, il doit pouvoir accéder au certificat de celui-ci. C'est pourquoi on crée le fichier /home/user/.ldaprc :
TLS_CERT /etc/ssl/certs/clientcrt.pem # Permet de vérifier que clientcrt.pem # appartient bien au client. # clientkey.pem doit être en lecture seule # pour l'utilisateur client et lui appartenir TLS_KEY /etc/ssl/private/clientkey.pem
le serveur maître est ldap-maitre.mon-domaine.net et le réplica ldap-replica.mon-domaine.net
Dans /etc/ldap/slapd.conf,
replogfile /var/lib/ldap/slapd.replog
replica host=ldap-replica.mon-domaine.net:389
suffix="dc=mon-domaine,dc=net"
binddn="cn=compte-de-replication,dc=mon-domaine,dc=net"
credentials="dedeestcompletementdudu"
bindmethod=simple
# Force l'utilisation de TLS entre slurpd et le slapd du replica
tls=critical
Dans /etc/ldap/ldap.conf (utilisé par slurpd)
TLS_CACERT /etc/ssl/certs/cacert.pem # On demande également au client (slurpd)de toujours valider l'identité du serveur (ldap-replica). TLS_REQCERT demand
Attention, slurpd tourne sous root, on crée donc le fichier /root/.ldaprc
TLS_CERT /etc/ssl/certs/servercrt.pem TLS_KEY /etc/ssl/private/serverkey.pem
Dans notre cas le couple certificat-clé privé du serveur maître sera aussi utilisé comme certificats-clé privé pour la connexion cliente de slurpd sur le réplica ldap-replica, on a donc les permissions suivantes sur la clé privé du certificat :
-r--r----- 1 root slapd 1636 2005-01-17 16:22 serverkey.pem
Car slapd tourne sous le login slapd
NB: il serait peut-être plus prudent de créer deux couples certificat-clé privé, un pour root et un pour slapd. Mais cela n'est pas forcément évident.
Dans /usr/local/etc/openldap/slapd.conf :
#TLS options for slapd TLSCipherSuite HIGH:MEDIUM:+SSLv2 TLSCACertificateFile /usr/local/certs/cacert.pem TLSCertificateFile /usr/local/certs/servercrt.pem TLSCertificateKeyFile /usr/local/private/serverkey.pem
On oblige l'authentification du slurpd tournant sur ldap-maitre.mon-domaine.net
TLSVerifyClient demand
Dans le cas d'une réplication via TLS le niveau de sécurité est donc correct.
Attention : Si le client ne se connecte pas en TLS, aucune verification de son identité n'est faite.
Rq : si le serveur n'est configuré qu'en ssl (ou avec un démon spécifique pour ssl avec sa propre configuration et une version récente de openldap) la remarque précédente n'est plus vraie.
Il existe un bug dans Apache2.0 mod_ssl qui empêche de traiter la méthode POST conjointement à une authentification cliente par certificat.
Le problème apparaît quand le niveau d'authentification (SSLVerifyClient) est plus élevé au niveau d'une directive Location qu'au niveau du virtual host.
Le message qui apparaît dans les logs est alors
[error] SSL Re-negotiation in conjunction with POST method not supported!\nhint: try SSLOptions +OptRenegotiate
Les parades envisageables :
L'objectif est d'attribuer à des contrôleurs de domaine Windows (2000 ou 2003) un certificat de serveur du CRU permettant ensuite (entre autres) de pouvoir se connecter à Active Directory en LDAPS.
Cette page s'appuie sur une documentation Microsoft disponible ici.
La manipulation qui est proposée ici ne peut être réalisée que sur un Windows 2003. Toutefois, il sera possible à partir d'une machine de fournir des certificats à n'importe quel contrôleur qu'il soit en Windows 2000 ou 2003.
Le principe va être de générer en local sur la machine un bi-clé ainsi qu'une requête de certification. C'est cette requête qui sera envoyée au CRU afin d'être validée.
L'outil permettant de réaliser ces étapes s'appelle certreq.exe. Il est disponible à partir du Service Pack 1 de Windows 2003.
Pour paramétrer la requête que l'on va générer, il va être nécessaire de fournir à certreq un fichier de configuration que nous appellerons request.inf.
Request.inf :
[Version] Signature="$Windows NT$" [NewRequest] Subject = "CN=<1>,o=<2>,C=FR" KeySpec = 1 KeyLength = 1024 ; Peut être 1024, 2048, 4096, 8192, ou 16384 Exportable = TRUE MachineKeySet = TRUE SMIME = False PrivateKeyArchive = FALSE UserProtected = FALSE UseExistingKeySet = FALSE ProviderName = "Microsoft RSA SChannel Cryptographic Provider" ProviderType = 12 RequestType = PKCS10 KeyUsage = 0xa0 [EnhancedKeyUsageExtension] OID=1.3.6.1.5.5.7.3.1 [Extensions] 2.5.29.17=email ((à remplacer par l'adresse électronique de contact encodée en Base64 par exemple pour reseau@univ.fr on obtient cmVzZWF1QHVuaXYuZnI=))
Des encodeurs Base64 sont disponibles en particulier celui-ci qui est très pratique. Génération de la requête : La génération de la requête s'obtient en lançant en ligne de commande l'instruction suivante :
certreq -new request.inf request.req
Si tout se passe correctement, on va pouvoir observer plusieurs choses :
Validation de la requête : Une fois la requête validée par le CRU, vous récupérez le fichier contenant le certificat de la machine.
Il est nécessaire de copier manuellement dans le fichier .cer la chaîne contenue dans la chaine de certification de façon à obtenir ceci (en respectant l'ordre) :
On peut désormais valider la requête à l'aide de l'instruction suivante : certreq -accept request.cer Si tout se passe correctement, on peut observer que le certificat qui était en attente dans le magasin Demandes d'inscription de certificat a disparu et qu'on le retrouve dans le magasin Personnel.
Si le certificat était destiné à la machine sur laquelle a été réalisée la manipulation, il ne reste plus qu'à ajouter le certificat de l'ac-racine dans le magasin Autorités de certification racines de confiance de l'ordinateur local et à redémarrer la machine.
Si le certificat est destiné à une autre machine, il faut l'exporter en incluant la clé privée au format PKCS12, puis l'importer sur la machine concernée dans le magasin Personnel de l'ordinateur local.
Attention :
Test du bon fonctionnement : Pour indiquer au contrôleur de domaine qu'il dispose désormais d'un certificat, il faut le redémarrer. On peut tester alors avec openssl qu'il répond bien sur le port LDAPS (636) avec la commande suivante :
openssl s_client -host machine.univ.fr -port 636
L'objectif est de créer un keystore java contenant la clé privé d'un serveur, son certificat certifié par l'IGC et la chaine de certification, à partir d'un bi-clé généré localement.
Ce certificat sera directement utilisable pour un serveur tomcat.
On suppose que le serveur est : serv.univ.fr
PREALABLE :
a) disposer d'un JDK
b) récupérer le fichier concernant la chaîne de certification
c) vérifier dans les bases whois le champ propriétaire du nom de domaine de votre serveur. on supposera ici qu'il s'agit de MONUNIVERSITE
PROCEDURE :
générer un keystore contenant un couple clé privée - clé publique
keytool -genkey -alias serv -keyalg RSA -dname "EMAILADDRESS=reseau@univ.fr,CN=serv.univ.fr,O=MONUNIVERSITE,C=FR" -keystore serv.keystore
Controler :
keytool -list -v -keystore serv.keystore
Le keystore contient une entrée, de type keyEntry
générer une requête de certification (Certificate Signing Request) :
keytool -certreq -alias serv -keystore serv.keystore -file serv.csr
serv.csr est un fichier 'lisible'
Transmettre ce fichier à un de vos demandeurs désignés de certificat Il recevra du CRU le certificat associé : serv.univ.fr.crt
concaténer le certificat du serveur avec celui de la chine de certification des AC :
% (cat serv.univ.fr.crt ; echo ; cat cachain.txt) > serv-chain.pem
ATTENTION : l'ordre a de l'importance (d'abord certif de serveur, puis de l'ac-serveur, puis de l'ac-racine) 'formater' le fichier généré
supprimer dans le fichier généré tout ce qui n'est pas entre des lignes —–BEGIN CERTIFICATE—– et —–END CERTIFICATE—–, en maintenant un retour chariot en dernière ligne.
Le résultat est similaire à ceci :
-----BEGIN CERTIFICATE----- MIIEBzCCAu+gAwIBAgICANcwDQYJKoZIhvcNAQEEBQAwUDELMAkGA1UEBhMCRlIx ... certif de serv.univ.fr ... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID1zCCAr+gAwIBAgIBAzANBgkqhkiG9w0BAQQFADBPMQswCQYDVQQGEwJGUjEM ... certif de l'ac-serveur ... nbnQ04fo+LDLFWa9qCI8mLX1JGcP4WDKJ9hk -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIID1jCCAr6gAwIBAgIBADANBgkqhkiG9w0BAQQFADBPMQswCQYDVQQGEwJGUjEM ... certif de l'ac-racine ... 6cKi0FjWaBYjBOH6/ULalf1g4P38vbUAT4A= -----END CERTIFICATE-----
Controler la validité de ce fichier :
keytool -printcert -file serv-chain.pem
Les 3 certificats sont listés, dans l'ordre
Importation des certificats de la chaine de certification
keytool -import -alias serv -trustcacerts -file serv-chain.pem -keystore serv.keystore
ATTENTION : il est important que l'alias soit identique à l'alias correspondant à l'entrée à laquelle on veut ajouter les certificats.
controler :
keytool -list -v -keystore serv.keystore
S'assurer que le keystore ne contient qu'une seule entrée de type keyEntry, avec une longueur de chaîne du certificat de 3, et que les 3 certificats sont bien listés.
Le fichier serv.keystore est prêt pour son usage.
Le plus simple est de créer un nouveau keystore, contenant le nouveau certificat, et qui remplace l'ancien. Ensuite il suffit de faire pointer son serveur Tomcat vers le nouveau keystore. Voir Créer un keystore à partir un couple de fichiers .key et .crt pour la création d'un keystore.
La solution que nous avons expérimentée est la suivante :
tls {
certificate_file = /etc/pki/crts/serverAvecChaine.crt
private_key_file = /etc/pki/key/server.key
CA_file = /etc/pki/crts/tcschain.crt
[...]
}
Ensuite, par exemple pour le client par défaut de windows, il suffit de lui signaler qu'on fait confiance à l'AC AddTrust External CA Root. La confiance est alors propagée en cascade via la chaîne de certification.