Vous soumettez un CSR d’appliance à une AC Microsoft pour obtenir un certificat au modèle Appliance avec plusieurs SAN… mais seul le premier est conservé ? Voici l’analyse, les causes probables et surtout des procédures fiables qui fonctionnent en production.
Problème : impossibilité d’obtenir plusieurs SAN avec certreq
/ certutil
Lors d’une soumission directe en ligne de commande, l’attribut -attrib
regroupe le modèle et les SAN :
certreq -submit `
-attrib "CertificateTemplate:Appliance\nSAN:dns=entry1.contoso.com&dns=entry2.contoso.com&dns=entry3.contoso.com" `
cert.csr
Le certificat est bien émis, mais l’extension Subject Alternative Name (SAN) ne contient que entry1.contoso.com
. Les autres noms semblent ignorés.
Contexte
- CSR généré sur une appliance (clé privée non exportable ou environnement verrouillé).
- Objectif : certificat basé sur le modèle Appliance avec plusieurs SAN DNS.
- Soumission via
certreq -submit
, en passant les SAN dans-attrib
plutôt que dans le CSR.
Symptômes observés
- Dans un
certutil -dump
du certificat émis : un seul SAN (le premier) est présent. - Événements AC sans erreur explicite ; la demande est “valide” mais tronquée.
- Répéter la soumission avec plus de SAN ne change rien : seul le premier est conservé.
Causes probables
Syntaxe de l’attribut SAN
SAN:
ne doit apparaître qu’une seule fois. Tous les noms sont enchaînés derrière, séparés par &
, sans retour à la ligne ni répétition de SAN:
. Exemple correct :
SAN:dns=host1.contoso.com&dns=host2.contoso.com&dns=host3.contoso.com
La moindre rupture de ligne, espace parasite, guillemet manquant, ou répétition de l’étiquette SAN:
peut faire échouer l’agrégation.
Limitation côté certreq
avec -attrib
Des retours terrain concordants montrent que certreq
interprète correctement le premier élément SAN mais ignore les suivants lorsqu’on combine CertificateTemplate
et SAN=...
dans la même chaîne -attrib
. Le résultat : un certificat émis, mais avec un SAN réduit à une seule entrée.
Stratégie de l’AC (AD CS)
Si l’autorité ne copie pas l’attribut subjectAltName
depuis la requête, elle n’inclura pas tous les noms alternatifs demandés. Sur une AC Microsoft, vérifier et, si besoin, activer :
certutil -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
net stop certsrv & net start certsrv
Sans ce drapeau, l’AC peut ignorer ou tronquer les SAN fournis dans la demande.
Solutions éprouvées
Solution | Résultat |
---|---|
Conserver le CSR de l’appliance et passer plusieurs SAN via -attrib | Ne fonctionne pas : seul le 1er SAN est retenu |
Générer un CSR local via un fichier INF (Subject vide, SubjectAltName complet), puis certreq -new req.inf req.csr | Fonctionne : tous les SAN sont présents dans le certificat |
Convertir le PFX obtenu en PEM et extraire clé / cert / chaîne via openssl pkcs12 -in file.pfx -nodes | Permet d’importer le certificat sur l’appliance malgré l’absence de prise en charge directe du PFX |
Procédure INF de référence
req.inf
de base (modèle Appliance, SAN DNS multiples) :
[Version] ; identique pour toutes les requêtes
Signature="$Windows NT$"
\[NewRequest] ; section principale
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
SMIME = FALSE
Silent = TRUE
RequestType = CMC ; ou PKCS10
CertificateTemplate= Appliance ; nom exact du modèle
\[Extensions] ; ---- extension SAN ----
2.5.29.17 = "{text}"
*continue* = "dns=entry1.contoso.com&"
*continue* = "dns=entry2.contoso.com&"
*continue* = "dns=entry3.contoso.com"
Enchaînez ensuite :
certreq -new req.inf req.csr
certreq -submit req.csr issued.cer # ou passer par l’EAC/WebEnroll
certreq -accept issued.cer
Étapes détaillées pas à pas
- Préparer le fichier INF en listant tous les SAN dans la section
[Extensions]
. GarderSubject
vide si le modèle impose “Supply in the request”. - Générer le CSR avec
certreq -new
. Conservez le.csr
et le.inf
pour audit ultérieur. - Soumettre à l’AC via
certreq -submit
ou via l’interface Web d’inscription. Sélectionner le modèle Appliance le cas échéant. - Accepter et lier le certificat via
certreq -accept
(associe le cert au couple clé/CSR local). - Exporter si nécessaire un PFX depuis le magasin machine (
certlm.msc
) pour remise à l’appliance. - Convertir PFX en PEM si l’appliance n’accepte pas le PFX :
openssl pkcs12 -in device.pfx -nodes -out bundle.pem # Séparer ensuite : # - clé privée : -----BEGIN PRIVATE KEY----- ... # - certificat : -----BEGIN CERTIFICATE----- # - chaîne : certificats CA intermédiaire + racine (si requis par la cible)
- Importer sur l’appliance la clé privée et le certificat/chaîne, selon son format attendu.
Variantes d’attributs SAN dans un INF
Vous pouvez mélanger différents types de SAN. Syntaxes usuelles :
[Extensions]
2.5.29.17 = "{text}"
; DNS
_continue_ = "dns=www.contoso.com&"
; IP
_continue_ = "ipaddress=10.10.10.10&"
; Adresse e-mail
_continue_ = "rfc822Name=alerts@contoso.com&"
; UPN (souvent pour authent. Kerberos)
_continue_ = "otherName=1.3.6.1.4.1.311.20.2.3;UTF8:device01@contoso.com&"
; URI
_continue_ = "url=http://status.contoso.com"
Astuce : terminez toutes les lignes par &
sauf la dernière. Évitez les espaces en trop, ils comptent.
Quand utiliser CMC plutôt que PKCS#10 ?
PKCS#10 suffit dans la majorité des cas. CMC (Certificate Management over CMS) devient utile pour transporter des attributs additionnels, des données d’autorisation ou des demandes groupées. Pour ce cas précis (plusieurs SAN), PKCS#10 + section [Extensions]
est simple et fiable.
Vérifications et diagnostic
Valider l’extension SAN du certificat
certutil -dump issued.cer | findstr /I "Alternative"
# Depuis n’importe quel poste avec OpenSSL
openssl x509 -in issued.cer -noout -text | sed -n '/Subject Alternative Name:/,/X509v3/p'
Contrôler la demande côté AC
- Journal Windows → Applications and Services Logs → CertificationAuthority : présence d’événements d’émission et de copie d’attributs.
certutil -config - -ping
pour valider la connectivité AC.certutil -getreg policy\EditFlags
pour inspecter les drapeaux actifs (EDITF_ATTRIBUTESUBJECTALTNAME2
attendu).
Checklist rapide
Point de contrôle | Attendu | Commande / Indice |
---|---|---|
Syntaxe -attrib | Un seul SAN: , valeurs séparées par & | Revoir guillemets et retours de ligne |
Modèle | CertificateTemplate correct, droits d’inscription OK | Console AC → Certificate Templates |
Copie du SAN | EDITF_ATTRIBUTESUBJECTALTNAME2 activé | certutil -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2 |
Source du SAN | SAN inclus dans le CSR (INF/OpenSSL) | certreq -new avec [Extensions] |
Validation finale | Tous les SAN présents | certutil -dump / openssl x509 -text |
Bonnes pratiques PKI pour ce scénario
- Mettre les SAN dans le CSR (INF/OpenSSL/PowerShell) plutôt que dans
-attrib
. - Éviter les modifications manuelles des SAN au moment de l’émission : préférez des workflows reproductibles.
- Limiter les droits sur le modèle Appliance : seuls les opérateurs autorisés doivent pouvoir inscrire des certificats avec SAN multiples.
- Journaliser les demandes et conserver les
.inf
/.csr
associés. - Tester en préproduction chaque changement (modèle, flags AC, versions d’OS).
Alternatives et compléments
- PowerShell / ACME : si l’appliance ou l’environnement autorise ACME (par ex. via
New-PACertificate
), laissez le protocole gérer les SAN. Utile pour le renouvellement automatisé. - OpenSSL natif : générez la paire clé/CSR sur une station sécurisée, insérez les SAN dans
openssl.cnf
, puis ne livrez à l’appliance que la clé et le certificat final. - Modèle “Supply in the request” : dans le Certificate Template, cochez Subject Name → Supply in the request pour autoriser la copie de
subjectAltName
depuis la demande.
Exemples prêts à copier
Commande certreq
avec SAN correct (un seul attribut)
certreq -submit `
-attrib "CertificateTemplate:Appliance" `
req.csr
# Tous les SAN sont dans req.csr, pas dans -attrib
INF avec SAN DNS + IP
[Version]
Signature="$Windows NT$"
\[NewRequest]
KeySpec=1
KeyLength=2048
Exportable=TRUE
MachineKeySet=TRUE
RequestType=PKCS10
CertificateTemplate=Appliance
\[Extensions]
2.5.29.17="{text}"
*continue*="dns=app01.contoso.com&"
*continue*="dns=app01&" ; court alias DNS interne
*continue*="ipaddress=192.0.2.15"
Validation rapide après émission
certutil -dump issued.cer | more
Extraction de la chaîne depuis un PFX
openssl pkcs12 -in device.pfx -nodes -out device-all.pem
awk 'BEGIN{RS=""} /BEGIN CERTIFICATE/{print > "device-cert.pem"}' device-all.pem
# Ajustez selon votre politique d’extraction ; vérifiez les en-têtes.
FAQ
Pourquoi un seul SAN apparaît-il lorsque j’utilise -attrib
?
Parce que combiner CertificateTemplate:...
et SAN:...
dans la même chaîne -attrib
conduit certreq
à ne traiter que la première valeur SAN. C’est un comportement couramment observé en production.
Puis-je répéter SAN:
plusieurs fois ?
Non. Utilisez SAN:
une seule fois et séparez les valeurs par &
.
Comment ajouter des SAN IP, e-mail, UPN ?
Dans [Extensions]
: ipaddress=1.2.3.4
, rfc822Name=user@contoso.com
, ou otherName=1.3.6.1.4.1.311.20.2.3;UTF8:upn@contoso.com
.
Le sujet (CN) doit-il être vide ?
Si le modèle impose Supply in the request, laissez le Subject vide et fournissez tout via SAN. Beaucoup de modèles modernes évitent d’utiliser le CN.
Faut-il redémarrer le service CA après changement de stratégie ?
Oui : net stop certsrv & net start certsrv
après avoir modifié les EditFlags.
Que faire si l’appliance n’accepte que PEM ?
Exportez un PFX, puis convertissez-le en PEM avec openssl pkcs12 -nodes
et séparez clé/cert/chaîne.
Erreurs fréquentes et comment les éviter
- Retour à la ligne dans
-attrib
: supprimez-le. La chaîne doit être contiguë. - Espaces accidentels avant/après
&
ou=
: proscrits. - Nom de modèle incorrect (
CertificateTemplate
) : orthographe exacte requise. - Absence de
EDITF_ATTRIBUTESUBJECTALTNAME2
: l’AC n’insèrera pas (ou pas entièrement) les SAN depuis la demande. - Droits d’inscription insuffisants : l’AC peut substituer un modèle par défaut ou refuser des attributs.
Synthèse exécutable
- Constat :
certreq -attrib
combinantCertificateTemplate
et plusieurs SAN ne conserve que le premier SAN. - Solution robuste : placez tous les SAN dans le CSR (INF/OpenSSL/PowerShell). N’utilisez
-attrib
que pour le modèle ou des attributs simples. - Vérifications : modèle configuré en Supply in the request et drapeau
EDITF_ATTRIBUTESUBJECTALTNAME2
activé sur l’AC. - Livraison : si l’appliance ne supporte pas PFX, convertissez en PEM et séparez clé/cert/chaîne.
Procédure express à garder sous la main
; req.inf
[Version]
Signature="$Windows NT$"
[NewRequest]
KeySpec=1
KeyLength=2048
Exportable=TRUE
MachineKeySet=TRUE
RequestType=PKCS10
CertificateTemplate=Appliance
[Extensions]
2.5.29.17="{text}"
_continue_="dns=entry1.contoso.com&"
_continue_="dns=entry2.contoso.com&"
_continue_="dns=entry3.contoso.com"
certreq -new req.inf req.csr
certreq -submit req.csr issued.cer
certreq -accept issued.cer
# Vérifier :
certutil -dump issued.cer | findstr /I "Alternative"
Conclusion
Retenez ceci : pour les SAN multiples avec une AC Microsoft, n’utilisez pas -attrib SAN:...
combiné à CertificateTemplate
. Placez plutôt tous les SAN dans la demande (INF/OpenSSL/PowerShell). Assurez-vous que le modèle et l’AC autorisent la copie de subjectAltName
(EDITF_ATTRIBUTESUBJECTALTNAME2
), puis validez le résultat avec certutil
ou openssl
. Cette approche évite les surprises et garantit un certificat final conforme à vos besoins d’appliance.