
689 - Cinco recomendaciones para exprimir tu proxy
Desde un login para #traefik hasta bloquear acceso por ip a tus servicios autoalojados y otras cinco recomendaciones para exprimir tu proxy inverso
Si bien llevo utilizando Traefik como proxy inverso varios años mas, habiendo, incluso, superado la transición del 1.7
al 2.X
, lo cierto es que no paro de descubrir nuevas características y opciones para exprimir el proxy. En general la mayoría de las recomendaciones de las que te voy a hablar son aplicables a cualquier proxy, y otras son mas particulares, o al menos mas fáciles de aplicar con Traefik. De cualquier forma, son ideas o conceptos que se pueden trasladar a otros proxy como Caddy o Nginx, de forma mas o menos sencilla. Aquí simplemente se trata de revisar estas recomendaciones y que dependiendo de la solución que tengas la apliques.

Cinco recomendaciones para exprimir tu proxy
Tinyauth con Traefik
La primera de las recomendaciones, te la comenté en el episodio 666 que titulé un login para tus aplicaciones self-hosted, y no es ni mas ni menos que proteger tu proxy inverso con una pantalla de login.
Es posible proteger Traefik utilizando autenticación básica, y además dependiendo de lo que estés haciendo puede llegar a ser aparentemente conveniente, sin embargo, a mi no me gusta, y es mas, no me resulta nada cómodo.
De esta forma, cuando descubrí Tinyauth no me lo pensé y lo fui implantando en los distintos servicios que tengo expuesto y que quiero tener protegidos por una pantalla de login. Sin embargo, no lo pensé para Traefik, y ahora que lo he puesto, me parece que lo tenía que haber hecho desde el principio.
Tinyauth, tiene soporte OAuth, lo que implica que puedes hacer login utilizando Google, GitHub o cualquier proveedor OAuth, y esto para mi representa una comodidad. No tengo que hacer login, si ya tengo sesión en otro de estos servicios puedo entrar en Traefik, de forma sencilla.
En este sentido, para poder utilizar Tinyauth con Traefik, tan solo tienes que añadir el middleware como te muestro a continuación.
- traefik.http.routers.traefik.middlewares=tinyauth@docker,error-pages-middleware@docker
El Healthcheck de Traefik
Otra de las características de las que te hablé recientemente fue el Healthcheck. En concreto en el episodio 688 titulado tu contenedor Docker podría estar muerto y tu sin enterarte, te hablé sobre esta interesante característica que te ofrece Docker, y que te permite saber si el servicio que está corriendo en un contenedor está en estado saludable o ha dejado de responder.
En el caso del Healthcheck de Traefik, tienes que realizar varios cambios en la configuración. Así, lo primero es añadir en la configuración estática, al inicio de ella un ping: {}
, y un nuevo punto de entrada (entryPoint), en concreto,
ping:
address: ":8082"
Y ya en el docker-compose
, lo que tienes que incluir es la parte correspondiente al healthcheck y las etiquetas para la parte del ping,
healthcheck:
test: [ "CMD", "traefik", "healthcheck", "--ping" ]
start_period: 10s
timeout: 5s
retries: 3
labels:
- traefik.http.routers.traefik-ping-web.entrypoints=ping
- traefik.http.routers.traefik-ping-web.rule=PathPrefix(`/ping`)
- traefik.http.routers.traefik-ping-web.service=ping@internal
Las páginas de error
Lo de las páginas de error tiene bastante guasa. Lo cierto es que yo lo tenía en el docker-compose.yml
, de Traefik, desde hace meses, pero hasta hace unos pocos días no lo conseguí hacer funcionar. Y no lo conseguí hacer funcionar por lo mas tonto que se te pueda pasar por la cabeza. Simplemente me faltaban estas dos líneas en la definición,
networks:
- proxy
Tan sencillo como eso. No se como no me había dado cuenta, pero era algo tan simple y que hago de forma habitual, y como por, alguna absurda razón se me había escapado hasta el momento.
¿Que es esto de las páginas de error?. error-pages es un servicio que te proporciona páginas de error para los diferentes estados de error que puedan aparecer. En general, sabes que cuando visitas una página que está detrás de tu proxy inverso, pero que no contiene nada, te mostrará un 404
. Sin embargo, en el caso particular de Traefik, aunque esto es aplicable a cualquier otro, en el caso de que no encuentre nada te muestra un feo mensaje de error. La verdad, esto creo que debería estar resuelto de caja, pero bueno.
Con error-pages, puedes mostrar elegantes y simpáticos mensajes de error, cuando alguien visite esa página. Realmente es muy sencillo de utilizar, y tan solo tienes que elegir el tema que quieres utilizar mediante una variable de entorno.
A continuación te dejo el docker-compose
para que lo puedas empezar a utilizar ya mismo,
error-pages:
image: tarampampam/error-pages:3
container_name: error-pages
init: true
restart: unless-stopped
environment:
TEMPLATE_NAME: hacker-terminal
depends_on:
- traefik
labels:
traefik.enable: true
traefik.http.routers.error-pages-router.rule: HostRegexp(`.+`)
traefik.http.routers.error-pages-router.priority: 10
traefik.http.routers.error-pages-router.entrypoints: https
traefik.http.routers.error-pages-router.middlewares: error-pages-middleware
traefik.http.middlewares.error-pages-middleware.errors.status: 400-599
traefik.http.middlewares.error-pages-middleware.errors.service: error-pages-service
traefik.http.middlewares.error-pages-middleware.errors.query: /{status}.html
traefik.http.services.error-pages-service.loadbalancer.server.port: 8080
networks:
- proxy
Acceder a la API desde Homepage
Como te he contado en recientes episodios, actualmente estoy utilizando Homepage, como mi página de inicio. Un servicio que de un solo vistazo, te permite saber y conocer el estado de tu mundo self-hosted.
Así en mi caso, además conocer el estado de las páginas web que administro, también me da acceso a todos los servicios que tengo allí alojados. En concreto Homepage es otro de esos servicios que tengo detrás de Tinyauth, dado que también lo tengo expuesto.
Además de diferentes accesos y widgets, en mi caso, también tengo información de Traefik directamente en Homepage. Sin embargo, al poner Traefik detrás de Tinyauth, me encontré con el problema de como podía hacer funcionar el widget de Traefik. No puedes hacerlo funcionar directamente a través de la url externa de traefik.
La solución era bien sencilla, simplemente tenía que atacar Traefik desde Homepage a través de la red interna, a través de mi red proxy
. Así añadí las siguientes líneas en la configuración de Traefik,
- traefik.http.routers.traefik-internal.entrypoints=https
- traefik.http.routers.traefik-internal.rule=Host(`traefik`)
- traefik.http.routers.traefik-internal.service=api@internal
Mientras que en la configuración de Homepage
tienes que utilizar lo siguiente para el widget,
- Traefik:
href: https://traefik.tuservicio.es/dashboard/#/
description: Traefik
icon: traefik
container: traefik
widget:
type: traefik
url: https://traefik
Para tu acceder a la página de Traefik, si que lo haces por la url
que indicas en href
, pero para consultar la api de Traefik
, lo haces utilizando directamente https://traefik
, mediante la red proxy.
Algunos middlewares interesantes
Otra de las características que es realmente interesante de Traefik son los middleware. Esto no es ni mas ni menos que servicios o utilidades que se modifican el tráfico, tanto el de entrada como el de salida. Por ejemplo, te permite comprimir el flujo, o añadir cabeceras o incluso bloquear el tráfico de ciertos países.
chain
El primero es una combinación, lo que se conoce un chain
que está compuesto por uno primero correspondiente a unos encabezados de seguridad, que tantos quebraderos de cabeza me ha dado en atareao.es y un segundo que es para comprimir lo que enviamos. Respecto al primero, al de los encabezados de seguridad, te recomiendo que lo utilices con mucho cuidado para no hacerte un mal, como me sucedió a mi. La configuración que tengo en esto es la siguiente,
default:
chain:
middlewares:
- default-security-headers
- gzip
gzip:
compress: {}
default-security-headers:
headers:
browserXssFilter: true # X-XSS-Protection=1; mode=block
contentTypeNosniff: true # X-Content-Type-Options=nosniff
forceSTSHeader: true # Add the Strict-Transport-Security header even when the connection is HTTP
#frameDeny: true # X-Frame-Options=deny
referrerPolicy: "strict-origin-when-cross-origin"
sslRedirect: true # Allow only https requests
stsIncludeSubdomains: true # Add includeSubdomains to the Strict-Transport-Security header
stsPreload: true # Add preload flag appended to the Strict-Transport-Security header
stsSeconds: 63072000
secure-headers:
headers:
# Connection: "keep-alive, Upgrade"
# X-Forwarded-Proto: "https, http, ws, wss"
# Upgrade: "WebSocket"
STSSeconds: "31536000"
STSIncludeSubdomains: "true"
STSPreload: "true"
customRequestHeaders:
Connection: "keep-alive, Upgrade"
X-Forwarded-Host: ""
X-Forwarded-Proto: "https, http, ws, wss"
customResponseHeaders:
Connection: "keep-alive, Upgrade"
X-Forwarded-Host: ""
X-Forwarded-Proto: "https, http, ws, wss"
Upgrade: "WebSocket"
frameDeny: true
contentTypeNosniff: true
browserXssFilter: true
#referrerPolicy: "same-origin"
Geoblock
Este middleware es realmente interesante. En concreto, lo que hace es bloquear el tráfico de ciertos países, o también lo puedes tener configurado, como es mi caso para permitir el paso solo desde ciertos países. Esto puede ser interesante si tienes un servicio que no quieres que sea accesible desde ciertos países.
Aquí tienes que ir con cuidado porque te puedes bloquear tu propio tráfico, que es lo que me pasó a mi en concreto. Y es que resulta que el registry de Docker lo tengo en Alemanía, y como estoy restringiendo el tráfico solo para España, no tenía acceso, hasta que me di cuenta claro. La solución fue, permitirlo puntualmente, y luego volverlo a restringir.
La configuración es la siguiente,
my-geoblock:
plugin:
geoblock:
silentStartUp: false
allowLocalRequests: true
logLocalRequests: false
logAllowedRequests: false
logApiRequests: true
api: "https://get.geojs.io/v1/ip/country/{ip}"
apiTimeoutMs: 750 # optional
cacheSize: 15
forceMonthlyUpdate: true
allowUnknownCountries: false
unknownCountryApiResponse: "nil"
blackListMode: false
countries:
- ES
Torblock
El siguiente middleware es realmente interesante, y es que lo que hace es bloquear el tráfico de la red Tor. Esto puede ser interesante si tienes un servicio que no quieres que sea accesible desde la red Tor. En mi caso, lo tengo configurado para que me bloquee el tráfico de la red Tor.
La configuración es la siguiente,
my-torblock:
plugin:
torblock:
enabled: true
Sablier
Otro middleware muy interesante, aunque ahora mismo no lo estoy utilizando es Sablier. Este middleware te permite levantar un servicio que esté detrás de Traefik, o cualquier otro proxy inverso, a voluntad.
Por ejemplo, hasta hace poco tenía Visual Studio Code autoalojado. De forma que podía programar en remoto en cualquier momento. Sin embargo, tener esto en funcionamiento cuando no lo estás utilizando es un verdadero desperdicio de recursos. Aquí es justo donde entra Sablier, porque mientras no lo estés utilizando, puedes apagar Visual, y cuando lo necesites simplemente te conectas a la url donde se supone que está Visual y Sablier se encarga de despertarlo y ponerlo en funcionamiento. Tienes lo mejor de los dos mundos.
La configuración es la siguiente,
my-sablier:
plugin:
sablier:
group: default
dynamic:
displayName: Territorio Linux
refreshFrequency: 5s
showDetails: "true"
theme: hacker-terminal
sablierUrl: http://sablier:10000
sessionDuration: 1m
Más información,