web-dev-qa-db-fra.com

Comment créer un certificat auto-signé avec OpenSSL

J'ajoute le support HTTPS à un périphérique Linux intégré. J'ai essayé de générer un certificat auto-signé en procédant comme suit:

openssl req -new > cert.csr
openssl rsa -in privkey.pem -out key.pem
openssl x509 -in cert.csr -out cert.pem -req -signkey key.pem -days 1001
cat key.pem>>cert.pem

Cela fonctionne, mais il y a des erreurs avec, par exemple, Google Chrome:

Ce n'est probablement pas le site que vous recherchez!
Le certificat de sécurité du site n'est pas approuvé!

Est-ce que je manque quelque chose? Est-ce la bonne façon de créer un certificat auto-signé?

1127
michelemarcon

Vous pouvez le faire en une seule commande:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365

Vous pouvez également ajouter -nodes (abréviation de no DES) si vous ne souhaitez pas protéger votre clé privée avec une phrase secrète. Sinon, vous serez invité à entrer un mot de passe "au moins 4 caractères".

Le paramètre days (365), que vous pouvez remplacer par un nombre quelconque, a une incidence sur la date d'expiration. Il vous invitera ensuite pour des choses comme "Nom du pays", mais vous pouvez simplement appuyer sur Enter et accepter les valeurs par défaut.

Ajoutez -subj '/CN=localhost' pour supprimer les questions sur le contenu du certificat (remplacez localhost par votre domaine souhaité).

Les certificats auto-signés ne sont validés par aucun tiers, à moins que vous ne les ayez importés auparavant dans les navigateurs. Si vous avez besoin de plus de sécurité, vous devez utiliser un certificat signé par autorité de certification (CA).

1856
Diego Woitasen

Est-ce que je manque quelque chose? Est-ce la bonne façon de créer un certificat auto-signé?

Il est facile de créer un certificat auto-signé. Vous utilisez simplement la commande openssl req. Il peut être délicat d’en créer un qui puisse être utilisé par le plus grand nombre de clients, tels que les navigateurs et les outils de ligne de commande.

C'est difficile parce que les navigateurs ont leurs propres exigences et qu'ils sont plus restrictifs que IETF . Les exigences utilisées par les navigateurs sont décrites dans le Forums CA/Navigateur (voir les références ci-dessous). Les restrictions concernent deux domaines clés: (1) les ancres de confiance et (2) les noms DNS.

Les navigateurs modernes (comme le warez que nous utilisons en 2014/2015) veulent un certificat lié à une ancre de confiance et souhaitent que les noms DNS soient présentés de manière particulière dans le certificat. Et les navigateurs se déplacent activement contre des certificats de serveur auto-signés.

Certains navigateurs ne facilitent pas l'importation d'un certificat de serveur auto-signé. En fait, vous ne pouvez pas utiliser certains navigateurs, comme le navigateur Android. La solution complète consiste donc à devenir votre propre autorité.

En l'absence de devenir votre propre autorité, vous devez obtenir le droit de nommer les noms DNS pour donner au certificat les plus grandes chances de succès. Mais je vous encourage à devenir votre propre autorité. Il est facile de devenir votre propre autorité et vous éviterez tous les problèmes de confiance (qui de mieux en faire confiance que vous-même?).


Ce n'est probablement pas le site que vous recherchez!
Le certificat de sécurité du site n'est pas approuvé!

En effet, les navigateurs utilisent une liste prédéfinie d'ancres de confiance pour valider les certificats de serveur. Un certificat auto-signé ne renvoie pas à une ancre de confiance.

Le meilleur moyen d'éviter cela est:

  1. Créez votre propre autorité (c.-à-d., Devenez un CA )
  2. Créer une demande de signature de certificat (CSR) pour le serveur
  3. Signez la CSR du serveur avec votre clé CA
  4. Installer le certificat de serveur sur le serveur
  5. Installer le certificat de l'autorité de certification sur le client

Étape 1 - Créer votre propre autorité signifie simplement créer un certificat auto-signé avec CA: true et l'utilisation correcte de la clé. Cela signifie que Subject ​​et Issuer sont la même entité, CA est défini sur true dans Basic Constraints (il doit également être marqué comme critique), L'utilisation de la clé est keyCertSign et crlSign (si vous utilisez des CRL), et le identificateur de clé d'objet ​​(SKI) est identique à l'identificateur identificateur de clé d'autorité (AKI).

Pour devenir votre propre autorité de certification, voir * Comment signez-vous une demande de signature de certificat avec votre autorité de certification? sur Stack Overflow. Importez ensuite votre autorité de certification dans le Trust Store utilisé par le navigateur.

Les étapes 2 à 4 correspondent à peu près à ce que vous faites maintenant pour un serveur public lorsque vous faites appel aux services d'une autorité de certification, telle que Startcom ou CAcert . Les étapes 1 et 5 vous permettent d’éviter l’autorité tierce et d’agir en tant que votre propre autorité (qui mieux que vous pouvez avoir confiance en vous?).

Le meilleur moyen d'éviter les avertissements du navigateur consiste à faire confiance au certificat du serveur. Mais certains navigateurs, comme le navigateur par défaut d'Android, ne vous le permettent pas. Donc ça ne marchera jamais sur la plateforme.

La question des navigateurs (et d’autres agents utilisateurs similaires) not ​​faire confiance à des certificats auto-signés va devenir un gros problème dans l’Internet des objets (IoT). Par exemple, que va-t-il se passer lorsque vous vous connecterez à votre thermostat ou à votre réfrigérateur pour le programmer? La réponse est: rien de bon en ce qui concerne l'expérience utilisateur.

Le groupe de travail WebAppSec du W3C commence à examiner la question. Voir, par exemple, Proposition: Marquer HTTP comme non sécurisé .


Comment créer un certificat auto-signé avec OpenSSL

Les commandes ci-dessous et le fichier de configuration créent un certificat auto-signé (il explique également comment créer une demande de signature). Elles diffèrent des autres réponses sur un point: les noms DNS utilisés pour le certificat auto-signé se trouvent dans le Nom alternatif du sujet (SAN), et non le Nom usuel (CN) .

Les noms DNS sont placés dans SAN via le fichier de configuration avec la ligne subjectAltName = @alternate_names (vous ne pouvez pas le faire via la ligne de commande). Ensuite, il y a une section alternate_names dans le fichier de configuration (vous devriez l’accorder à votre goût):

[ alternate_names ]

DNS.1       = example.com
DNS.2       = www.example.com
DNS.3       = mail.example.com
DNS.4       = ftp.example.com

# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

Il est important de mettre le nom DNS dans le SAN et non dans le CN, car les deux les forums IETF et CA/Browser spécifient la pratique. Ils spécifient également que les noms DNS dans le CN sont obsolètes (mais non interdits). Si vous mettez un nom DNS dans le CN, alors il doit ​​être inclus dans le SAN sous les règles CA/B. Donc, vous ne pouvez pas éviter d'utiliser le nom alternatif du sujet.

Si vous ne mettez pas de noms DNS dans le réseau SAN, le certificat ne sera pas validé sous un navigateur ni par d'autres agents d'utilisateur conformes aux instructions du forum CA/Browser.

Connexe: les navigateurs suivent les règles du forum CA/Navigateur; et non les politiques de l'IETF. C'est l'une des raisons pour lesquelles un certificat créé avec OpenSSL (qui suit généralement l'IETF) ne peut parfois pas être validé sous un navigateur (les navigateurs suivent le CA/B). Ce sont des normes différentes, elles ont des politiques d'émission différentes et des exigences de validation différentes.


Créez un certificat auto-signé (notez l'ajout de l'option -x509):

openssl req -config example-com.conf -new -x509 -sha256 -newkey rsa:2048 -nodes \
    -keyout example-com.key.pem -days 365 -out example-com.cert.pem

Créez une demande de signature (notez l'absence de l'option -x509):

openssl req -config example-com.conf -new -sha256 -newkey rsa:2048 -nodes \
    -keyout example-com.key.pem -days 365 -out example-com.req.pem

Imprimez un certificat auto-signé :

openssl x509 -in example-com.cert.pem -text -noout

Imprimer une demande de signature :

openssl req -in example-com.req.pem -text -noout

Fichier de configuration (transmis via l'option -config)

[ req ]
default_bits        = 2048
default_keyfile     = server-key.pem
distinguished_name  = subject
req_extensions      = req_ext
x509_extensions     = x509_ext
string_mask         = utf8only

# The Subject DN can be formed using X501 or RFC 4514 (see RFC 4519 for a description).
#   Its sort of a mashup. For example, RFC 4514 does not provide emailAddress.
[ subject ]
countryName         = Country Name (2 letter code)
countryName_default     = US

stateOrProvinceName     = State or Province Name (full name)
stateOrProvinceName_default = NY

localityName            = Locality Name (eg, city)
localityName_default        = New York

organizationName         = Organization Name (eg, company)
organizationName_default    = Example, LLC

# Use a friendly name here because it's presented to the user. The server's DNS
#   names are placed in Subject Alternate Names. Plus, DNS names here is deprecated
#   by both IETF and CA/Browser Forums. If you place a DNS name here, then you
#   must include the DNS name in the SAN too (otherwise, Chrome and others that
#   strictly follow the CA/Browser Baseline Requirements will fail).
commonName          = Common Name (e.g. server FQDN or YOUR name)
commonName_default      = Example Company

emailAddress            = Email Address
emailAddress_default        = [email protected]

# Section x509_ext is used when generating a self-signed certificate. I.e., openssl req -x509 ...
[ x509_ext ]

subjectKeyIdentifier        = hash
authorityKeyIdentifier    = keyid,issuer

# You only need digitalSignature below. *If* you don't allow
#   RSA Key transport (i.e., you use ephemeral cipher suites), then
#   omit keyEncipherment because that's key transport.
basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage    = serverAuth, clientAuth

# Section req_ext is used when generating a certificate signing request. I.e., openssl req ...
[ req_ext ]

subjectKeyIdentifier        = hash

basicConstraints        = CA:FALSE
keyUsage            = digitalSignature, keyEncipherment
subjectAltName          = @alternate_names
nsComment           = "OpenSSL Generated Certificate"

# RFC 5280, Section 4.2.1.12 makes EKU optional
#   CA/Browser Baseline Requirements, Appendix (B)(3)(G) makes me confused
#   In either case, you probably only need serverAuth.
# extendedKeyUsage    = serverAuth, clientAuth

[ alternate_names ]

DNS.1       = example.com
DNS.2       = www.example.com
DNS.3       = mail.example.com
DNS.4       = ftp.example.com

# Add these if you need them. But usually you don't want them or
#   need them in production. You may need them for development.
# DNS.5       = localhost
# DNS.6       = localhost.localdomain
# DNS.7       = 127.0.0.1

# IPv6 localhost
# DNS.8     = ::1

Vous devrez peut-être procéder comme suit pour Chrome. Sinon Chrome peut se plaindre d'un Nom commun n'est pas valide (ERR_CERT_COMMON_NAME_INVALID) . Je ne suis pas sûr de la relation entre une adresse IP dans le SAN et un CN dans cet exemple.

# IPv4 localhost
# IP.1       = 127.0.0.1

# IPv6 localhost
# IP.2     = ::1

Il existe d'autres règles concernant le traitement des noms DNS dans les certificats X.509/PKIX. Reportez-vous à ces documents pour les règles:

Les documents RFC 6797 et RFC 7469 sont répertoriés, car ils sont plus restrictifs que les autres documents RFC et CA/B. Les RFC 6797 et 7469 ne pas autorisent une adresse IP non plus.

470
jww

Voici les options décrites dans la réponse de @ diegows , décrite plus en détail dans la documentation :

openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days XXX
req

Demande de certificat PKCS # 10 et utilitaire de génération de certificat.

-x509

cette option génère un certificat auto-signé au lieu d'une demande de certificat. Ceci est généralement utilisé pour générer un certificat de test ou une autorité de certification racine auto-signée.

-newkey arg

cette option crée une nouvelle demande de certificat et une nouvelle clé privée. L'argument prend l'une des formes suivantes. rsa: nbits , où nbits est le nombre de bits, génère un Clé RSA nbits en taille.

-keyout filename

cela donne le nom du fichier dans lequel écrire la clé privée nouvellement créée.

-out filename

Ceci spécifie le nom de fichier de sortie à écrire ou la sortie standard par défaut.

-days n

lorsque l'option - x509 est utilisée, elle spécifie le nombre de jours pour certifier le certificat. La valeur par défaut est 30 jours.

-nodes

si cette option est spécifiée, si une clé privée est créée, elle ne sera pas chiffrée.

La documentation est en réalité plus détaillée que celle ci-dessus; Je viens de résumer ici.

389
user456814

À compter de 2019, la commande suivante répond à tous vos besoins, y compris SAN:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -extensions san -config \
  <(echo "[req]"; 
    echo distinguished_name=req; 
    echo "[san]"; 
    echo subjectAltName=DNS:example.com,DNS:example.net,IP:10.0.0.1
    ) \
  -subj /CN=example.com

Dans OpenSSL ≥ 1.1.1, cela peut être réduit à:

openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
  -keyout example.key -out example.crt -subj /CN=example.com \
  -addext subjectAltName=DNS:example.com,DNS:example.net,IP:10.0.0.1

Il crée un certificat qui est

  • valable pour les domaines example.com et example.net (SAN),
  • également valable pour l'adresse IP 10.0.0.1 (SAN),
  • relativement forte (à partir de 2019) et
  • valable pour 3650 jours (~ 10 ans).

Il crée les fichiers suivants:

  • Clé privée: example.key
  • Certificat: example.crt

Toutes les informations sont fournies sur la ligne de commande. Il n'y a pas d'entrée interactive ennuyante. Il n'y a pas de problèmes avec les fichiers de configuration. Toutes les étapes nécessaires sont exécutées par cette seule invocation OpenSSL: depuis la génération de la clé privée jusqu'au certificat auto-signé.

Remarque n ° 1: paramètres de cryptographie

Étant donné que le certificat est auto-signé et doit être accepté manuellement par les utilisateurs, il n’est pas logique d’utiliser une cryptographie à expiration courte ou faible.

À l'avenir, vous voudrez peut-être utiliser plus de 4096 bits pour la clé RSA et un algorithme de hachage plus fort que sha256, mais à compter de 2019, ces valeurs sont saines. Ils sont suffisamment puissants tout en étant supportés par tous les navigateurs modernes.

Remarque n ° 2: paramètre "-nodes"

Théoriquement, vous pouvez omettre le paramètre -nodes (ce qui signifie "pas de DES cryptage"), auquel cas example.key sera crypté avec un mot de passe. Toutefois, cela n’est presque jamais utile pour une installation de serveur, car vous devez également stocker le mot de passe sur le serveur ou le saisir manuellement à chaque redémarrage.

Remarque n ° 3: MinGW

Sous Windows dans MinGW bash, vous devez préfixer la commande avec MSYS_NO_PATHCONV=1:

MSYS_NO_PATHCONV=1 openssl ...

Vous pouvez également exécuter la commande dans l'invite de commandes plain cmd.exe Windows.

Remarque n ° 4: voir aussi

232
vog

Je ne peux pas commenter, alors je vais mettre cela comme une réponse séparée. J'ai trouvé quelques problèmes avec la réponse acceptée sur une ligne:

  • One-Liner inclut une phrase secrète dans la clé.
  • One-Liner utilise SHA-1 qui, dans de nombreux navigateurs, affiche des avertissements dans la console.

Voici une version simplifiée qui supprime la phrase secrète, augmente la sécurité pour supprimer les avertissements et inclut une suggestion dans les commentaires de passer dans -sous afin de supprimer la liste complète des questions:

openssl genrsa -out server.key 2048
openssl rsa -in server.key -out server.key
openssl req -sha256 -new -key server.key -out server.csr -subj '/CN=localhost'
openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

Remplacez 'localhost' par le domaine que vous souhaitez. Vous devrez exécuter les deux premières commandes une par une, car OpenSSL demandera une phrase secrète.

Pour combiner les deux dans un fichier .pem:

cat server.crt server.key > cert.pem
129
Mike N

Les navigateurs modernes génèrent maintenant une erreur de sécurité pour les certificats auto-signés, par ailleurs bien formés, s'il leur manque un SAN (nom alternatif du sujet). OpenSSL ne fournit pas de moyen de commande en ligne de commande pour spécifier cela , donc beaucoup de tutoriels et de signets pour les développeurs. sont soudainement obsolètes.

Le moyen le plus rapide de fonctionner à nouveau est un fichier de configuration court et autonome:

  1. Créez un fichier de configuration OpenSSL (exemple: req.cnf)

    [req]
    distinguished_name = req_distinguished_name
    x509_extensions = v3_req
    Prompt = no
    [req_distinguished_name]
    C = US
    ST = VA
    L = SomeCity
    O = MyCompany
    OU = MyDivision
    CN = www.company.com
    [v3_req]
    keyUsage = critical, digitalSignature, keyAgreement
    extendedKeyUsage = serverAuth
    subjectAltName = @alt_names
    [alt_names]
    DNS.1 = www.company.com
    DNS.2 = company.com
    DNS.3 = company.net
    
  2. Créer le certificat référençant ce fichier de configuration

    openssl req -x509 -nodes -days 730 -newkey rsa:2048 \
     -keyout cert.key -out cert.pem -config req.cnf -sha256
    

Exemple de configuration de https://support.citrix.com/article/CTX135602

72
rymo

Je recommanderais d'ajouter le paramètre - sha256 pour utiliser l'algorithme de hachage SHA-2, car les principaux navigateurs envisagent d'afficher des "certificats SHA-1". comme non sécurisé.

La même ligne de commande de la réponse acceptée - @diegows avec -sha256 ajouté

openssl req -x509 - sha256 -newkey rsa: 2048 -keyout key.pem -out cert.pem -days XXX

Plus d'informations dans blog Google Security .

Mise à jour de mai 2018. Comme beaucoup l'ont mentionné dans les commentaires, l'utilisation de SHA-2 n'apporte aucune sécurité à un certificat auto-signé. Mais je recommande quand même de l’utiliser comme une bonne habitude de ne pas utiliser de fonctions de hachage cryptographique obsolètes/peu sûres. Une explication complète est disponible dans pourquoi est-il préférable que les certificats supérieurs au certificat d'entité finale soient basés sur SHA-1?.

65
Maris B.

C'est le script que j'utilise sur les boîtes locales pour définir le SAN (subjectAltName) dans des certificats auto-signés.

Ce script prend le nom de domaine (exemple.com) et génère le SAN pour * .example.com et exemple.com dans le même certificat. Les sections ci-dessous sont commentées. Nommez le script (par exemple generate-ssl.sh) et accordez-lui des autorisations d'exécution. Les fichiers seront écrits dans le même répertoire que le script.

Chrome 58 et ultérieur nécessite que SAN soit défini dans des certificats auto-signés.

#!/usr/bin/env bash

# Set the TLD domain we want to use
BASE_DOMAIN="example.com"

# Days for the cert to live
DAYS=1095

# A blank passphrase
PASSPHRASE=""

# Generated configuration file
CONFIG_FILE="config.txt"

cat > $CONFIG_FILE <<-EOF
[req]
default_bits = 2048
Prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn

[dn]
C = CA
ST = BC
L = Vancouver
O = Example Corp
OU = Testing Domain
emailAddress = webmaster@$BASE_DOMAIN
CN = $BASE_DOMAIN

[v3_req]
subjectAltName = @alt_names

[alt_names]
DNS.1 = *.$BASE_DOMAIN
DNS.2 = $BASE_DOMAIN
EOF

# The file name can be anything
FILE_NAME="$BASE_DOMAIN"

# Remove previous keys
echo "Removing existing certs like $FILE_NAME.*"
chmod 770 $FILE_NAME.*
rm $FILE_NAME.*

echo "Generating certs for $BASE_DOMAIN"

# Generate our Private Key, CSR and Certificate
# Use SHA-2 as SHA-1 is unsupported from Jan 1, 2017

openssl req -new -x509 -newkey rsa:2048 -sha256 -nodes -keyout "$FILE_NAME.key" -days $DAYS -out "$FILE_NAME.crt" -passin pass:$PASSPHRASE -config "$CONFIG_FILE"

# OPTIONAL - write an info to see the details of the generated crt
openssl x509 -noout -fingerprint -text < "$FILE_NAME.crt" > "$FILE_NAME.info"

# Protect the key
chmod 400 "$FILE_NAME.key"

Ce script écrit également un fichier d'informations. Vous pouvez ainsi inspecter le nouveau certificat et vérifier que le SAN est défini correctement.

                ...
                28:dd:b8:1e:34:b5:b1:44:1a:60:6d:e3:3c:5a:c4:
                da:3d
            Exponent: 65537 (0x10001)
    X509v3 extensions:
        X509v3 Subject Alternative Name: 
            DNS:*.example.com, DNS:example.com
Signature Algorithm: sha256WithRSAEncryption
     3b:35:5a:d6:9e:92:4f:fc:f4:f4:87:78:cd:c7:8d:cd:8c:cc:
     ...

Si vous utilisez Apache, vous pouvez référencer le certificat ci-dessus dans votre fichier de configuration de la manière suivante:

<VirtualHost _default_:443>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/htdocs

    SSLEngine on
    SSLCertificateFile path/to/your/example.com.crt
    SSLCertificateKeyFile path/to/your/example.com.key
</VirtualHost>

N'oubliez pas de redémarrer votre serveur Apache (ou Nginx ou IIS) pour que le nouveau certificat prenne effet.

18
Drakes

2017 one-liner:

openssl req \
-newkey rsa:2048 \
-x509 \
-nodes \
-keyout server.pem \
-new \
-out server.pem \
-subj /CN=localhost \
-reqexts SAN \
-extensions SAN \
-config <(cat /System/Library/OpenSSL/openssl.cnf \
    <(printf '[SAN]\nsubjectAltName=DNS:localhost')) \
-sha256 \
-days 3650

Cela fonctionne également dans Chrome 57, car il fournit le réseau de stockage sans disposer d'un autre fichier de configuration. Il a été tiré d'une réponse ici .

Cela crée un fichier .pem unique contenant à la fois la clé privée et le certificat. Vous pouvez les déplacer vers des fichiers .pem séparés si nécessaire.

9
joemillervi

Une doublure FTW. J'aime garder les choses simples. Pourquoi ne pas utiliser une commande contenant TOUS les arguments nécessaires? C'est comme ça que je l'aime - cela crée un certificat x509 et sa clé PEM:

openssl req -x509 \
 -nodes -days 365 -newkey rsa:4096 \
 -keyout self.key.pem \
 -out self-x509.crt \
 -subj "/C=US/ST=WA/L=Seattle/CN=example.com/[email protected]"

Cette commande unique contient toutes les réponses que vous auriez normalement fournies pour les détails du certificat. De cette façon, vous pouvez définir les paramètres et exécuter la commande, obtenir votre sortie - puis opter pour le café.

>> Plus ici <<

6
OkezieE

Vous avez la procédure générale correcte. La syntaxe de la commande est la suivante.

openssl req -new -key {private key file} -out {output file}

Toutefois, les avertissements sont affichés, car le navigateur n'a pas pu vérifier l'identité en validant le certificat avec une autorité de certification connue.

S'agissant d'un certificat auto-signé, il n'y a pas de CA et vous pouvez ignorer l'avertissement et continuer en toute sécurité. Si vous souhaitez obtenir un véritable certificat reconnaissable par tous les internautes, la procédure est la suivante.

  1. Générer une clé privée
  2. Utiliser cette clé privée pour créer un fichier CSR
  3. Soumettre le CSR à CA (Verisign ou autres, etc.)
  4. Installer le certificat reçu de l'autorité de certification sur le serveur Web
  5. Ajouter d'autres certificats à la chaîne d'authentification en fonction du type de certificat

J'ai plus de détails à ce sujet dans un article à l'adresse Sécurisation de la connexion: création d'un certificat de sécurité avec OpenSSL

6
nneko

Version monocouche 2017:

CentOS:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/pki/tls/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))

buntu:

openssl req -x509 -nodes -sha256 -newkey rsa:2048 \
-keyout localhost.key -out localhost.crt \
-days 3650 \
-subj "CN=localhost" \
-reqexts SAN -extensions SAN \
-config <(cat /etc/ssl/openssl.cnf <(printf "\n[SAN]\nsubjectAltName=IP:127.0.0.1,DNS:localhost"))
4
user327843

Générer des clés

J'utilise /etc/mysql pour le stockage de certificats, car /etc/apparmor.d/usr.sbin.mysqld contient /etc/mysql/*.pem r.

Sudo su -
cd /etc/mysql
openssl genrsa -out ca-key.pem 2048;
openssl req -new -x509 -nodes -days 1000 -key ca-key.pem -out ca-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout server-key.pem -out server-req.pem;
openssl x509 -req -in server-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem;
openssl req -newkey rsa:2048 -days 1000 -nodes -keyout client-key.pem -out client-req.pem;
openssl x509 -req -in client-req.pem -days 1000 -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem;

Ajouter une configuration

/etc/mysql/my.cnf

[client]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/client-cert.pem
ssl-key=/etc/mysql/client-key.pem

[mysqld]
ssl-ca=/etc/mysql/ca-cert.pem
ssl-cert=/etc/mysql/server-cert.pem
ssl-key=/etc/mysql/server-key.pem

Sur ma configuration, le serveur Ubuntu s'est connecté à: /var/log/mysql/error.log

Notes de suivi:

  • SSL error: Unable to get certificate from '...'

    MySQL peut se voir refuser l'accès en lecture à votre fichier de certificat s'il ne fait pas partie de la configuration d'apparmors . Comme indiqué aux étapes précédentes ^, enregistrez tous nos certificats sous forme de fichiers .pem dans le répertoire /etc/mysql/ approuvé par défaut par apparmor (ou modifiez votre application/sELinux pour autoriser l’accès où que vous soyez stocké. )

  • SSL error: Unable to get private key

    Votre version de serveur MySQL peut ne pas supporter le format rsa:2048 par défaut

    Convertissez rsa:2048 générée en plain rsa avec:

    openssl rsa -in server-key.pem -out server-key.pem
    openssl rsa -in client-key.pem -out client-key.pem
    
  • Vérifiez si le serveur local supporte SSL :

    mysql -u root -p
    mysql> show variables like "%ssl%";
    +---------------+----------------------------+
    | Variable_name | Value                      |
    +---------------+----------------------------+
    | have_openssl  | YES                        |
    | have_ssl      | YES                        |
    | ssl_ca        | /etc/mysql/ca-cert.pem     |
    | ssl_capath    |                            |
    | ssl_cert      | /etc/mysql/server-cert.pem |
    | ssl_cipher    |                            |
    | ssl_key       | /etc/mysql/server-key.pem  |
    +---------------+----------------------------+
    
  • La vérification d'une connexion à la base de données est cryptée SSL :

    Vérification de la connexion

    Une fois connecté à l'instance MySQL, vous pouvez émettre la requête:

    show status like 'Ssl_cipher';
    

    Si votre connexion n'est pas cryptée, le résultat sera vide:

    mysql> show status like 'Ssl_cipher';
    +---------------+-------+
    | Variable_name | Value |
    +---------------+-------+
    | Ssl_cipher    |       |
    +---------------+-------+
    1 row in set (0.00 sec)
    

    Sinon, il afficherait une chaîne de longueur non nulle pour le chiffrement utilisé:

    mysql> show status like 'Ssl_cipher';
    +---------------+--------------------+
    | Variable_name | Value              |
    +---------------+--------------------+
    | Ssl_cipher    | DHE-RSA-AES256-SHA |
    +---------------+--------------------+
    1 row in set (0.00 sec)
    
  • Requiert ssl pour une connexion utilisateur spécifique ('Requiert ssl'):

    • SSL

    Indique au serveur d'autoriser uniquement les connexions chiffrées par SSL pour le compte.

    GRANT ALL PRIVILEGES ON test.* TO 'root'@'localhost'
      REQUIRE SSL;
    

    Pour se connecter, le client doit spécifier l'option --ssl-ca pour authentifier le certificat de serveur et peut également spécifier les options --ssl-key et --ssl-cert. Si ni l'option --ssl-ca, ni l'option --ssl-capath n'est spécifiée, le client n'authentifie pas le certificat du serveur.


Lien alternatif: long tutoriel en connexion sécurisée PHP à MySQL avec SSL.

3
ThorSummoner

Comme cela a été discuté en détail, certificats auto-signésne sont pas fiables pour Internet . Vous pouvez ajouter votre certificat auto-signé à de nombreux navigateurs, mais pas à tous . Sinon, vous pouvez devenir votre propre autorité de certification .

La raison principale pour laquelle on ne veut pas obtenir un certificat signé d'une autorité de certification est son coût - Symantec facture entre 995 USD et 1 999 USD par an pour les certificats; rien que pour un certificat destiné au réseau interne, Symantec facture 399 USD par an. . Ce coût est facile à justifier si vous traitez des paiements par carte de crédit ou travaillez pour le centre de profit d’une entreprise très rentable. C’est bien plus que ce que beaucoup peuvent se permettre pour un projet personnel qu’on crée sur Internet, pour un budget modeste ou pour un organisme sans but lucratif, ou si l’on travaille dans le centre de coûts d’une organisation - les centres de coûts essaient toujours d’en faire plus. avec moins.

Une alternative consiste à utiliser certbot (voir à propos de certbot ). Certbot est un client automatique facile à utiliser qui récupère et déploie des certificats SSL/TLS pour votre serveur Web.

Si vous installez certbot, vous pouvez lui permettre de créer et de gérer un certificat pour vous émis par l’autorité de certification Let’s Encrypt .

Je l'ai fait pendant le week-end pour mon organisation. J'ai installé les packages requis pour certbot sur mon serveur (Ubuntu 16.04), puis j'ai exécuté la commande nécessaire à la configuration et à l'activation de certbot. Il faut probablement un plugin DNS pour certbot - nous utilisons actuellement DigitalOcean même si nous allons bientôt migrer vers un autre service.

Notez que certaines des instructions n'étaient pas tout à fait correctes et ont pris un peu de temps avec Google pour comprendre. Cela a pris pas mal de temps la première fois mais maintenant je pense que je pourrais le faire en quelques minutes.

Pour DigitalOcean, j'ai eu du mal à résoudre le problème lorsque j'ai été invité à saisir le chemin d'accès à votre fichier de données d'identification DigitalOcean INI. Le script fait référence à la page Applications & API et à l'onglet Tokens/Key de cette page. Vous devez disposer ou générer un jeton d'accès personnel (lecture et écriture) pour l'API de DigitalOcean - il s'agit d'une chaîne hexadécimale de 65 caractères. Cette chaîne doit ensuite être placée dans un fichier sur le serveur Web à partir duquel vous exécutez certbot. Ce fichier peut avoir un commentaire en première ligne (les commentaires commencent par #). La seconde ligne est:

dns_digitalocean_token = 0000111122223333444455556666777788889999aaaabbbbccccddddeeeeffff

Une fois que j'ai compris comment configurer un jeton lecture + écriture pour l'API de DigitalOcean, il était assez facile d'utiliser certbot pour configurer un certificat générique . Notez qu'il n'est pas nécessaire de configurer un certificat générique, vous pouvez spécifier chaque domaine et sous-domaine auquel vous souhaitez que le certificat s'applique. C'était le certificat générique qui nécessitait les informations d'identification INI contenant le jeton d'accès personnel de DigitalOcean.

Notez que les certificats de clé publique (également appelés certificats d'identité ou certificats SSL) expirent et doivent être renouvelés. Ainsi, vous devrez renouveler votre certificat sur une base périodique (récurrente). La documentation de certbot couvre renouvellement des certificats .

Mon plan est d'écrire un script utilisant la commande openssl pour obtenir la date d'expiration de mon certificat et pour déclencher le renouvellement lorsqu'il tombe 30 jours ou moins avant son expiration. Je vais ensuite ajouter ce script à cron et l'exécuter une fois par jour.

Voici la commande pour lire la date d'expiration de votre certificat:

root@prod-Host:~# /usr/bin/openssl x509 -enddate -noout -in path-to-certificate-pem-file
notAfter=May 25 19:24:12 2019 GMT
3
Peter Jirak Eldritch

Des scripts de création de chaîne de certificats et de certificats auto-signés pour RSA et ECDSA à l'aide d'OpenSSL sont disponibles ici.

0
rashok