Diferencia entre revisiones de «Crear un CA para firmar certificados SSL»

De Recursos Educativos
Ir a la navegación Ir a la búsqueda
Sin resumen de edición
 
Línea 51: Línea 51:
Firmar la solicitud de certificado con la CA
Firmar la solicitud de certificado con la CA


  openssl ca -config openssl.conf -extensions v3_req -days 3650 -notext -md sha256 -in csr/${DOMINIO}.csr.pem -out certs/${DOMINIO}.cert.pem     
  openssl ca -config openssl.conf -policy policy_loose -extensions v3_req -days 3650 -notext -md sha256 -in csr/${DOMINIO}.csr.pem -out certs/${DOMINIO}.cert.pem     
  chmod 444 certs/${DOMINIO}.cert.pem
  chmod 444 certs/${DOMINIO}.cert.pem



Revisión actual - 11:16 4 feb 2022

Problema: estamos practicando SSL/TLS y queremos ir más allá de los certificados auto-firmados. Además es un incordio estar añadiendo las excepciones de seguridad en los programas cliente, y además quiero usar comodines en los dominios.

Solución: crear una clave privada+certificado de una CA, usarla para firmar certificados, e importar esa CA a Firefox y Thunderbird para que confien en ella.

Procedimiento

Practicamente todo está tomado de este fantástico artículo Crear autoridad certificadora (CA) y certificados autofirmados en Linux. ¡Muchas gracias Antonio Guillen!

Basicamente lo que ves aquí es una simplificación de ese artículo.

Creamos un directorio vacío como base, aquí va a estar la CA.

export BASE='/root/ca' 
mkdir $BASE
cd $BASE
mkdir certs csr crl newcerts private
chmod 700 private
touch index.txt
touch index.txt.attr
echo 1000 > serial

Creamos el fichero openssl.conf, puedes ver el contenido al final.

Creamos la clave privada de la CA

openssl genrsa -aes256 -out ./private/ca.key.pem 4096
chmod 400 ./private/ca.key.pem

Generamos el certificado de la CA (En Common Name ponemos lo que queramos)

URL=luisantolin.com
export SAN=DNS:$URL
openssl req -config openssl.conf -key private/ca.key.pem -new -x509 -days 7300 -sha256 -extensions v3_ca -out certs/ca.cert.pem
chmod 444 certs/ca.cert.pem

Crear una clave privada para nuestro sitio web.

URL="*.miweb.com"
DOMINIO=$(echo $URL | sed 's/*\.//g' )
openssl genrsa -out ./private/${DOMINIO}.key.pem 2048
chmod 400 ./private/${DOMINIO}.key.pem

Generar la solicitud de certificado (en Common Name ponemos el DOMINIO)

URL="*.miweb.com"
DOMINIO=$(echo $URL | sed 's/*\.//g' )
export SAN=DNS:$URL,DNS:$DOMINIO
openssl req -config openssl.conf -key private/${DOMINIO}.key.pem -new -sha256 -out csr/${DOMINIO}.csr.pem

Firmar la solicitud de certificado con la CA

openssl ca -config openssl.conf -policy policy_loose -extensions v3_req -days 3650 -notext -md sha256 -in csr/${DOMINIO}.csr.pem -out certs/${DOMINIO}.cert.pem    
chmod 444 certs/${DOMINIO}.cert.pem

Convertimos el certificado en DER, por si nos lo piden en ese formato, tenerlo ya

openssl x509 -in certs/${DOMINIO}.cert.pem -out certs/${DOMINIO}.cert.der -outform DER

Ahora hay colocar el certs/DOMINIO.cert.pem y el private/DOMINIO.key.pem al servidor (Apache, o Postfix, o Dovecot), en donde corresponda en cada caso.

Por ultimo hay que importar el certs/ca.cert.pem en los clientes. En Mar-2021, para Firefox Linux y para Thunderbird Linux, en Ubuntu 20.04 LTS el procedimiento es trivial, basta con ir a opciones, buscar certificados, ahi CAs e importar el PEM.

openssl.conf

[ ca ]
# man ca

default_ca = CA_default
 
[ CA_default ]
# Directory and file locations.

dir               = ./
certs             = ./certs
crl_dir           = ./crl
new_certs_dir     = ./newcerts
database          = ./index.txt
serial            = ./serial
RANDFILE          = ./private/.rand
 
# The root key and root certificate.

private_key       = ./private/ca.key.pem
certificate       = ./certs/ca.cert.pem
 
# For certificate revocation lists.

crlnumber         = ./crlnumber
crl               = ./crl/ca.crl.pem
crl_extensions    = crl_ext
default_crl_days  = 30
 
# SHA-1 is deprecated, so use SHA-2 instead.

default_md        = sha256
 
name_opt          = ca_default
cert_opt          = ca_default
default_days      = 375
preserve          = no
policy            = policy_strict
 
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.

# See the POLICY FORMAT section of man ca.

countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
 
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.

# See the POLICY FORMAT section of the ca man page.

countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
 
[ req ]
# Options for the req tool (man req).

default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only
# SHA-1 is deprecated, so use SHA-2 instead.

default_md          = sha256
# Extension to add when the -x509 option is used.

x509_extensions     = v3_ca
# Extension for SANs

req_extensions      = v3_req
 
[ v3_req ]
# Extensions to add to a certificate request

# Before invoke openssl use: export SAN=DNS:value1,DNS:value2

basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = ${ENV::SAN}
 
[ req_distinguished_name ]
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.

countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address
 
# Optionally, specify some defaults.

countryName_default             = CO
stateOrProvinceName_default     = Coruscant
localityName_default            = Ciudad Galactica
0.organizationName_default      = Consejo Jedi
organizationalUnitName_default  = CJ
emailAddress_default            = consejo@templo.jedi.org
 
[ v3_ca ]
# Extensions for a typical CA (man x509v3_config).

subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
 
[ v3_intermediate_ca ]
# Extensions for a typical intermediate CA (man x509v3_config).

subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
 
[ usr_cert ]
# Extensions for client certificates (man x509v3_config).

basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
 
[ server_cert ]
# Extensions for server certificates (man x509v3_config).

basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
 
[ crl_ext ]
# Extension for CRLs (man x509v3_config).

authorityKeyIdentifier=keyid:always
 
[ ocsp ]
# Extension for OCSP signing certificates (man ocsp).

basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning