bookmark_borderRenovar el certificado de keycloak

Habia instalado keycloak con una imagen de docker y le puse un certificado hecho con certbot. El problema que ahora veo es que los certificados de cerbot solo tienen una vigencia de 3 meses, por lo tanto, unos dias antes de que expire hay que renovar el certificado y volver a pasarlo al contenedor de keycloak.

Bueno en este articulo voy a describir los pasos que realice para renovar y automatizar la renovación de los certificados de certbot.

Versiones

Esto utilizando las siguientes versiones.

  • Ubuntu server 22.04
  • Docker version 20.10.8, build 3967b7d
  • certbot 1.32.2
  • KEYCLOAK_VERSION=15.0.0

Procedimiento

  • Crea un nuevo certificado con certbot
$ sudo certbot certonly --manual -d keycloak.yourdomain.com
[sudo] contraseña para username: 
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Certificate not yet due for renewal

You have an existing certificate that has exactly the same domains or certificate name you requested and isn't close to expiry.
(ref: /etc/letsencrypt/renewal/keycloak.yourdomain.com.conf)

What would you like to do?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Keep the existing certificate for now
2: Renew & replace the certificate (may be subject to CA rate limits)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Renewing an existing certificate for keycloak.yourdomain.com

Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/keycloak.yourdomain.com/fullchain.pem
Key is saved at:         /etc/letsencrypt/live/keycloak.yourdomain.com/privkey.pem
This certificate expires on 2023-04-12.
These files will be updated when the certificate renews.

NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
If you like Certbot, please consider supporting our work by:
 * Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
 * Donating to EFF:                    https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  • Deten el contenedor de keycloak
$ docker stop keycloak
keycloak
  • Borra el contenedor de keycloak, asegurate de tener:
    • Configurada la base de datos fuera de tu contenedor
    • El script de creación del contenedor con la configuración de las variables de sesión.
$ docker rm keycloak
keycloak
  • Vuelve a crear el contenedor con el script de creación que tenias.
docker run -it -d --name keycloak --net keycloak-network -p8080:8080 -p 8443:8443 -v /etc/letsencrypt/live/keycloak.yourdomain.com/fullchain.pem:/etc/x509/https/tls.crt -v /etc/letsencrypt/live/keycloak.yourdomain.com/privkey.pem:/etc/x509/https/tls.key -e KEYCLOAK_USER=administrador -e KEYCLOAK_PASSWORD=yourkeycloakpassword -e DB_VENDOR=mariadb -e DB_DATABASE=keycloak -e DB_USER=keycloak -e DB_PASSWORD=your-db-password jboss/keycloak
  • Asegurate de que la llave privada y la llave publica, el agente de docker tenga permisos para su ejecución.

bookmark_borderComo empaquetar un microservicio hecho en spring con docker

Prerequisitos

  • Aplicación Spring
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.6.4</version>
  • Docker version 2.10.12, build e91ed57
  • Apache Maven 3.8.5

Pasos

  • Asegurate de que tu aplicacon de spring se ejecute con maven
./mvnw package && java -jar target/gs-spring-boot-docker-0.1.0.jar
  • Crea el Dockerfile en el proyecto de spring con las siguientes caracteristicas. No olvides renombrar al app.jar para que los guar
FROM openjdk:17-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
  • Compila con maven y que genera el componente jar.
mvn install
  • Construye la imagen con el comando de maven. No olvides sustituir myorg/myapp por un identificador para el hub de docker (compañia, y aplicacion)
docker build --build-arg JAR_FILE=target/*.jar -t myorg/myapp .
  • una vez que se haya creado por primera vez la imagen, puedes ahora reconstruirla solo utilizando la sentencia
docker build -t myorg/myapp .
  • Comprueba que se haya construido la imagen
docker image list --all
REPOSITORY                                         TAG             IMAGE ID       CREATED          SIZE
bcee/eureka                                        latest          2782caf7a46e   28 minutes ago   372MB
  • Crea un contenedor con la imagen creada.
docker run -p 8080:8080 myorg/myapp
  • Recuerda que los otros parametros de run (ver comandos de docker)

bookmark_borderComandos de docker

Los comandos y sus parametros que mas he usado, supongo que no son todos pero me dan una vision de lo que debo de hacer.

  • docker run <imagen>:[tag]
    • Descarga una imagen para crear un contenedor si la imagen no se encuentra en la lista, y adicionalmente ejecuta el contenedor con los parametros que has hayan indicado, por ejemplo,
    • –name nombre que se le va a dar al contenedor, en caso de no indicarse, se genera uno aleatorio.
    • -i. Modo interactivo al arrancar el contenedor.
    • –reset. on Se reinicia cuando caiga.
    • -t. Abre una terminal tty (TELEFONO DE TEXTO)
    • -d. Indica que se va a arrancar el contenedor y va a estar desatendido.
    • -e Declara una variable de sesión que va a estar definida en el contenedor.
    • –network Nombre de la red a la cual pertenece. Previamente debe de existir la red.
    • -p. Expone los puertos del contenedor al host del contendor.
    • -P. Expone todos los puertos que estan abiertos en el contedor. Es util cuando se levantan los servicios en random.
    • -v. Volumenes registrados en el contenedor y su mapeo en la maquina que hospeda.
  • docker build. construye una imagen
  • docker image
  • docker container
  • docker start [nombre del contenedor | id del contenedor ]
    • Inicia un contenedor.
  • docker stop [nombre del contenedor | id del contenedor ]
  • docker rm [nombre del contenedor | id del contenedor ]*
  • docker ps. Muestra todos los contenedores que se encuentran activos.
    • -a muestra todos los contenedores incluso los que no se encuentran ejecutandose.
  • docker push
  • docker inspect
  • docker network create
  • docker network rm
  • docker network attach

bookmark_borderInstala un servidor keycloak en producción con docker

En esta entrada vamos a instalar un servidor keycloak en producción, utilizando docker, mariadb y certbot

Los pasos que vamos a seguir son

  • Genera un certificado para producción utilizando certbot
  • Configura la red de docker y configura los contenedores.
  • Instala el reverse proxy para tu servidor.

Genera un certificado para producción utilizando certbot

$ sudo certbot certonly -d tu.dominio.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log

How would you like to authenticate with the ACME CA?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: Nginx Web Server plugin (nginx)
2: Spin up a temporary webserver (standalone)
3: Place files in webroot directory (webroot)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-3] then [enter] (press 'c' to cancel): 3
Plugins selected: Authenticator webroot, Installer None
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for tu.dominio.com
Input the webroot for tu.dominio.com: (Enter 'c' to cancel): /var/www/html
Waiting for verification...
Cleaning up challenges
Subscribe to the EFF mailing list (email: pruebas@dominio.com).

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/tu.dominio.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/tu.dominio.com/privkey.pem
   Your cert will expire on 2021-11-18. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot
   again. To non-interactively renew *all* of your certificates, run
   "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

Si no quieres utilizar certbot, puedes ocupara para crear el certificado openssl, solo que como no es emitido por una entidad certificadora, seguramente lo va a detectar como aprocrifo.

$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/tudominio-selfsigned.key -out /etc/ssl/certs/tudominio-selfsigned.crt
   Country Name (2 letter code) [AU]:
   State or Province Name (full name) [Some-State]:
   Locality Name (eg, city) []:
   Organization Name (eg, company) [Internet Widgits Pty Ltd]:
   Organizational Unit Name (eg, section) []:
   Common Name (e.g. server FQDN or YOUR name) []:
   Email Address []:

Para que podamos leer la llave privada desde el servidor docker debemos de cambiarle los permisos para que se pueda leer.

Si lo hicimios con certbot

$ sudo chmod 644 /etc/letsencrypt/live/tu.dominio.com/privkey.pem

Si lo hicimos con openssl

$ sudo chmod 644 /etc/ssl/private/tudominio-selfsigned.key

Configura la red de docker

Esto lo vamos a ocupar para que sea vea el contenedor de keycloak y el de la base de datos.

$ docker network create keycloak-network

Instala una instancia de mariadb para almacenar la información

$ docker run -d --name mariadb \
--net keycloak-network \
-e MYSQL_ROOT_PASSWORD=root_p@assword \
-e MYSQL_DATABASE=keycloak \
-e MYSQL_USER=keycloak \
-e MYSQL_PASSWORD=p@ssword \
mariadb

Si ya tienes una instancia de mariadb en un contenedor docker solo debes de poner ponerla en la misma red de keycloak, con la sentencia

$ docker network connect mariadb

Donde mariadb es el nombre del contenedor de mariadb.

Descarga e instala la imagen de keycloak para producción.

$ docker run -it -d --name keycloak \
--net keycloak-network \
-p8080:8080 -p 8443:8443s \
-v /etc/ssl/certs/keycloak-selfsigned.crt:/etc/x509/https/tls.crt \
-v /etc/ssl/private/keycloak-selfsigned.key:/etc/x509/https/tls.key \
-e KEYCLOAK_USER=administrador \
-e KEYCLOAK_PASSWORD=p@ssword \
-e DB_VENDOR=mariadb \
-e DB_DATABASE=keycloak \
-e DB_USER=keycloak \
-e DB_PASSWORD=p@assworddb \
jboss/keycloak

donde

-v se indican el certificado y la llave privada para el keycloak.

Por último, si necesitamos reiniciar el servidor, debemos detener el contenedor, borrarlo y volverlo a construir

$ docker stop keycloak
$ docker rm keycloak

bookmark_borderInstalar keycloak en un contenedor docker

En este artículo vamos a describir como debe de instalarse un servidor keycloack en un contenedor docker y vamos a utilizar mariadb como repositorio de los datos de nuestro servidor, y explica las variables que puedes cambiar y como afectan.

Prerequisitos

Asegurate de tener instalado docker.

$ docker --version

Vamos a trabajar con la versión Docker CE 16.

Uso e instalación

Crea un recurso de red si lo vas a instalar en el mismo equipo, un contenedor para la base de datos y otro para el keycloak.

$ docker network create keycloak-network

Crea el contendor de la base de datos, para este caso yo voy a utilizar mariadb. Las variables que debes de cambiar cuando vas a crear el contenedor de mariadb para keycloak son:

  • MYSQL_ROOT_PASSWORD. Contraseña del root de mariadb.
  • MYSQL_DATABASE. Nombre de la base de datos donde se va a almacenar la información de keycloak.
  • MYSQL_USER. Nombre del usuario de base de datos con el cual se va a conectar el servidor de keycloak.
  • MYSQL_PASSWORD. Contraseña del usuario de base de datos, que va a utilizar el seridor de keycloak.
$ docker run -d 
   --name mariadb 
   --net keycloak-network 
   -e MYSQL_ROOT_PASSWORD=password 
   -e MYSQL_DATABASE=keycloak 
   -e MYSQL_USER=keycloak 
   -e MYSQL_PASSWORD=password mariadb

Ahora toca el turno para crear el contendor de keycloak, y que utilice la base de datos mariadb.

  • KEYCLOAK_USER. Es el administrador de keycloak y el primer usuario con el cual vas a ingresar.
  • KEYCLOAK_PASSWORD. La contraseña del administrador de keycloak.
  • DB_VENDOR. Debe de escribirse el nombre del manejador de base de datos en minusculas, ES MUY QUISQUILLOSO asi es que pon los nombres exactamente como te dice la documentación.
  • DB_USER. El nombre del usuario que creaste al crear el contenedor de mariadb, este es el que pusisten en la variable MYSQL_USER cuando creaste el contenedor de mariadb.
  • DB_PASSWORD. Es la contraseña del usuario de la base de datos, es lo que pusiste en la variable MYSQL_PASSWORD.
$ docker run -it -d 
   --name keycloak 
   --net keycloak-network 
   -p8080:8080 
   -e KEYCLOAK_USER=administrador 
   -e KEYCLOAK_PASSWORD=password 
   -e DB_VENDOR=mariadb 
   -e DB_USER=keycloak 
   -e DB_PASSWORD=password 
   jboss/keycloak

Y ahora solo queda probar que todo este correcto, abre un explorador de internet y navega a la url http://localhost:8080/auth.

Navega a la opción de Administration Console, y completa el formulario. Debes de utilizar el nombre del usuario (KEYCLOAK_USER) y contraseña (KEYCLOAK_PASSWORD) que pusiste para crear el contenedor de keycloak.

Observaciones importantes, si tu detienes el contenedor de keycloak con la sentencia

$ docker stop keycloak
$ docker start keycloak

Te va a marcar un error y no vas a poder volverlo a levantar. Primero debes destruirlo y volverlo a generar. Para destruir el contenedor de docker utiliza la sentencia.

$ docker rm keycloak

Como toda la configuración esta en tu contenedor de base de datos no tienes de que preocuparte.

bookmark_borderInstalacion de MONGODB con Docker

A continuación vamos a mostrar como estoy instalando mongodb en un contenedor docker.

Prerequisitos

  • AMD A4 8GB RAM y SSD 480
  • Ubuntu Desktop 20.04 LTS
  • Docker CE

Instalación

  • Baja la imagen 
$ docker pull mongo
  • Ten a la mano los siguientes datos que debes de poner para asegurar cuando levantes el servidor dentro del contenedor.
    1. ruta donde se va almacenar los datos.
    2. usuario y contraseña con el cual se va a generar el root del mongo.
    3. puerto en el cual se va a natear el contenedor al host.
  • Crea el contenedor con la imagen que acabas de bajar poniendo escribiendo los parámetros, en el archivo mongo.yml
$ cat > mongo-docker.yml
# Use root/example as user/password credentials
version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    container_name: docker-mongodb
    ports:
             - 27017:27017
    volumes:
             - /mnt/secondary/data/db:/data/db
    environment:
      MONGO_INITDB_ROOT_USERNAME: root
      MONGO_INITDB_ROOT_PASSWORD: xxxxxx

$ chmod 777 mongo.yml
  • tambien puedes crear el contenedor con la imagen que acabas de bajar escribiendo los parámetros en la linea de comando
$ docker run --name docker-mongo 
-v /home/user/data/mongodb:/data/db 
-p 27017:27017 
-e MONGO_INITDB_ROOT_USERNAME=administrator 
-e MONGO_INITDB_ROOT_PASSWORD=XXXXX 
--restart always -d mongo
  • ahora si puedes conectarte desde el host del contenedor a mongodb, y ya estas listo para trabajar, con la siguiente sentencia.
$ mongo -u administrador -p xxxxx --authenticationDatabase admin
  • tambien puedes conectarte desde un equipo que no sea el host con la siguiente sentencia.
$ mongo --host xxx.xxx.xxx.xxx -u administrator -p xxxxxxx --authenticationDatabase admin

Cómo configurar un servidor para producción 

  • Las características que debe de tener un servidor de producción, 
    1. Debe estar cifrada la comunicación con ssl
    2. Debe de tener un administrator, con una contraseña fuerte
    3. Debes de tener un usuario por cada base de datos que crees en el servidor.
    4. Debe de tener un respaldo de la base de datos.
    5. Debes de tener configurado un esquema de recuperación del servidor.
  • Debes de cifrar la comunicación con ssl

  • Crea el usuario administrador de la base de datos.
$ mongo --host xxx.xxx.xxx.xxx -u administrator -p xxxxxxxxxx --authenticationDatabase admin
$ db.createUser(
 {
    user: "rrhh_dbo",
    pwd: "xxxxxx",
    roles: [ { role: "readWrite", db: "rrhh" } ]
  }
)