587 - Traefik, Docker y Crowdsec o dos días sin servidor
Como tener tus servicios autoalojados en tu #vps o en una #raspberry protegidos y actualizados con #traefik #docker #crowdsec y #watchtower
Hace un par de días cuando me preparaba para correr, me di cuenta que los podcast que escucho mediante u2vpodcast no se sincronizaban. Era como si no hubiera acceso al servidor. Y no es que fuera como si, es que realmente no había acceso al servidor. La cuestión es que no le di mas importancia que esta, y continué como si tal. Posteriormente, intenté escuchar la música que tengo alojada en el servidor mediante Navidrome, y tampoco me permitía. Y es que en lugar de utilizar Spotify u otros servicios, para trabajar utilizo Symfonium para escuchar música, y así me permite concentrarme. Symfonium es una aplicación de Android que me permite escuchar la música de Navidrome. Llegados a este punto, salió el detective que llevo dentro y deduje que algo pasaba en el servidor. Todo tenía que ver con Traefik, Docker, Crowdsec y WatchTower.
Traefik, Docker y Crowdsec o dos días sin servidor
Un paseo por el pasado
Actualmente, como he comentado en mas de una ocasión, tengo mas de cuarenta servicios funcionando en el servidor VPS que tengo contratado actualmente. Inicialmente, comencé con los servicios instalados en la propia máquina, en el propio servidor, pero con el paso del tiempo los fui migrando a Docker, por la facilidad que representa poner un servicio en funcionamiento desde Docker.
El proxy inverso
El primer problema con el que te enfrentas con tanto servidor funcionando es como alcanzar la página web de cada uno de ellos. Para solucionarlo, existen los proxy inverso. Un proxy inverso, no es ni mas ni menos, que un servicio que se encarga de llevarte a la web del servicio en función de la url que indiques, o en base a el puerto, por ejemplo. Con esto, la parte de direccionamiento la tienes resuelta.
Existen multitud de proxy inverso que te permiten hacer este tipo de operaciones. En particular, yo estoy utilizando de forma habitual Caddy y Traefik. En particular, para mis servicios utilizo Traefik, porque es el que mas flexibilidad me aporta.
Traefik se conecta al socket de Docker y es capaz, en base a las etiquetas que añadimos al despliegue del contenedor, indicar como dirigir el tráfico.
Seguridad
Por supuesto que con tanto servicio en marcha es necesario de añadir una capa de seguridad a tu sistema. Existen distintos mecanismos que te ayudaran a esto, por ejemplo el hardening, pero además de esto, también puedes recurrir a herramientas como fail2ban o Crowdec, por ejemplo. En mi caso yo me decanté por Crowdsec.
Crowdsec es un servicio que es capaz de detectar un ataque DDoS, un escaneo de puertos o de vulnerabilidades, intentos de acceso incorrectos, ya sea a una web a RDP, SSH, etc. En caso de detectar ese acceso indebido, Crowdsec realiza algún tipo de acción, como puede ser por ejemplo un baneo de IP.
Este baneo de IP, lo puede hacer a nivel de Sistema Operativo, o, si lo combinas con Traefik, el baneo lo hace directamente con Traefik, siendo Traefik el encargado de realizar la denegación de servicio para las IP baneadas.
Como ves se trata de un servicio realmente espectacular y una medida de serguridad mas que excelente.
Las actualizaciones
Por último y para completar el círculo, y siguiendo con el tema de seguridad, están las actualizaciones. La he querido separar de la seguridad, porque aquí hay dos vertientes, la primera es clara, que es la comentada en el punto anterior, pero la segunda es tener tus servicios con las últimas características proporcionadas por los desarrolladores.
Las actualizaciones las puedes hacer de forma manual, lo cual es un problema, sobre todo en el caso de una vulnerabilidad, dado que entre el descubrimiento de la vulnerabilidad y el parcheo pasa un tiempo precioso. O lo puedes hacer de forma automática.
En mi caso, yo me decanté por las forma automática, aprovechando las características de Docker. Básicamente aprovechando el socket de Docker, que permite saber que servicios están funcionando y actuar sobre ellos.
Esto es precisamente lo que hace WatchTower. Este servicio se encarga de revisar todos y cada uno de las imágenes Docker que tienes desplegadas y en su caso notificarte o actualizar aquellas que tengan una versión mas actualizadas en sus correspondientes repositorios.
Las actualizaciones las carga el diablo
En general, yo tengo WatchTower habilitado para todos los servicios, excepto para Traefik, para evitar, que en un momento realice una actualización y me quede sin ninguno de los servicios.
Y como ya habrás deducido, fue este precisamente el problema, no que se actualizara la imagen de Traefik, sino la que se actualizó fue la imagen de Crowdsec, y por la razón que fuera, no consiguió levantar correctamente.
Al parecer, la configuración de la nueva versión no era compatible con la antigua o algo similar. Esto es por lo menos lo que conseguí deducir de los logs.
La solución fue sencilla, eliminar la configuración antigua y levantar de nuevo, y así se restableció todo. Pero, por este problema, estuve un par de días sin mis servicios.
La conclusión es evidente, tengo que aplicar la misma solución a Crowdsec que la que tengo con Traefik.
Algunos cambios en Traefik
Aprovechando este trabajo estuve realizando algunas cambios adicionales en Traefik, que me facilitaran levantar nuevos contenedores Docker. Algunos de estos cambios te los indico a continuación,
- tls activado de forma automática para todos los servicios, de forma que no lo tengo que declarar en cada uno de ellos
- crowdsec activado de forma automática para todos los servicios, de forma que no lo tengo que declarar en cada uno de ellos
Para esto, lo que tengo es la siguiente configuración,
entryPoints:
http:
address: ":80"
http:
redirections:
entryPoint:
to: https
scheme: https
permanent: true
middlewares:
- crowdsec-bouncer
https:
address: ":443"
http:
tls:
certResolver: myresolver
middlewares:
- crowdsec-bouncer
y en dynamic.yml
tengo lo siguiente,
http:
middlewares:
crowdsec-bouncer:
forwardauth:
address: http://bouncer-traefik:8080/api/v1/forwarddAuth
trustForwardHeader: true
dless
Por último, y dado que tengo los logs de Traefik en un volumen destinado a ello, revisar estos logs no es tan sencillo como en el caso de un contenedor normal. Para eso implementé un sencillo script, al que le puse el nombre de dless
, que me permite de una forma bastante sencilla e intuitiva navegar por los logs de un determinado contenedor. De esta manera, tan solo tengo que hacer lo siguiente,
dless traefik:/var/log/traefik/traefik.log
Para utilizar less
con los logs en un determinado contenedor. Y quien dice logs
, dice cualquier otro tipo de archivos.
function dless(){
command="$1"
if [[ -n "$command" && "$command" == *":"* ]]; then
container=${command%:*}
filepath=${command##*:}
docker exec -it "$container" less "$filepath"
fi
}
Muchas gracias por estas notas. Desde que escuche el podcast el martes los he estado esperando como agua de mayo.
Gracias por todo