Saltar al contenido principal
Version: 1.7.1

Configurar Certificados de Prueba

Para realizar pruebas básicas se puede disponer de certificados autofirmados, recuerde que estos certificados NO son válidos para un entorno productivo y que los navegadores solicitarán agregar excepciones para permitir la navegación.

Previo a la generación de los certificados, asegurese de haber cumplimentado los pasos previos.

Generando Certificados de prueba

Primeramente generamos un directorio para contener los certificados en cuestion:

mkdir -p prod/servicios/certs
cd prod/servicios/certs

Si aún no realizo el siguiente paso, es un buen momento:

export DOMAIN_NAME_URL=universidad.edu.ar

Pasos para construir una CA y sus certificados correspondientes:

Crear CA raíz e intermedia

  • Paso 1 Crear la estructura de directorios para OpenSSL Root CA

Se puede crear sin ninguna estructura de directorios y utilizando algunos ajustes manuales, lo haremos de esta manera para una mejor comprensión. Crearemos nuestra estructura de directorios de la siguiente manera prod/servicios/certs/srv/tls para almacenar nuestros certificados.

mkdir /srv/tls
cd /srv/tls

Dentro del directorio raíz de la CA (srv/tls), necesitamos crear dos subdirectorios:

mkdir certs private	

Tambien tenemos que crear dos archivos que necesita nuestra infraestructura de CA (todo esto dentro de tls/).

Un archivo de serie que se utiliza para realizar un seguimiento del último número de serie que se utilizó para emitir un certificado:

echo 01 > serial

Luego crearemos el archivo index.txt que realiza un seguimiento de los certificados emitidos por la CA

touch index.txt

finalizado con esto el contenido de srv/tls nos debería quedar de la siguiente manera:

drwxr-xr-x 2 root root 4096 Apr  8 22:29 certs
-rw-r--r-- 1 root root 0 Apr 9 03:36 index.txt
drwxr-xr-x 2 root root 4096 Apr 9 03:34 private
-rw-r--r-- 1 root root 3 Apr 9 03:37 serial
  • Paso 2 Configurar openssl.cnf para el certificado de CA raíz

Crearemos el archivo openssl.cnf en la ubicación de nuestro certificado, en nuestro caso srv/tls, cada uno de los siguientes pasos van en este archivo, no saltear ninguno (Tener en cuenta que para una maquina de distribucion debian podemos encontrar el archivo default openssl.cnf en /etc/ssl/openssl.cnf, pero a fines de esta guia en vez de usarse ese archivo crearemos uno con los parametros indicados):

HOME                    = .
#RANDFILE = $ENV::HOME/.rnd
oid_section = new_oids

#openssl_conf = default_modules

#[ default_modules ]
#ssl_conf = ssl_module

#[ ssl_module ]
#system_default = crypto_policy

#[ crypto_policy ]
#.include /etc/crypto-policies/back-ends/opensslcnf.config

[ new_oids ]

En la sección [ CA_default ] contiene una variedad de valores predeterminados. Tenemos que declarar el directorio que elegimos anteriormente srv/tls.

[ ca ]
default_ca = CA_default # The default ca section

[ CA_default ]
dir = /srv/tls # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
database = $dir/index.txt # database index file.
# several certs with same subject.
new_certs_dir = $dir/certs # default place for new certs.
certificate = $dir/certs/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
private_key = $dir/private/cakey.pem # The private key

name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options

default_days = 365 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha256 # use SHA-256 by default
preserve = no # keep passed DN ordering
policy = policy_match

Aplicaremos policy_match para crear certificados de CA raíz

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

Y policy_anything para crear certificados de CA intermedios

[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

Los valores de la sección [req] se aplican al crear solicitudes de firma de certificado (CSR) o certificados.

[ req ]
default_bits = 4096
default_md = sha256
default_keyfile = privkey.pem
distinguished_name = req_distinguished_name
x509_extensions = v3_ca
string_mask = nombstr

req_distinguished_name determina cómo obtiene OpenSSL la información que necesita para completar el nombre distinguido del certificado.

[ req_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = AR
countryName_min = 2
countryName_max = 2
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = BS-AS
localityName = Locality Name (eg, city)
localityName_default = CABA
0.organizationName = Organization Name (eg, company)
0.organizationName_default = SIU
organizationalUnitName = Organizational Unit Name (eg, section)
commonName = Common Name
commonName_max = 64
emailAddress = Email Address
emailAddress_max = 64

Usaremos la extensión v3_ca para crear el certificado de CA raíz y la extensión v3_intermediate para el certificado de CA intermedio

[ v3_ca ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always,issuer
basicConstraints = critical,CA:true

[ v3_intermediate_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
keyUsage = critical, digitalSignature, cRLSign, keyCertSign

Con esto ya tendriamos nuestro archivo openssl.cnf

  • Paso 3 Generar Root CA Private Key

Dentro de la carpeta tls/ . Creamos un archivo de texto sin formato mypass con nuestra frase de contraseña secret:

echo secret > mypass

Usando openssl enc, ciframos el archivo mypass y cramos un archivo cifrado mypass.enc

openssl enc -aes256 -pbkdf2 -salt -in mypass -out mypass.enc

Ya tenemos cifrado el contenido, ahora puedemos compartir este archivo cifrado con cualquier usuario para generar un certificado SSL

cat mypass.enc

Se puede desifrar usando este comando:

openssl enc -aes256 -pbkdf2 -salt -d -in mypass.enc
enter aes-256-cbc decryption password:

Ya teniendo mipass.enc podemos seguir con este paso.

Crearemos una clave de CA raíz usando 4096 bits y encriptación 3DES, usaremos mypass.enc para proporcionar la frase de contraseña para la clave privada. Guardaremos esta clave privada en srv/tls/private

openssl genrsa -des3 -passout file:mypass.enc -out private/cakey.pem 4096

IMPORTANTE: Si esta clave se ve comprometida, la integridad de la CA se ve comprometida, lo que significa que los certificados emitidos (se hayan emitido antes o después de que la clave se viera comprometida) ya no se puede confiar en ellos.

  • Paso 4 Creamos nuestro certificado de CA raíz

Nota: esta bueno distinguir el common name (CN) de cada uno de los certificados a la hora de crearlos, ejemplo:

CA Root -->  CN --> Root CA
CA Intermedia --> CN --> Intermedia

Asignaremos al certificado raíz una fecha de caducidad larga, ya que una vez que caduca el certificado raíz, todos los certificados firmados por la CA pierden su validez.

openssl req -new -x509 -days 3650 -passin file:mypass.enc -config openssl.cnf -extensions v3_ca -key private/cakey.pem -out certs/cacert.pem

cambiamos el formato del CRT a formato PEM

openssl x509 -in certs/cacert.pem -out certs/cacert.pem -outform PEM

Ejecutamos el siguiente comando para que openssl verifique el certificado de CA raíz

openssl x509 -noout -text -in certs/cacert.pem
  • Paso 5 Crear el directorio de CA intermedia OpenSSL

Necesitaremos un certificado intermedio para el paquete de CA. Crearemos una nueva estructura de directorios srv/tls/intermediate en nuestra carpeta principal srv/tls para mantener separados ambos archivos de certificado.

mkdir /srv/tls/intermediate
cd /srv/tls/intermediate

A su vez crearemos subdirectorios en srv/tls/intermediate para almacenar nuestras claves y archivos de certificados.

mkdir certs csr private
touch index.txt
echo 01 > serial

Agregamos un archivo crlnumber al árbol de directorios de CA intermedio, este se utiliza para realizar un seguimiento de las listas de revocación de certificados.

echo 01 > /srv/tls/intermediate/crlnumber
  • Paso 6 Configurar openssl.cnf para el certificado de CA intermedio

Copiamos el archivo openssl.cnf utilizado para el Certificado de CA raíz de srv/tls/openssl.cnf a srv/tls/intermediate/openssl.cnf. Aca se muestran las configuraciones que debemos cambiar:

dir             = /srv/tls/intermediate               # Where everything is kept
certificate = $dir/certs/intermediate.cacert.pem # The CA certificate
private_key = $dir/private/intermediate.cakey.pem # The private key
policy = policy_anything
  • Paso 7 Generar CA intermedia

Generaremos la clave CA intermedia ca-intermediate.key. usando openssl genrsa con cifrado 3DES y nuestro archivo de frase de contraseña cifrada (mypass.enc).

openssl genrsa -des3 -passout file:mypass.enc -out intermediate/private/intermediate.cakey.pem 4096
  • Paso 8 Crear immediate CA Certificate Signing Request (CSR)

Utilizaremos la intermediate CA key para crear la solicitud de firma de certificado (CSR).

Los detalles generalmente deben coincidir con la CA raíz.

El Common Name, sin embargo, debe ser diferente (ej: EEI CSR Intermediate CA).

openssl req -new -sha256 -config intermediate/openssl.cnf -passin file:mypass.enc  -key intermediate/private/intermediate.cakey.pem -out intermediate/csr/intermediate.csr.pem
  • Paso 9 Firmar y generar certificado CA intermedio

El último paso antes de concluir la cadena de certificados de creación de openssl, necesitamos crear un certificado de CA inmediato utilizando nuestra solicitud de firma de certificado que creamos en el paso anterior. Usaremos la extensión v3_intermediate_ca de srv/tls/openssl.cnf para crear el certificado de CA intermedio en srv/tls/intermediate/certs/intermediate.cacert.pem

openssl ca -config openssl.cnf -extensions v3_intermediate_ca -days 2650 -notext -batch -passin file:mypass.enc -in intermediate/csr/intermediate.csr.pem -out intermediate/certs/intermediate.cacert.pem

OpenSSL verify Certificate

openssl x509 -noout -text -in intermediate/certs/intermediate.cacert.pem

A continuación, openssl verifica el certificado intermedio contra el certificado raíz. Un OK indica que la cadena de confianza está intacta.

openssl verify -CAfile certs/cacert.pem intermediate/certs/intermediate.cacert.pem

para convertir el formato del CRT a formato PEM

openssl x509 -in intermediate/certs/intermediate.cacert.pem -out intermediate/certs/intermediate.cacert.pem -outform PEM
  • Paso 10 Crear una cadena de certificados (Certificate Chain)

Combinamos los certificados CA raíz e intermedio para abrir una cadena de certificados en Linux. Usaremos este archivo más adelante para verificar los certificados firmados por la CA intermedia.

cat intermediate/certs/intermediate.cacert.pem certs/cacert.pem > intermediate/certs/ca-chain-bundle.cert.pem

OpenSSL verify Certificate Chain

Para verificar la cadena de certificados, usaremos el siguiente comando

openssl verify -CAfile certs/cacert.pem intermediate/certs/ca-chain-bundle.cert.pem

Certificados para el servidor

  • Primero crearemos la clave privada del servidor (en nuestro caso server.key.pem) usando el comando openssl.
openssl genrsa -out server.key.pem 4096
  • Crear Certificate Signing Request (CSR) usando la clave del servidor

Usaremos nuestra clave de servidor server.key.pem para generar el Certificate Signing Request (CSR) server.csr usando el comando openssl. En este paso es muy importante que proporcione el nombre de host o el valor de la dirección IP de su nodo de servidor en Common Name o nos fallará

openssl req -new -key server.key.pem -out server.csr
  • Configurar las extensiones de openssl x509 para el certificado del servidor

Debemos crear un archivo en tls/ llamado server_cert_ext.cnf. con los siguientes parametros (mas info):

basicConstraints = CA:FALSE
nsCertType = server
nsComment = "Ambiente EEI dev"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
  • Crear certificado de servidor

Usaremos el certificado de CA (certificate bundle) y la clave de CA de nuestro artículo anterior para emitir y firmar el certificado. Este comando creará un certificado de servidor server.cert.pem

openssl x509 -req -in server.csr -passin file:mypass.enc -CA /srv/tls/intermediate/certs/ca-chain-bundle.cert.pem -CAkey /srv/tls/intermediate/private/intermediate.cakey.pem -out server.cert.pem -CAcreateserial -days 365 -sha256 -extfile server_cert_ext.cnf

Una vez tengamos el server.key.pem y server.cert.pem deberíamos crear el docker config y secret para el traefik:

docker secret create traefik_tls_key /srv/tls/server.key.pem
docker config create traefik_tls_cert /srv/tls/server.cert.pem
cd prod/servicios/
sed -i 's/--api.dashboard=false/--api.dashboard=true/' traefik.yml
sed -i 's/frameDeny = true/frameDeny = false/' security.toml

Y para finalizar procederemos a deployar el servicio traefik.yml: docker stack deploy -c traefik.yml traefik

ca-certificates.crt

Extraer ca-certificates.crt de un contenedor para así luego poder mapearlo en los contenedores necesarios:

  • Para extraer el ca-certificate lo haremos con el siguiente comando, en este tendremos que setear dos variables (RUTA_CACERT_PEM y RUTA_INTERMEDIATE_CACERT_PEM) las cuales debemos cambiar a donde nosotros tengamos el cacert.pem e intermediate.cacert.pem:
RUTA_CACERT_PEM=/srv/tls/certs
RUTA_INTERMEDIATE_CACERT_PEM=/srv/tls/intermediate/certs

Luego ejecutamos el comando:

docker run --rm --name cert-build \
-v $RUTA_CACERT_PEM/cacert.pem:/usr/local/share/ca-certificates/cacert.pem \
-v $RUTA_INTERMEDIATE_CACERT_PEM/intermediate.cacert.pem:/usr/local/share/ca-certificates/intermediate.cacert.pem \
-v $RUTA_CACERT_PEM:/tmp \
hub.siu.edu.ar:5005/siu/expedientes/arai-usuarios/idm:v3.1.9 \
-- "update-ca-certificates && cp /etc/ssl/certs/ca-certificates.crt /tmp"

Este nos traerá el archivo ca-certificates.crt en nuestra carpeta certs/ dentro de tls/

  • Teniendo esto lo mapearemos en los servicios necesarios (ej: sudocu_api-server , huarpe_webapp, etc):

primeramente generamos un config de docker:

docker config create ca-certificates ca-certificates.crt

Luego procedemos a mapearlo en el yml del servicio que queramos (solo debemos cambiar el yml por el cual necesitemos):

sed -i -e 's/^\    configs:/\    configs:\n\      -\ source:\ ca-certificates\n\        target:\ \/etc\/ssl\/certs\/ca-certificates.crt/' huarpe.yml

y config global

sed -i -e 's/^configs:/configs:\n\  ca-certificates:\n\    external:\ true/' huarpe.yml

Mapear certificados en servidor (opcional)

Si queremos meter los certificados (cacert.pem y intermediate.cacert.pem) en un servidor seria de la siguiente manera:

En Debian

Debian only supports certificates in the X509 form, aka. .crt

mv cacert.pem /usr/local/share/ca-certificates/cacert.crt
mv intermediate.cacert.pem /usr/local/share/ca-certificates/intermediate.cacert.crt
update-ca-certificates

En alpine

apk add ca-certificates
mv cacert.pem /usr/local/share/ca-certificates/
mv intermediate.cacert.pem /usr/local/share/ca-certificates/
update-ca-certificates

Configurando los certificados generados

Para utilizar sus certificados es necesario cargar la clave pública como una config y la key como un secret:

docker config create traefik_tls_cert servicios/certs/${DOMAIN_NAME_URL}.crt
docker secret create traefik_tls_key servicios/certs/${DOMAIN_NAME_URL}.key

Luego de realizados estos pasos, continue con el procedimiento de despliegue.