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
eintermediate.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.