Certificados Wildcards de Letsecnrypt con Traefik y Duckdns

5 minutos de lectura

Hasta ahora utilizaba el contenedor de Letsencript para obtener los certificados de ciertos servicios que utilizo para mi servidor personal. Pero sinceramente el método que utilizaba era un poco “chapuzas”, utilizada un subdominio de Duckdns por cada servicio, el problema es que Duckdns solo ofrece 5 subdominios de manera gratuita, pero además, los certificados que obtenía a través del proxy inverso, no eran del todo correctos ya que al final se mostraba el subdominio raiz.

\
De todo ello te hable en este articulo. Pero fue a raíz de una serie de problemas que he tenido a la hora de volver a configurar el proxy inverso para la Raspberry Pi, lo que me decidio a probar Traefik.

A la hora de escribir este articulo hay disponibles dos versiones de Traefik, 1.7 y 2.0, yo he instalado la versión 1.7 que la versión 2 no tiene una imagen para Raspberry, además usare la imagen creada sobre alpine al se mas ligera.

¿Que es un certificado wildcard?

La respuesta es sencilla, es un certificado único que vale para todos tus subdominios. Por ejemplo nextcloud.mi_dominio.org, jellyfin.mi_dominio.org, etc.

Conceptos

  • Frontend: es por donde va a recibir la petición, por ejemplo un

subdominio.

  • Backend: es a qué aplicación a enviar la petición

  • Providers: Es la tecnología que estás usando y que con la que Traefik es capaz de trabajar para crear routers y poder llegar a los servicios de tu red interna (services). Por ejemplo Docker, Nextcloud,,,

  • Entrypoints: son los puertos que tienes abiertos al exterior.

  • Services: las aplicaciones de tu red interna que pretendes sacar al exterior. (home assistant, wordpress, nextcloud, traccar,…)

  • Routers: el mecanismo por el que se «conecta» los servicios con internet por el puerto del entrypoint.

  • Middleware: componentes de diversa funcionalidad que alteran el comportamiento de un router. (autenticación, redireccionamiento, ssl,…)

  • docker-compose.yml: fichero para desplegar los contenedores

  • traefik.toml: fichero de configuración de Traefik, tambien se puede hacer ficheros aparte

Configuración

Para desplegar el contenedor vamos a utilizar docker-compose, el fichero es el siguiente

docker-compose.yml

 1
 2 version: '3'
 3
 4 services:
 5  proxy:
 6    image: traefik:alpine
 7    restart: always
 8    networks:
 9      - traefik_net
10    ports:
11      - "80:80"
12      - "8080:8080"
13      - "443:443"
14    volumes:
15      - /var/run/docker.sock:/var/run/docker.sock
16      - $PWD/traefik.toml:/etc/traefik/traefik.toml
17      - ${PWD}/acme:/etc/traefik/acme
18    labels:
19      - traefik.enable=true
20      - traefik.port=8080
21      - traefik.frontend.rule=Host:traefik.mi_diminio.duckdns.org
22    environment:
23     - DUCKDNS_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
24
25networks:
26  traefik_net:
27    external:
28      name: traefik_net

Donde:

  • image: es la imagen que vamos a utilizar para construir el contenedor

  • networks: la red que vamos a utilizar

  • ports: puertos a exponer por el contenedor

  • traefik.enable=true:, el contenedor aparece en el tablero de traefik, si no queremos que aparezca, traefik.enable=true

  • traefik.port=8080: puerto del tablero de Traefik

  • traefik.frontend.rule=Host:traefik.mi_dominio_duckdns.org le dice a Traefik que examine el host solicitado y si coincide con el patrón traefik.mi_dominio_duckdns.org, enruta el tráfico al contenedor traefik.

  • DUCKDNS_TOKEN=xxxxxxx token de tu cuenta de Duckdns, en este articulo te enseñe como obtenerlo.

Para mayor seguridad, el contenedor va a utilizar la red traefik_net, de hecho, todos los contenedores que son accesibles desde internet utilizan esta red.

Los contenedores que vayan a ser supervisados por Traefik han de estar en la misma red

El resto de opciones creo que se entienden bastante bien

Crear red interna para los contenedores

Vamos a crear la red que compartirán los contenedores, como comente antes, todos los dockers que vayas a manejar con Traefik han de estar en la misma red

1docker network create traefik_net

traefik.toml

Tan solo nos queda crear el fichero de configuración para Traefik

 1
 2      debug = false
 3      logLevel = "DEBUG"
 4
 5
 6      defaultEntryPoints = ["http", "https"]
 7
 8# Fuerza HTTPS
 9
10[entryPoints]
11  [entryPoints.dashboard]
12    address = ":8080"
13  [entryPoints.http]
14    address = ":80"
15      [entryPoints.http.redirect]
16        entryPoint = "https"
17  [entryPoints.https]
18    address = ":443"
19      [entryPoints.https.tls]
20
21# Interfaz WEB de Traefik: mostrará la página web con una descripción general de las configuraciones frontend y backend
22[api]
23  entrypoint="dashboard"
24
25
26# Conexion con el sistema docker del host  (docker.sock)
27
28[docker]
29  endpoint = "unix:///var/run/docker.sock"
30  domain = "mi_dominio.duckdns.org"
31  watch = true
32  network = "traefik_net"
33
34
35# Let's encrypt configuracion
36
37[acme]
38  email = "mi_correo0xxxx.xxx"
39  storage = "/etc/traefik/acme/acme.json"
40  entryPoint = "https"
41  onHostRule = true
42  acmeLogging = true
43
44# validación por DNS
45
46[acme.dnsChallenge]
47    provider = "duckdns"
48    delayBeforeCheck = 0
49
50[[acme.domains]]
51    main = "*.mi_dominio.duckdns.org"

He dejado comentadas las entradas en el fichero de configuración, aun así:

defaultEntryPoints = [“http”, “https”]

Añadimos http y https para que todos los servicios de manera predeterminada

[docker]

Permite que Traefik actúe como un proxy frente a los contenedores Docker.

watch = true

Busca nuevos contenedores en la red traefik_net y los expondrá como subdominios de su_dominio (por ejemplo si tienes un contenedor llamado nextcloud obtendrás nextcloud.tudominio.duckdns.org).

Con esto ha hemos terminado, ahora podemos acceder a nuestros séricos desde exterior de nuestra red a través de un criticado expedido por Letsencript.

Si quieres saber más

Si quieres conocer más sobre traefik te recomiendo que eches un vistazo a los siguientes enlaces:

Espero que te haya gustado, pasa un buen día… :penguin: