Cert-Manager
Si no tenemos certificados propios, la mejor opción es Let's Encrypt. A partir de cert-manager, podemos crear y renovar estos certificados automáticamente, tanto para servicios públicos (extranet) como privados (intranet).
En cualquier caso, necesitamos un dominio de internet válido y que el DNS resuelva el dominio. Su coste es bajo y podemos contratarlo en casi cualquier lugar.
Cert-manager se configura a partir de anotaciones en caso de utilizar Ingress mediante Nginx, así que solo hará falta ajustar estos Ingress o los Helm que los generan.
Tipo de validación
El proceso de petición y obtención del certificado requiere que validemos que el dominio es nuestro, para ello existen dos tipos de validaciones.
Este es un resumen de ambos y recomiendo leer sus artículos para obtener más información:
- HTTP01: La más sencilla y rápida. Ingress publica una URL y Let's encrypt la valida. Tiene dos requerimientos: el subdominio debe ser público (no permite intranet) y debe ser creado antes de hacer la petición.
- DNS01: Let's encrypt envía un código de validación a añadir como
TXT
en nuestra DNS. Una vez detectada, lo valida y acepta el certificado, tras ello se puede borrar elTXT
. Es más lento ya que los DNS tienen tiempo de recarga y requiere que nuestro DNS disponga de un servicio de modificación por API o similar.
Partiendo de esto, asignamos una validación HTTP01
para el Ingress de extranet y otro de DNS01
para el de intranet.
DNS01
Antes de empezar, como he indicado, DNS01
requiere una API para modificar las DNS automáticamente. Por desgracia, muchos registradores de dominio no tienen esta opción.
Existen manuales oficiales para varias clouds:
- AWS Route53
- Azure DNS
- Digital Ocean Y la comunidad ha creado webhooks para diferentes registradores de renombre como OVH.
Si el tuyo no es ninguno de ellos y no puedes/quieres cambiar de registrador. ¡Bienvenid@ al club! Tienes varias opciones:
- Desplegar un servidor de DNS limitado con ACMEDNS únicamente para estas validaciones.
- Dejarte de historias y transferir el control de tu DNS a Cloudflare u otro compatible por cert-manager.
Después de pensar en los problemas que tendría con ACMEDNS (revisión de la instalación, añadir más controles al DNS, mantenimiento, explosiones, ...), he optado por transferir el control del DNS a Cloudflare. Es gratuito y de paso te añade otros controles (y ojo, que Cloudflare también modifica a HTTPS y utiliza Let's Encrypt en tus webs si así lo deseas).
Cada registrador de dominio es diferente, así que hay que acceder o preguntar a estos para ver cómo transferir el control.
Nuestro registrador seguirá siendo el encargado de los pagos y renovación del dominio, así como otros servicios (como e-mail). Solo transferimos el control de la DNS.
Cloudflare
Unos detalles para antes de terminar el traspaso del dominio a Cloudflare:
DNS - Records
: Por defecto los DNS se crean de tipoProxied
, esto significa que Cloudflare oculta la IP real y hace deproxy
ocache
. Al hacer esto (y con otras configuraciones que tiene por defecto), añade certificados de Let's Encrypt a nuestras webs y las hace pasar a HTTPS. Teniendo esto configurado, podemos obviar el obtener certificados para estas. La recomendación es tenerlos igualmente para evitar fallos de seguridad.SSL/TLS - Overview
: Nuestro Ingress hace redirección obligatoria de HTTP a HTTPS, y Cloudflare en modoFlexible
también, así que provocará un error de redirecciones. Cambiar aFull
para evitar el problema y tener control total.
Para que cert-manager acceda, necesita una API. Creamos un token con los permisos para ello
cert-manager permite utilizar el token de usuario directamente, algo que nunca deberíamos hacer.
Accedemos a My Profile - API Tokens
para crear un token con los permisos:
Zone - DNS - Edit
Zone - Zone - Read
Y con acceso al dominio que debe controlar, o a todos ellos en caso de tener múltiples.
Nos guardamos el token para cuando lo vayamos a configurar.
Despliegue
Más detalles en Artifact Hub.
Añadimos el repositorio.
helm repo add cert-manager https://charts.jetstack.io
helm repo update
Desplegamos indicando que genere los Custom Resources (CRD).
helm install cert-manager cert-manager/cert-manager \
--namespace cert-manager-system --create-namespace \
--set installCRDs=true
A partir de aquí tenemos que crear la configuración de uso acorde a cada validación.
Let's Encrypt tiene el servidor de producción que genera certificados válidos, y el de staging
que ofrece certificados para hacer pruebas. La principal diferencia es que este permite más duplicados, ideal para cuando estamos probando un sistema por primera vez.
Para utilizarlo, cambiar los valores de server
por https://acme-staging-v02.api.letsencrypt.org/directory
HTTP01
El más sencillo, asignamos un e-mail y el Ingress que tiene el control de la extranet.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-http-prod
spec:
acme:
email: [email protected]
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-http-prod
solvers:
- http01:
ingress:
ingressClassName: nginx-extranet
DNS01 con Cloudflare
Seguir el manual oficial para registradores diferentes a Cloudflare.
El token se debe crear en un secret
y este debe estar en el mismo namepace
que cert-manager.
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: cert-manager-system
type: Opaque
stringData:
api-token: <api-token>
Similar al anterior, se indica el e-mail, el usuario de Cloudflare y el secret
de su token.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns-prod
spec:
acme:
email: [email protected]
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-dns-prod
solvers:
- dns01:
cloudflare:
email: [email protected]
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
El e-mail que asignamos a Let's Encrypt puede ser diferente al utilizado en Cloudflare.
Ingress
Ingress se debe ajustar para indicar a quien debe llamar (http
o dns
) y además se debe añadir la configuración del tls
y el secret
donde guardará el certificado recibido.
Debido a que los servicios explicados en esta web están en continua actualización, si se quiere usar certificados con cert-manager, se debe ajustar los ejemplos para ello.
Versión para extranet:
metadata:
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-http-prod"
spec:
hosts:
- subdomain.domain.cat
tls:
- hosts:
- subdomain.domain.cat
secretName: service-tls
Versión para intranet:
metadata:
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-http-prod"
spec:
hosts:
- subdomain.intranet.domain.cat
tls:
- hosts:
- subdomain.intranet.domain.cat
secretName: service-tls