Configura Portainer, Traefik y otros servicios en un NAS QNAP con Docker

Todos los servidores NAS del fabricante QNAP incorporan la utilidad de Container Station que se puede instalar a través de App Center, este software nos permite configurar virtualización ligera a través de contenedores Docker y LXC, esto nos permite una inmensa libertad a la hora de instalar diferente software en nuestro NAS QNAP sin necesidad de instalarlo de manera nativa. Hoy en RedesZone os vamos a explicar en detalle cómo configurar Container Station con Docker, e instalaremos software tan fundamental como Portainer o Traefik entre otros muchos servicios para exprimir al máximo nuestro servidor NAS.

Servidor NAS utilizado en este tutorial

En este tutorial hemos utilizado un QNAP QGD-1602P, el popular switch que también hace las funciones de servidor NAS al integrar el sistema operativo QTS. Al utilizar este equipo, es posible que a nivel de redes sea algo más complejo como os mostraremos en las imágenes, si tu NAS tiene uno o dos puertos de red físicos, en la sección de «Conmutador virtual» lo verás todo de forma más simple, sin embargo, nosotros hemos utilizado este equipo para realizar todas las pruebas, además, viene con Virtualization Station configurado a nivel de red para usarlo con pfSense como router principal, por tanto, veréis que en las capturas de pantalla tenemos «enlazados» diferentes «Virtual Switch» a diferentes interfaces físicas del propio equipo, esto es algo completamente normal pero vosotros no lo tendréis que utilizar.

Este servidor NAS lo hemos configurado detrás de nuestro router principal que es un pfSense, debemos tener en cuenta el router porque deberemos abrir los puertos 80 y 443 hacia la dirección IP que tenga el servidor NAS, con el objetivo de acceder a los diferentes recursos a través de Internet.

El sistema operativo QTS utilizado es la versión 4.5.2 en su última versión, no obstante, si utilizas una versión más nueva el procedimiento de todo lo que hay que realizar es exactamente igual, no cambia absolutamente nada. La configuración de los conjuntos de almacenamiento es en un RAID 1, creando diferentes volúmenes dentro para el «Sistema» y también para las «MaquinasVirtuales», ya sea con Virtualization Station o con Container Station. El proceso de creación de los conjuntos de almacenamiento y los volúmenes los omitimos porque es algo que ya deberías saber, no obstante, tenemos tutoriales sobre cómo hacerlo.

La configuración a nivel de red con «Conmutador virtual y de red» es algo complejo en un primer momento, porque nosotros ya tenemos configurado diferentes «Virtual Switch» y adaptadores virtuales de Virtualization Station. A vosotros os debería aparecer únicamente una interfaz (o las que tenga vuestro NAS) en la sección de «Adaptador físico» en la parte derecha. Actualmente la dirección IP de la red local que utilizaremos será la 10.11.1.9, por tanto, esta será la dirección IP de acceso al NAS, la dirección IP donde tendremos que abrir los puertos en el pfSense etc.

La configuración actual a nivel de «Network / Interfaces» es la siguiente, debemos recordar que la dirección IP privada de acceso de este NAS es la 10.11.1.9, será importante para después, en tu caso será la que le haya proporcionado el DHCP del router o el que hayas puesto tú específicamente.

En los puertos del propio switch no tenemos ningún equipo conectado, es en el puerto de «Host» donde lo hemos conectado. Esto es importante si justamente esto lo estás haciendo con un QNAP Guardian.

Una vez que hemos visto la configuración básica, vamos a hablar sobre los diferentes softwares que vamos a instalar y configurar.

Container Station: ¿qué es y para qué sirve?

Container Station es un software de QNAP completamente gratuito que se puede descargar directamente desde la App Center del fabricante. Container Station integra tecnologías de virtualización ligeras como LXC y también el popular Docker, por lo que podremos utilizar una gran cantidad de contenedores virtualizados y aislados del servidor NAS de QNAP, sin necesidad de instalarlos nativamente en nuestro servidor. Podremos descargar todas las aplicaciones que queramos a través del registro central de Docker, e incluso cualquier contenedor Docker de otras webs.

En la imagen siguiente se puede ver cómo funcionaría Container Station, y es que es mucho más sencillo desplegar un contenedor con LXC o con Docker que usar Virtualization Station y un sistema operativo completo por encima, por tanto, si necesitas instalar aplicaciones o herramientas que ya están en un contenedor de Docker, te será muchísimo más sencillo usar Container Station que Virtualization Station, aunque ambas tecnologías pueden convivir sin ningún tipo de problema en el mismo NAS.

Docker es el software de virtualización ligera por excelencia, nos permite tener un contenedor individual por cada aplicación que nosotros queramos desplegar, además, la implementación es realmente rápida y la migración entre plataformas es completamente transparente, porque no tendremos que reinstalar absolutamente nada. Gracias a Docker podremos ejecutar aplicaciones avanzadas de forma totalmente aislada al sistema operativo QTS.

Otras características de Container Station son que nos permitirá la importación y exportación de los contenedores de forma fácil y rápida, realizar copias de seguridad y mucho más, no obstante, en nuestra opinión el mejor gestor de contenedores Docker es Portainer, porque es un software mucho más avanzado con herramientas específicas para exprimir al máximo el potencial de Docker. Por este motivo, dentro de Container Station haremos uso de un Docker con Portainer para gestionar los contenedores que nosotros vayamos a instalar en el servidor NAS de QNAP.

Debemos tener en cuenta que los recursos de hardware en un NAS de QNAP pueden ser limitados, en función de la gama del servidor y del procesador principal, el rendimiento que obtendremos será mayor o menor. Por norma general, tanto LXC como Docker tiene una necesidad de recursos realmente baja, muchísimo más baja que desplegar una máquina virtual completa con Virtualization Station, además, la configuración es mucho más rápida porque normalmente ya viene preconfigurado en una plantilla y simplemente tendremos que desplegarlo.

Instalación y configuración de Container Station

Lo primero que tenemos que hacer es instalar Container Station a través de App Center, la tienda de aplicaciones y software del fabricante QNAP. Seleccionaremos «Container Station» y procedemos a instalarlo en nuestro servidor NAS de QNAP.

Una vez instalado, tendremos que crear una «Carpeta de Recursos compartidos», sección «Panel de control / Privilegio / Carpetas compartidas», y le daremos el nombre de «DockerCarpeta» seleccionando el Volumen que vosotros queráis.

Una vez que la hayamos creado, nos aparecerá en el listado de carpetas compartidas.

Si entramos dentro veremos que está completamente vacío.

La primera vez que abrimos Container Station nos indicará que el sistema deberá crear una carpeta compartida llamada «Container» para almacenas las imágenes y los contenedores. Elegiremos la carpeta que acabamos de crear que está en la ruta «DockerCarpeta», y dentro podemos crear una nueva carpeta.

Podemos crear una nueva carpeta que se llame «ContainerStation» para que almacene ahí toda la información sobre las imágenes y contenedores.

Una vez seleccionada, pinchamos en «Start Now».

Ahora nos saldrá el menú principal de Container Station, podremos ver el número de contenedores funcionando, parados, el procesador del servidor NAS, el uso de CPU y memoria RAM y más información.

Si pinchamos en «Create» podremos instalar fácilmente diferentes contenedores en el propio Container Station, tenemos un listado bastante grande, pero en Internet podremos encontrar miles de Dockers.

En la sección de «Preferences» podremos ver las opciones de red de los contenedores LXC y también de Docker, podremos cambiarlo en cualquier momento, pero nuestra recomendación es que no toquéis esta configuración predeterminada, porque nosotros crearemos una nueva red.

A continuación, podéis ver la configuración de la parte de Docker, pero insistimos, nosotros crearemos una red completamente nueva vía SSH.

Una vez que ya tenemos instalado y funcionando Container Station, ahora vamos a realizar una configuración intermedia creando una nueva red.

Crear una nueva red en «Virtual Adapter» para todos los Dockers

Lo primero que tenemos que hacer es configurar el servidor SSH del servidor QNAP, para ello nos vamos a la sección de «Panel de control / Servicios de red/ Telnet y SSH», ponemos que queremos permitir conexiones SSH, el número de puerto que nosotros queramos (por defecto es el puerto 22), y podremos activar el SFTP si queremos para pasarle archivos de configuración más adelante. Debemos recordar que solo los usuarios administradores pueden iniciar sesión vía SSH, tanto el usuario «admin» como cualquier usuario que esté en el grupo de administradores.

Con un programa como Putty o cualquier otro, iniciamos sesión en el servidor NAS poniendo: admin@IP y el puerto que hayamos configurado previamente.

Ponemos la contraseña de acceso del usuario administrador:

Ponemos Q mayúscula y pulsamos enter, esto nos permitirá acceder a la línea de comandos completa.

Ahora nos preguntará que, si queremos salir del menú, ponemos Y en mayúscula y pulsamos enter.

Ahora tendremos que crear una nueva red para poner ahí todos los Docker que nosotros vayamos a instalar, el comando que tenéis que utilizar es el siguiente:

docker network create nombre-que-quieras

En nuestro caso, el nombre del adaptador de red que vamos a crear es «redeszone»:

docker network create redeszone

Una vez que hayamos hecho esto, si nos metemos en «Conmutador Virtual y de red» en la sección de «Network / Virtual Switch» debemos editar el nombre del Virtual Switch para no tener problemas:

Ponemos exactamente el mismo nombre creado en «Docker», en nuestro caso es «redeszone». Debemos tener en cuenta que a la hora de instalar los Docker siempre les tendremos que pasar la «network = «redeszone»» para que lo instale correctamente.

A partir de este momento y durante todo el tutorial, la red a la que harán referencia los diferentes Dockers cuando los vayamos a instalar será «redeszone».

Liberar los puertos 80 y 443 para que todo funcione bien

El traefik que es el proxy inverso estará funcionando en los puertos 80 y 443 (para HTTPS) obligatoriamente, por tanto, es totalmente necesario liberar estos puertos en el propio sistema operativo QTS del servidor NAS. Tal y como podéis ver, nosotros estamos usando los puertos 8080 para HTTP y el 44333 para el HTTPS del QNAP.

También debemos cambiarlo en la parte de «Servidores de aplicaciones» y «Servidor web», por ejemplo, ponemos el 8091 que no va a estar nunca en uso.

Una vez que ya lo tenemos todo listo, procedemos a realizar la configuración global.

Software que vamos a instalar: Portainer, Traefik, whoami y más

En RedesZone os vamos a proporcionar un docker-compose con la instalación y configuración automatizada de todos estos servicios que os hemos comentado, con el objetivo de facilitar enormemente el inicio al mundo de los Docker sin tener problemas. El software fundamental que configuraremos es Portainer, Traefik, Whoami y contenedores adicionales que se encargarán de facilitarnos la vida enormemente.

Portainer: ¿qué es y para qué sirve?

Portainer es la herramienta más recomendable para gestionar contenedores Docker con una interfaz gráfica de usuario realmente intuitiva. Permite administrar los contenedores de forma local o remota, además de soportar Docker también soporta Kubernetes. Algunas de las principales características de Portainer es que nos permitirá gestionar los contenedores Docker, las imágenes, las redes y volúmenes, podremos ver los registros a la ahora de arrancar un contenedor, configurar plantillas para los contenedores, configurar etiquetas y mucho más. Si vamos a utilizar Docker en un NAS de QNAP, en lugar de gestionarlos con Container Station, los gestionaremos todos ellos con Portainer que es claramente el mejor gestor de contenedores Docker que existe hoy en día. Su instalación a través del propio Docker es realmente sencilla.

Traefik: ¿qué es y para qué sirve?

Traefik es el mejor proxy inverso o «reverse proxy» que podemos utilizar para llegar a todos los servicios que tenemos en el servidor NAS, tan solo será necesario abrir dos puertos (el 80 y el 443), y automáticamente traefik nos redireccionará internamente a los diferentes servicios y servidores que tengamos corriendo en el servidor NAS. Según la documentación oficial, Traefik es un «Edge Router» que permite acceder a todos los servicios del interior. Este software recibe solicitudes de nombre en su sistema, y descubre qué componentes de dentro deben responder a estas solicitudes. Este software es capaz de descubrir automáticamente los contenedores Docker que tengamos, siempre y cuando le pasemos unas «labels», de esta forma, podremos automatizar el reconocimiento de los diferentes contenedores por parte de Traefik, es compatible con Docker, Docker Swarm, Kubernetes, AWS y otros. Si queremos añadir o retirar servicios lo podremos hacer en tiempo real sin necesidad de reiniciar el servicio, esto es ideal para no interrumpir el servicio.

Traefik «entiende» ficheros de configuración toml y yml, en RedesZone hemos configurado todo con yml ya que es más limpio (en nuestra opinión). Básicamente traefik dispone de dos ficheros de configuración, el traefik.yml que es el archivo de configuración global, y otro archivo que es el dynamic-conf.yml (pero lo podemos llamar como queramos) que se encarga de interconectar los diferentes servicios internamente.

Para reconocer los diferentes servicios de los Docker podremos hacerlo vía «labels» a la hora de crear el contenedor Docker, o poniéndolo en el archivo dinámico dynamic-conf.yml, en nuestra opinión, creemos que es mejor hacerlo directamente en el archivo «file» para no depender de los labels que hayamos configurado en cada uno de los contenedores, e ir uno por uno. Es mucho más sencillo hacerlo en este archivo y realizar todas las configuraciones desde aquí de forma masiva, sin necesidad de reconfigurar el docker-compose o ir contenedor por contenedor configurándolo todo.

Whoami

whoami es un contenedor Docker que nos permitirá saber si el Traefik está funcionando correctamente, proporcionándonos información de las direcciones IP, cabeceras de HTTPS y mucha más información. Lo más importante de este contenedor es si al entrar en el dominio nos carga o no, si nos carga entonces tendremos la configuración correcta y podremos seguir añadiendo el resto de Dockers, de lo contrario, hay algún problema y tenemos que solucionarlo.

DuckDNS

DuckDNS es un servicio gratuito de DNS Dinámico, para poder hacer funcionar todo el sistema necesitamos de este contenedor para que actualice nuestro dominio con la IP pública que tenemos actualmente en nuestro hogar. Este servicio es completamente gratuito y funciona realmente bien, además, está soportado de forma oficial por Traefik por lo que lo hemos elegido. Lo primero que tenemos que hacer es entrar en la web oficial de DuckDNS y proceder a configurar un dominio DuckDNS, en nuestro caso el dominio es «bronredeszone.duckdns.org»

Lo más importante de duckdns es el dominio «bronredeszone» y el «token», porque tendremos que utilizarlo a la hora de crear el Docker. Nosotros lo hemos a dejar indicado en el archivo.

traefik-certs-dumper

Este contenedor se encargará de transformar los certificados digitales HTTPS de Let’s Encrypt en un archivo con la clave pública y otro con la clave privada, para que no esté todo junto en el mismo «json» tal y como ocurre si no tenemos este contenedor. Esto nos facilitará la vida enormemente si queremos gestionar los certificados digitales manualmente. Esto es opcional, pero os recomendamos utilizarlo.

Instalación de todo el software y puesta en marcha

Antes de empezar a instalar todo el software a la ves a través de un docker-compose que os vamos a proporcionar, tenemos que crear las diferentes carpetas y archivos, para que luego el traefik y el resto del software instalado lo puedan utilizar correctamente y sin problemas. Podéis modificar estas rutas, pero nuestra recomendación es que uséis las mismas que nosotros para que no tengáis problemas ni fallos. Recordad que hemos creado una carpeta compartida llamada «DockerCarpeta» y dentro hemos creado una carpeta llamada «Docker» con todo el contenido que veréis a continuación. Por tanto, la ruta absoluta desde donde parte todo el software es /share/DockerCarpeta/Docker

Nos conectamos vía SSH y ejecutamos los siguientes comandos:

mkdir -p /share/DockerCarpeta/Docker/Docker-compose
mkdir -p /share/DockerCarpeta/Docker/traefik/
mkdir -p /share/DockerCarpeta/Docker/traefik/letsencrypt
mkdir -p /share/DockerCarpeta/Docker/traefik/logs/
touch /share/DockerCarpeta/Docker/traefik/letsencrypt/acme.json
touch /share/DockerCarpeta/Docker/traefik/logs/access.log
touch /share/DockerCarpeta/Docker/traefik/logs/traefik.log
chmod 600 /share/DockerCarpeta/Docker/traefik/letsencrypt/acme.json
chmod 600 /share/DockerCarpeta/Docker/traefik/logs/access.log
chmod 600 /share/DockerCarpeta/Docker/traefik/logs/traefik.log

Una vez que hayamos ejecutado todo esto, abrimos un archivo yml para copiar el docker-compose, tenéis que ejecutar la siguiente orden para crear el docker-compose en su carpeta:

cd /share/DockerCarpeta/Docker/Docker-compose

Ahora creamos el archivo con vim y el nombre del fichero que debe ser docker-compose.yml

vim docker-compose.yml

Si no habéis usado nunca «vim», tenéis que pulsar en «Insert» del teclado, y proceder a escribir o copiar

version: ‘3.7’

services:

## duckdns – actualizar ip publica dinamica
duckdns:
image: ghcr.io/linuxserver/duckdns
container_name: duckdns
environment:
– PUID=1000
– PGID=1000
– TZ=Europe/Madrid
– SUBDOMAINS=vuestro_dominio
– TOKEN=vuestro_token
– LOG_FILE=true
volumes:
– /share/DockerCarpeta/Docker/duckdns:/config
restart: always
networks:
– redeszone

## Portainer – Gestor Dockers
portainer:
container_name: portainer
image: portainer/portainer
command: -H unix:///var/run/docker.sock
restart: always
ports:
– 9000:9000
– 8000:8000
volumes:
– /var/run/docker.sock:/var/run/docker.sock
– /share/DockerCarpeta/Docker/portainer:/data
networks:
– redeszone

## Traefik proxy inverso
traefik:
container_name: traefik
image: traefik:v2.4
restart: always
ports:
– 80:80
– 443:443
– 8082:8082
environment:
– TZ=Europe/Madrid
– DUCKDNS_TOKEN=TU_TOKEN
volumes:
– /var/run/docker.sock:/var/run/docker.sock:ro
– /share/DockerCarpeta/Docker/traefik/traefik.yml:/etc/traefik/traefik.yml
– /share/DockerCarpeta/Docker/traefik:/etc/traefik
– /share/DockerCarpeta/Docker/traefik/letsencrypt:/letsencrypt
networks:
– redeszone

## whoami – Hacer pruebas de la red y la ruta y los certificados
whoami:
container_name: whoami
image: traefik/whoami
ports:
– 34280:80
networks:
– redeszone

## Certs-Dump – convierte el json en diferentes .crt y .key
traefik-certs-dumper:
container_name: certs-dumper
image: ldez/traefik-certs-dumper:v2.7.4
entrypoint: sh -c ‘
apk add jq
; while ! [ -e /data/acme.json ]
|| ! [ `jq «.[] | .Certificates | length» /data/acme.json` != 0 ]; do
sleep 1
; done
&& traefik-certs-dumper file –version v2 –watch
–source /data/acme.json –dest /data/certs’
volumes:
– /share/DockerCarpeta/Docker/traefik/letsencrypt:/data

#Podemos crear una red privada y otra publica
networks:
redeszone:
external: true #red publica

De este docker-compose tenéis que editar lo siguiente para adaptarlo a vuestro sistema:

  • DuckDNS: SUBDOMAINS y TOKEN. ¿La red «networks» la has llamado «redeszone»?

El resto no sería necesario cambiarlo, guardamos el archivo y podemos comprobar si está todo correcto con el siguiente comando:

docker-compose -f docker-compose.yml config

Debéis recordar que en un yml no hay que poner «tabulaciones» sino «espacios».

Instalación y configuración de Portainer

Para instalar el Docker de Portainer, debemos ejecutar la orden de docker-compose apropiada, no es necesario instalar todo de momento, podemos ir instalando servicio a servicio.

docker-compose up -d portainer

Ahora pondrá a descargar e instalar todo lo necesario.

Una vez que hayamos instalado y configurado Portainer, en la sección de «Conmutador virtual y de red» nos saldrá que «Portainer-Server Virtual adapter 1» está conectado con el «Virtual Switch» llamado «redeszone», y que hace NAT.

Ahora si ponemos la dirección IP del NAS y el puerto 9000 que es el que hemos configurado para el frontend, podremos acceder a su administración. En nuestro caso ponemos http://10.11.1.9:9000 tal y como podéis ver:

Pondremos un nombre de usuario «admin» y la contraseña que vosotros queráis, y pinchamos en «Create user»

Una vez que hayamos creado el usuario administrador, pinchamos en «Docker» y en «Connect».

Ahora mismo ya tenemos Portainer funcionando, a partir de ahora los Docker que instalemos aparecerán directamente en la sección de «Containers».

En la parte izquierda podremos ver las diferentes imágenes, contenedores, volúmenes, la configuración de la red con la subred que ha creado Docker automáticamente (172.29.0.0/22) y muchas otras opciones de configuración avanzadas.

Una vez que ya tenemos configurado Portainer, podremos instalar el resto de Dockers que nosotros deseemos, pero vamos a instalar primero el más importante y que será la «base» del resto de Dockers para acceder de forma remota a su administración, ahora tenemos que instalar Traefik.

Instalación y configuración de Traefik

Antes de instalar Traefik a través de docker-compose, nuestra recomendación es que pongáis los ficheros de configuración en su sitio.

El archivo «traefik.yml» y el archivo «dynamic-config.yml» en la ruta /share/DockerCarpeta/Docker/traefik/ como hemos explicado anteriormente.

El archivo «traefik.yml» debería tener el siguiente contenido:

global:
checkNewVersion: true
sendAnonymousUsage: true

entryPoints:
web:
address: ':80'
http:
redirections:
entryPoint:
to: web-secure
scheme: https
web-secure:
address: ':443'
http:
tls:
certResolver: lets-encrypt

traefik:
address: ':8082'

log:
level: DEBUG
filePath: /etc/traefik/logs/traefik.log

accessLog:
filePath: /etc/traefik/logs/access.log

api:
insecure: true
dashboard: true
debug: true

ping: {}

providers:
docker:
endpoint: unix:///var/run/docker.sock
exposedByDefault: false
watch: true
swarmMode: false
file:
filename: /etc/traefik/dynamic-conf.yml
watch: true

certificatesResolvers:
lets-encrypt:
acme:
email: "sergio.deluz@grupoadslzone.com"
storage: "/letsencrypt/acme.json"
httpChallenge:
entryPoint: web

Os explicamos brevemente la configuración:

  • Estamos usando los puertos 80 y 443 como «EntryPoint», estos dos puertos son los que tenemos que abrir en el router.
  • El puerto 8082 será el de administración que nos lleve al frontend.
  • Hemos configurado redirección desde HTTP a HTTPS para tener siempre la máxima seguridad, hemos usado certificados de Let’s Encrypt que se generarán de forma completamente automática para facilitar la configuración.
  • Aunque la «api» que es la administración está en «insecure : true» podemos cambiarlo posteriormente, no obstante, este puerto no lo vamos a exponer.
  • Los «Providers» son los docker (si hemos metido las label a la hora de crearlo, o si metemos la label a posteriori), y también el «file» del dinámico «dynamic-conf.yml». Nosotros no vamos a poner label en los Docker, por lo que configuraremos el «File».
  • En «certificateResolvers» tenéis que poner vuestro correo electrónico.

El archivo «dynamic-config.yml» debería tener el siguiente contenido:

tls:
options:
default:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
curvePreferences:
- CurveP521
- CurveP384

http:
routers:
api:
rule: Host(`traefik.bronredeszone.duckdns.org`)
entrypoints:
- web-secure
middlewares: simpleAuth
service: api@internal
tls:
certResolver: lets-encrypt

router-qts:
rule: Host(`qts.bronredeszone.duckdns.org`)
middlewares: security
service: service-qts
tls:
certResolver: lets-encrypt

router-portainer:
rule: Host(`portainer.bronredeszone.duckdns.org`)
middlewares: security
service: service-portainer
tls:
certResolver: lets-encrypt

router-whoami:
rule: Host(`whoami.bronredeszone.duckdns.org`)
middlewares: security
service: service-whoami
tls:
certResolver: lets-encrypt

services:
service-qts:
loadBalancer:
servers:
- url: "http://10.11.1.9:8080"

service-portainer:
loadBalancer:
servers:
- url: "http://10.11.1.9:9000"

service-whoami:
loadBalancer:
servers:
- url: "http://10.11.1.9:34280"

middlewares:
simpleAuth:
basicAuth:
users:
- admin:$2y$10$bae.2vNFdoXyBOLHiZDeJOSf8Y3finp9NGC9IqRxhHz9Y5SolHff.
- redeszone:$2y$10$e3.Qyf2yRoe1pc.KlYyaW.Pc/muW8irPG6MgaKEO9AdzV5ZzgYOCG.
security:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlMaxAge: 100
addVaryHeader: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
frameDeny: true
sslRedirect: true
sslForceHost: true
stsPreload: true
customFrameOptionsValue: SAMEORIGIN
referrerPolicy: "same-origin"
featurePolicy: "camera 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none'; vibrate 'self';"
stsSeconds: 315360000
hostsProxyHeaders:
- "X-Forwarded-Host"

Con este archivo dinámico podremos llegar a los diferentes servicios, os explicamos brevemente lo que hemos configurado.

  • Configuración TLS 1.2 como mínimo, soporta TLS 1.3.
  • En «http: routers:» podemos ver todos los dominios y las rutas que tenemos hacia los diferentes servicios, aquí hemos añadido el acceso al propio sistema operativo QTS, al Portainer y al Whoami que veremos próximamente. Tenemos la opción de que sea a través de «web» o «web-secure» como «EntryPoint», si lo dejamos así permite ambas entradas. Aquí tenéis que modificar la parte de «url» y poner la dirección IP interna de vuestro servidor NAS QNAP.
  • En «Services» podremos ver los diferentes servicios dados de alta y la URL que tiene que usar Traefik internamente.
  • En «Middlewares» tenemos configurada una autenticación básica para el traefik dashboard, pero se puede aplicar a cualquier servicio, además, podríamos añadir autenticación en dos pasos con otro Docker específico y mucho más. También tenemos una configuración de seguridad para el HTTPS. En todos los «routers» hemos puesto este middlewares de security.

Para instalar el Docker de Portainer, debemos ejecutar la orden de docker-compose apropiada, no es necesario instalar todo de momento, podemos ir instalando servicio a servicio. No obstante, ahora ya podremos instalar todos los servicios, por tanto, procedemos a ejecutarlo todo (también el Portainer, pero no lo tocará porque ya está creado en su última versión).

docker-compose up -d

Ahora pondrá a descargar e instalar todo lo necesario para su funcionamiento.

Para comprobar que funcione, desde una conexión a Internet que no sea la actual, podemos poner el siguiente dominio y comprobar si funciona o no:

  • https://whoami.bronredeszone.duckdns.org

Si funciona, en principio todo estaría correcto y podemos probar el resto de subdominios que hemos creado. Podemos verificar que se ha creado un certificado SSL de Let’s Encrypt por cada uno de los subdominios, esto lo podéis encontrar en la ruta «/share/DockerCarpeta/Docker/traefik/letsencrypt».

Respecto al detalle del certificado digital, podéis verlo aquí:

A continuación, podéis ver el acceso a los diferentes servicios que están funcionando perfectamente:

El acceso al panel de Traefik desde el exterior tiene usuario/contraseña, esto se ha hecho a través del «middlewares», podéis dar de alta más usuarios generando el usuario y clave con Bcrypt y esta web, o ejecutando directamente por consola el comando htpasswd para generarlo manualmente.

En estos instantes, ya podéis acceder a todos los servicios que os hemos explicado, no obstante, también podríamos poner más.

¿Qué otros servicios podemos instalar?

Con este sistema de contenedores Docker podremos instalar todo lo que queramos, tanto para ampliar funcionalidades del Traefik con autenticación en dos pasos, como de servicios como Transmission, Bitwarden, Nextcloud y mucho más. Ahora en RedesZone os vamos a enseñar a instalar Transmission, y próximamente también os enseñaremos a instalar Bitwarden y Nextcloud en Docker y para que pueda ser accesible a través de Traefik.

Instalación y configuración de Transmission

Para instalar transmission, lo primero que tenemos que hacer es crear las carpetas correctas para poner la configuración y también la configuración de descargas.

mkdir -p /share/DockerCarpeta/Docker/transmission/
mkdir -p /share/DockerCarpeta/Docker/transmission/config

Creamos carpeta compartida llamada «DescargasMultimedia»

mkdir -p /share/DescargasMultimedia/Descargas/Descargas
mkdir -p /share/DescargasMultimedia/Descargas/Torrents

Toda la información del Docker de Transmission la podéis leer aquí.

Para instalar transmission podemos hacerlo directamente con «Docker run», o utilizando el docker-compose anterior y añadiendo solamente lo necesario:

## Transmission - torrent
transmission:
image: ghcr.io/linuxserver/transmission
container_name: transmission
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
- USER=username
- PASS=password
volumes:
- /share/DockerCarpeta/Docker/transmission:/config
- /share/DescargasMultimedia/Descargas/Descargas:/downloads
- /share/DescargasMultimedia/Descargas/Torrents:/watch
- /etc/localtime:/etc/localtime:ro
ports:
- 9091:9091
- 51413:51413
- 51413:51413/udp
restart: always
networks:
- redeszone

Esto lo tenemos que situar al final, justo antes de:

#Podemos crear una red privada y otra publica
networks:
redeszone:
external: true #red publica

El archivo docker-compose final sería así:

version: '3.7'

services:

## duckdns - actualizar ip publica dinamica
duckdns:
image: ghcr.io/linuxserver/duckdns
container_name: duckdns
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
- SUBDOMAINS=bronredeszone
- TOKEN=7bd4e748-e9fe-42e7-917c-c99c113a7fb1
- LOG_FILE=true
volumes:
- /share/DockerCarpeta/Docker/duckdns:/config
restart: always
networks:
- redeszone

## Portainer - Gestor Dockers
portainer:
container_name: portainer
image: portainer/portainer
command: -H unix:///var/run/docker.sock
restart: always
ports:
- 9000:9000
- 8000:8000
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /share/DockerCarpeta/Docker/portainer:/data
networks:
- redeszone

## Traefik proxy inverso
traefik:
container_name: traefik
image: traefik:v2.4
restart: always
ports:
- 80:80
- 443:443
- 8082:8082
environment:
- TZ=Europe/Madrid
- DUCKDNS_TOKEN=7bd4e748-e9fe-42e7-917c-c99c113a7fb1
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- /share/DockerCarpeta/Docker/traefik/traefik.yml:/etc/traefik/traefik.yml
- /share/DockerCarpeta/Docker/traefik:/etc/traefik
- /share/DockerCarpeta/Docker/traefik/letsencrypt:/letsencrypt
networks:
- redeszone

## whoami - Hacer pruebas de la red y la ruta y los certificados
whoami:
container_name: whoami
image: traefik/whoami
ports:
- 34280:80
networks:
- redeszone

## Certs-Dump - convierte el json en diferentes .crt y .key
traefik-certs-dumper:
container_name: certs-dumper
image: ldez/traefik-certs-dumper:v2.7.4
entrypoint: sh -c '
apk add jq
; while ! [ -e /data/acme.json ]
|| ! [ `jq ".[] | .Certificates | length" /data/acme.json` != 0 ]; do
sleep 1
; done
&& traefik-certs-dumper file --version v2 --watch
--source /data/acme.json --dest /data/certs'
volumes:
- /share/DockerCarpeta/Docker/traefik/letsencrypt:/data

## Transmission - torrent
transmission:
image: ghcr.io/linuxserver/transmission
container_name: transmission
environment:
- PUID=1000
- PGID=1000
- TZ=Europe/Madrid
- USER=username
- PASS=password
volumes:
- /share/DockerCarpeta/Docker/transmission:/config
- /share/DescargasMultimedia/Descargas/Descargas:/downloads
- /share/DescargasMultimedia/Descargas/Torrents:/watch
- /etc/localtime:/etc/localtime:ro
ports:
- 9091:9091
- 51413:51413
- 51413:51413/udp
restart: always
networks:
- redeszone

#Podemos crear una red privada y otra publica
networks:
redeszone:
external: true #red publica

En estos instantes ya podremos acceder de forma local a transmission, poniendo la dirección IP de tu NAS seguido del puerto 9091 de administración.

Si quieres tener acceso desde fuera vía HTTPS a través de traefik, ahora en el archivo «dynamic-conf.yml» de traefik deberemos configurar tanto un «routers» como un «services», de la siguiente forma y ubicado donde corresponde.

router-transmission:
rule: Host(`transmission.bronredeszone.duckdns.org`)
middlewares: security
service: service-transmission
tls:
certResolver: lets-encrypt

Y también el services:

service-transmission:
loadBalancer:
servers:
- url: "http://10.11.1.9:9091"

El archivo completo de «dynamic-conf.yml» quedaría de la siguiente forma:

tls:
options:
default:
minVersion: VersionTLS12
sniStrict: true
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
curvePreferences:
- CurveP521
- CurveP384

http:
routers:
api:
rule: Host(`traefik.bronredeszone.duckdns.org`)
entrypoints:
- web-secure
middlewares: simpleAuth
service: api@internal
tls:
certResolver: lets-encrypt

router-qts:
rule: Host(`qts.bronredeszone.duckdns.org`)
middlewares: security
service: service-qts
tls:
certResolver: lets-encrypt

router-portainer:
rule: Host(`portainer.bronredeszone.duckdns.org`)
middlewares: security
service: service-portainer
tls:
certResolver: lets-encrypt

router-whoami:
rule: Host(`whoami.bronredeszone.duckdns.org`)
middlewares: security
service: service-whoami
tls:
certResolver: lets-encrypt
router-transmission:
rule: Host(`transmission.bronredeszone.duckdns.org`)
middlewares: security
service: service-transmission
tls:
certResolver: lets-encrypt
services:
service-qts:
loadBalancer:
servers:
- url: "http://10.11.1.9:8080"

service-portainer:
loadBalancer:
servers:
- url: "http://10.11.1.9:9000"

service-whoami:
loadBalancer:
servers:
- url: "http://10.11.1.9:34280"
service-transmission:
loadBalancer:
servers:
- url: "http://10.11.1.9:9091"

middlewares:
simpleAuth:
basicAuth:
users:
- admin:$2y$10$bae.2vNFdoXyBOLHiZDeJOSf8Y3finp9NGC9IqRxhHz9Y5SolHff.
- redeszone:$2y$10$e3.Qyf2yRoe1pc.KlYyaW.Pc/muW8irPG6MgaKEO9AdzV5ZzgYOCG.
security:
headers:
accessControlAllowMethods:
- GET
- OPTIONS
- PUT
accessControlMaxAge: 100
addVaryHeader: true
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
frameDeny: true
sslRedirect: true
sslForceHost: true
stsPreload: true
customFrameOptionsValue: SAMEORIGIN
referrerPolicy: "same-origin"
featurePolicy: "camera 'none'; microphone 'none'; payment 'none'; usb 'none'; vr 'none'; vibrate 'self';"
stsSeconds: 315360000
hostsProxyHeaders:
- "X-Forwarded-Host"

Próximamente ampliaremos este largo tutorial incorporando más servicios, pero tal y como habéis visto ampliar los contenedores e integrarlos en Traefik es realmente fácil y sencillo. Lo más importante es tener bien configurado los archivos de traefik.yml y el dynamic-conf.yml, una vez hecho simplemente es ampliar el número de servicios disponibles.

Agradecemos a Victor Sanz (@vsanz1001) su gran ayuda por toda su ayuda y pruebas para la realización de este completo tutorial de configuración y puesta en marcha.

¡Sé el primero en comentar!