Un proxy inverso y balanceador de carga Traefik que vale la pena incluso sin contenedores
(j6b72.de)- Traefik es famoso en entornos de contenedores, pero puede desplegarse como un único ejecutable en Go, por lo que también puede operarse como proxy inverso sin un motor de contenedores
- Más que de la familia nginx/caddy/apache2, que sirve archivos directamente, se parece a un proxy más cercano a HAProxy, con foco en reenviar solicitudes, devolver respuestas y ajustar encabezados
- Incluso sin usar etiquetas de Docker, puede configurarse con el provider de archivos, separando configuración estática y dinámica para gestionar routers, servicios y middlewares
- Soporta TLS Passthrough y entrada/salida del PROXY protocol de HAProxy, pero el PROXY protocol también debe ser compatible con el servicio de destino; apache2 y nginx sí lo soportan
- La integración de autenticación y el bloqueo por user-agent o IP pueden quedarse cortos con las funciones nativas, así que también hay que evaluar la carga de administrar ForwardAuth, oauth2-proxy y plugins de terceros
Traefik también sirve fuera de los contenedores
- Traefik ganó popularidad en los últimos años dentro del ámbito de YouTube de home lab, y normalmente se presenta junto con infraestructura de contenedores como Docker o Kubernetes
- Por su naturaleza funcional, está más cerca de HAProxy que de nginx/caddy/apache2
- Reenvía solicitudes a los servicios y devuelve las respuestas
- Puede modificar encabezados y partes de las solicitudes y respuestas
- No soporta servir archivos
- En entornos de contenedores, Traefik también puede ejecutarse como contenedor y montar el socket de Docker para detectar automáticamente otros contenedores
- El comportamiento del proxy puede configurarse con las etiquetas de Docker de cada contenedor
- Cuando detecta un contenedor nuevo, puede solicitar automáticamente certificados TLS de Let’s Encrypt y publicar el servicio
Binario único y despliegue con systemd
- Traefik está escrito en Go y se compila como un solo archivo ejecutable
- La distribución binaria puede descargarse desde la documentación de instalación de Traefik
- Es posible ejecutar tanto Traefik como los servicios de destino sin motor de contenedores
- Hay un ejemplo de unidad de servicio systemd en el repositorio de Traefik
- En una operación real, además del archivo de configuración, también hace falta crear un usuario dedicado y ajustar los permisos del archivo de configuración
Configuración basada en archivos
- Si no se usan contenedores, no se pueden usar etiquetas de Docker, pero Traefik puede configurarse mediante el provider de archivos
- La configuración se divide, a grandes rasgos, en dos partes
- Configuración estática: define proveedores de certificados como Let’s Encrypt y los entrypoints, es decir, los puertos en los que escucha Traefik
- Configuración dinámica: define routers, servicios y middlewares
- Traefik puede detectar eventos del sistema de archivos y hacer hot reload de la configuración dinámica
- La documentación ofrece conceptos clave y ejemplos de configuración según cada método
- Términos como certificate provider, entrypoint, router, service y middleware pueden consultarse rápidamente en la documentación de Traefik
Comportamiento tras la configuración y depuración
- Cuando la configuración no es correcta, Traefik muestra advertencias
- Los logs por defecto no son demasiados, pero facilitan entender por qué ruta pasa cada solicitud
- Según la experiencia compartida, la configuración inicial se completó rápido y no se encontraron problemas inesperados
TLS Passthrough y PROXY protocol
- Traefik soporta TLS Passthrough
- Permite reenviar tráfico a un servicio web que presenta su propio certificado TLS, sin terminar TLS en el proxy
- También es posible una configuración donde el servicio solicite directamente su certificado de Let’s Encrypt pasando a través de Traefik
- El proxy no puede ver el contenido que está reenviando
- La selección habitual de host virtual se hace con el encabezado HTTP
Host, pero en TLS Passthrough ese encabezado está dentro del contenido cifrado y no puede usarse - El host de destino se elige mediante SNI (Server Name Indication) de TLS, y este método lo usan Traefik y varios servidores web y proxies
- También soporta entrada y salida del PROXY protocol de HAProxy
- Es una forma de transmitir al servicio de destino la información que se pierde cuando el usuario llega primero al proxy
- Se considera más fácil de manejar de forma segura que los encabezados tradicionales
X-Forwarded-... - El servicio de destino también debe soportar PROXY protocol
- apache2 y nginx lo soportan, y la lista de servicios compatibles sigue creciendo
Lo que aún queda debiendo en integración de autenticación
- En nginx se puede usar Vouch Proxy para proteger algunos servicios con Azure AD, hoy conocido como autenticación de Microsoft Entra
- Traefik soporta ForwardAuth, similar al método de autenticación de nginx
- Vouch Proxy todavía no funciona en Traefik y existe un issue abierto al respecto
- Es posible operar una instancia propia de Keycloak e integrarla con AAD para usarla con ForwardAuth, pero la carga inicial de configuración, mantenimiento de seguridad y actualizaciones es alta
- traefik-forward-auth se recomienda con frecuencia, pero su última actualización fue en junio de 2020 y requiere actualizar dependencias, por lo que se consideró difícil de usar
- oauth2-proxy dejó una mala experiencia en el pasado, y poner otro proxy detrás del proxy aumenta la probabilidad de errores porque hay que ajustar HTTP/2·HTTP/3, timeouts, tamaño del cuerpo y configuración de WebSocket en cada proxy intermedio
- Según la actualización del 2024-05-06, oauth2-proxy también puede integrarse vía HTTP API
- Soporta auth_request de nginx
- Soporta ForwardAuth de Traefik
- Este enfoque parece una opción más cercana a la configuración deseada
Bloqueo de user-agent e IP
- Hay casos en los que no se desea que servicios internos sean archivados por archive.org
robots.txty encabezados similares no sirven para bloquear Archive.org; la forma de bloquear sus crawlers es filtrar el user-agentarchive.org_boto bloquear sus rangos de IP- Para bloquear user-agent o direcciones IP en Traefik, no bastan las funciones nativas: hace falta usar plugins de terceros
- Plugin para bloquear user-agent
- Plugin deny IP
- Los plugins de terceros requieren atención en cada actualización y pueden introducir vulnerabilidades de seguridad, por lo que no son preferibles
- Es posible usar el middleware IPAllowList permitiendo todo excepto las IP que se quieran bloquear
- También permite calcular rangos de IP
- No es peor que bloquear directamente, pero no resulta elegante porque al ver solo las subredes restantes es difícil entender qué rangos fueron bloqueados
Ejemplo de estructura de configuración
- El ejemplo se divide entre
/etc/traefik/traefik.ymly/etc/traefik/dynamic.yml - La configuración estática define lo siguiente
- EntryPoints
:80y:443 - Redirección de todos los endpoints HTTP a HTTPS sin excepciones
- Emisión de certificados de Let’s Encrypt usando TLS challenge
- Monitoreo del archivo de configuración dinámica
/etc/traefik/dynamic.yml
- EntryPoints
- La configuración dinámica incluye lo siguiente
- Enrutamiento TCP con TLS Passthrough para
cloud.xx.xyz - Reenvío a un servicio
10.33.1.2:4433de otro host - Activación de PROXY protocol version 2
- Terminación TLS y proxy hacia
http://127.0.0.1:3000paragit.xx.xyz - Middleware que redirige
https://xx.xyz/redirmeplsahttps://google.com - Middleware que añade el encabezado
X-Robots-Tag: noindex, nofollow, nosnippet, noarchive
- Enrutamiento TCP con TLS Passthrough para
1 comentarios
Opiniones de Hacker News
Traefik es bastante bueno, pero sufre el mismo problema terrible que Ansible. Hay muchísima documentación y artículos, pero no puedes encontrar lo que realmente necesitas.
Lo uso desde la v1 y aun así me pierdo seguido en la documentación, lo que resulta muy frustrante. Para proyectos pequeños suelo usar Caddy, porque su documentación no es tan mala como la de Traefik.
Para quienes escriben documentación técnica: la documentación basada en ejemplos solo le sirve a principiantes que están echando un vistazo. Quienes ya conocen el producto necesitan documentación de referencia y listas completas, no descripciones de campos dispersas en 10 páginas de tutoriales. No se enfoquen solo en el proceso de onboarding; hay que pensar en quienes usan el producto todos los días.
Esa es la parte que más molesta, la razón por la que terminé odiando tanto Ansible, y con Traefik pasa algo parecido, aunque en menor medida.
Se asume que uno hará tareas muy simples sobre estructuras de datos muy planas, pero la mayor parte del mundo real no es así. Para usar bien estos lenguajes hay que entender todo un conjunto de reglas implícitas sobre cómo usar YAML, y la documentación casi nunca las explica.
Hay documentación de la configuración propia de cada módulo, pero casi nunca queda claro cómo usar la configuración estándar, cómo manejar los datos devueltos o cómo combinarlos con algo apenas más complejo. Se siente como si te tiraran una docena de ejemplos de un párrafo por elemento, como una pila de ingredientes, y te dijeran que hornees un pastel.
Tuve casi siempre la misma experiencia con varios sistemas de intérpretes de YAML que usé, y recién después de pasar por cientos de miles de líneas de YAML pude hacer el trabajo, pero la documentación no aportaba mucho más que una lista de configuraciones.
Aun así, encontré un flujo de trabajo bastante bueno usando
ansible-doc, y los alias que uso seguido sonalias adl='ansible-doc --list',alias adls='ansible-doc --list | less -S',alias ad='ansible-doc'.Primero busco rápidamente el comando relacionado con
adls, luego reviso la documentación conady casi siempre salto directo al final (G) para ver los ejemplos. Normalmente ahí está justo la respuesta que necesito.Escribir scripts de Ansible depende muchísimo de la documentación, así que creo que incluso en su estado básico debería soportar mejor este proceso de consulta y ofrecer una interfaz que permita encontrar cosas rápido sin tener que crear un montón de alias.
Claro, es su proyecto, pero cada vez que quiero encontrar un método de un objeto tengo que escarbar en largas páginas en prosa. A veces es más fácil simplemente leer el código fuente.
He usado Traefik en producción durante 2 años. Antes usaba NGINX, pero decidí pasarme a Traefik por la integración automática con Let's Encrypt, y me arrepiento de esa decisión
La documentación de Traefik no nos resulta clara ni a mí ni a mi equipo. Es delicada y se comporta de forma extraña sin logs adecuados
Por ejemplo, cuando intento regenerar certificados, falla de forma intermitente y deja producción caída sin saber cuándo se va a recuperar. Estamos volviendo a NGINX
configuration.nix, y por debajo usalego(1)y letsencryptsecurity.acme = { acceptTerms = true; defaults.email = "admin-email@provider.net"; certs."mydomain.example.com" = { domain = "*.mydomain.example.com"; dnsProvider = "cloudflare"; environmentFile = "/path/to/cloudflare/password"; }; };services.caddy.enable = true;services.caddy.virtualHosts."subdomain1.mydomain.example.com" = { extraConfig = '' reverse_proxy 127.0.0.1:1234 ''; useACMEHost = "mydomain.example.com"; };Supongo que configurarlo con nginx sería bastante parecido. https://github.com/go-acme/lego
Era el mismo registrador de dominio, la misma API y la misma configuración de Docker; además activé todos los logs, pero no había ninguna información sobre por qué no se generaba el certificado. Simplemente volvía al certificado predeterminado generado, como si ni siquiera lo hubiera intentado
Después de dos sesiones de resolución de problemas y varias horas de búsqueda, me rendí y tuve que usar un archivo de certificado autofirmado. Es realmente frustrante que no haya ninguna información sobre por qué no funciona, que falle en silencio y pase al comportamiento alternativo
En general, ese fue el mayor problema de Traefik. Cuando funciona, es excelente; pero cuando no, siempre fue difícil depurarlo o encontrar en la documentación la información necesaria. En la empresa planeamos empezar a usar Traefik en producción hacia fin de año, así que espero familiarizarme más con Traefik antes de eso
Lo mejor es que no hay un lenguaje de configuración. Simplemente usas Go
Lo que descubrí después fue que, si el DNS no está configurado correctamente, tras N intentos fallidos de validación Let's Encrypt rechaza volver a intentar la validación TLS-01 durante un tiempo, y el problema que describes suena a algo de ese tipo
Después de pasarme a la validación DNS-01, la experiencia mejoró de golpe muchísimo. También puedes emitir certificados para servicios que no están expuestos públicamente, y requiere mucha menos orquestación que el método TLS-01
Si el proveedor DNS funciona bien, cuando haya un problema es más probable que recibas un error de API antes de que Let's Encrypt valide el registro, y el estado de falla ocurre mucho antes que el backoff por fallas de verificación de Let's Encrypt. Ahora estoy prácticamente decidido a usar solo validación basada en DNS-01 con Let's Encrypt, use Traefik, Caddy, Nginx u otro reverse proxy; y si tengo que usar TLS-01, me aseguraré sí o sí de que todo esté bien desde el inicio con la API de Staging
Como dato, si generas un certificado de Let's Encrypt Staging en Traefik, no hay una buena forma de invalidarlo. Hay que editar el JSON de ACME para eliminar el certificado y reiniciar Traefik para que tome el cambio. Quizá funcione con
SIGHUP, pero no lo he probadoEn general hay muchos fallos silenciosos y comportamientos raros, pero el mayor dolor es que vuelve opacos los errores de servicios de los que depende
Uso Caddy en lugar de Traefik. Para mí es mucho más fácil mantener un Caddyfile que la configuración YAML de Traefik, y mantengo Caddyfiles separados para despliegues locales, de producción y on-premise
También tiene muchos plugins excelentes, y nosotros usamos el plugin coraza WAF para Caddy, que funciona bien
Tiene todo lo que necesito y es mucho más simple
https://github.com/lucaslorentz/caddy-docker-proxy
Por ejemplo, cómo tratar el almacenamiento local cuando se usa almacenamiento externo. Se dice que puede tratarse como sin estado, pero quizá no sea así
Al final tienes que rezar para que quien creó el módulo que necesitas sepa bien lo que hace. Porque ahí tampoco hay un estándar de documentación. Los mantenedores deberían poner freno a módulos aleatorios que ofrecen funcionalidades clave con cero documentación, como por ejemplo un backend de almacenamiento S3
Si la necesidad es modesta, como unas pocas máquinas host con Docker y unas decenas de contenedores, me pregunto qué razón habría para usar Traefik en vez de nginx. Yo uso https://github.com/NginxProxyManager/nginx-proxy-manager; ¿Traefik daría alguna ventaja a esta escala tan chica?
La verdad, también está el hecho de que no me gusta la sintaxis de nginx y Traefik me pareció brillante. Entré por la renovación de Let's Encrypt y los contenedores, y me quedé por la forma de configurarlo.
Creo que recién consideraría migrar en el momento en que necesitara alguna función que Traefik ofrece y Nginx no.
También me parece un poco raro que Let's Encrypt automático sea un punto de venta, cuando Certbot está por todos lados y soporta más escenarios. Los argumentos de venta de Traefik y Caddy no me terminan de convencer, porque no son tanto algo que hagan más fácil que una alternativa ya ampliamente soportada.
Hace unas semanas estaba eligiendo un proxy inverso y al final me decidí por Caddy por su simplicidad. Dicho eso, el descubrimiento automático de contenedores de Traefik y las referencias por labels están bastante buenos, y Caddy también tiene un plugin que hace lo mismo.
Leí el artículo, pero todavía no estoy seguro de que Traefik tenga algo mejor que Caddy para mí. Puede que para otras personas sí, así que me gustaría escuchar opiniones.
También vale la pena señalar que Traefik viene configurado por defecto en K3s. Gracias a eso, K3s se convirtió en la forma más rápida de levantar un clúster de K8s para pruebas, y permite tratar los clústeres como ganado.
Con solo agregar el deployment y los servicios relacionados como NodePort, puedes acceder a la app sin preocuparte por el ingress controller.
Yo levanto clústeres K3s con un script de shell y pruebo, cuando lo necesito, la app indicada como argumento posicional. Para eso uso el registro temporal de contenedores de ttl.sh. Cuando el mismo script termina, también elimina el clúster.
Estoy pensando en mover mi proxy inverso para self-hosting a Traefik. A diferencia del autor, yo ejecuto cargas de trabajo contenerizadas con Docker Compose y ahora uso Caddy junto con el excelente plugin caddy-docker-proxy.
Lo que obtengo actualmente es un proxy inverso configurado con labels de Docker, detección automática de nuevas cargas de trabajo, certificados TLS y configuración automática de DNS mediante el plugin caddy-dynamicdns. No tengo que preocuparme demasiado por perder acceso si mi ISP me asigna otra IP.
Sin embargo, cada vez que se agrega o reinicia una carga de trabajo, Caddy completo se reinicia y el acceso se corta temporalmente. Caddy no puede pasar las conexiones existentes a la nueva instancia.
Además, usar certificados wildcard no es lo bastante simple. No quiero que todas mis cargas de trabajo queden expuestas al mundo a través de los logs de transparencia de certificados, así que uso un certificado wildcard, pero entonces no puedo usar la sintaxis sencilla de Caddyfile con un certificado por hostname. Sé que están trabajando en eso en Caddy, pero por ahora es así.
En cualquier caso, ya usé Traefik en entornos k8s y me pareció bastante bueno, así que pienso probarlo también para uso personal. Ojalá este comentario no haga que alguien deje de probar Caddy. Caddy también es realmente muy bueno.
localtest.mejunto con el hostname.Vale la pena probarlo. Los dos son excelentes en ámbitos distintos.
En realidad no hace falta ningún plugin. Tengo un playbook de Ansible que configura todo eso en una VM e incluso genera la plantilla del archivo compose, y otro playbook que elimina todo del servidor excepto los datos y los mounts. Para backups uso restic junto con scripts personalizados que pueden respaldar archivos y varias bases de datos, entre otras cosas, en varias ubicaciones.
Antes desplegaba k3s, pero me di cuenta de que para self-hosting era demasiado y demasiado complejo. Yo solo quiero desplegar rápido y no tener que manejar certificados manualmente.
Acabo de comprobarlo en local y funciona bien.
Usé bastante Traefik, pero me cansé de manejar labels de docker-compose, capas y un montón de líneas solo para tener un proxy inverso. Luego descubrí Caddy y no miré atrás.
Probablemente yo no era el usuario objetivo de Traefik. Lo que necesito es un proxy inverso con HTTPS activado o, como mucho, una capa de autenticación básica. En Caddy ambas cosas son de una línea, muy concisas, y no hay capas que todavía no entienda.
Durante varios años he usado Traefik para todo mi self-hosting.
Pero descarté el descubrimiento dinámico y la función de etiquetas de Docker porque eran demasiado complicados y molestos de depurar.
En su lugar, genero archivos de configuración estáticos con un motor de plantillas. Casi todos los servicios son una combinación de host/target/port, así que es muy fácil crear las secciones correspondientes, y no hay middleware complejo aparte del manejo de TLS. Parece que el autor del artículo enlazado tomó el mismo camino.
La configuración se genera con scripts de Ansible, luego se copia a la máquina donde corre Traefik, y Traefik vigila el directorio donde está ese archivo y lo recarga automáticamente cuando cambia. Ha funcionado muy bien.
Uso Traefik con contenedores en producción, y lo que más me gusta es que la configuración va cargada como etiquetas de contenedor. Por eso casi nunca tengo que modificar la configuración de Traefik en sí.
La mayor desventaja es averiguar cómo se supone que se pronuncia el nombre. Parece que simplemente se lee como el traffic común, pero me dan ganas de decir algo como “trey-feek”.
Creo que Traefik junto con Docker Compose es un buen punto intermedio para self-hosting pequeño antes de que crezca lo suficiente como para irse a k8s, sobre todo cuando se tienen menos servidores que los que usa un plano de control de alta disponibilidad de k8s.
La cantidad de muecas y risas que recibimos de colegas fue enorme, y eso estorbó la adopción y el uso del producto.
Nosotros le decíamos “tray-feek” y más o menos estaba bien, pero al hablar con soporte oficial nos dijeron que se pronuncia exactamente igual que el “traffic” normal. Así que cada vez que hablamos de ese proxy, terminamos con frases como: “recibimos traffic en el balanceador de carga público, y el balanceo de carga nativo de traffic envía el traffic a los pods de traffic”. Suena tonto, y de hecho es tonto.
Si no fuera así, sería más fácil hacer cosas interesantes como una página de mantenimiento o levantar un contenedor con la primera solicitud después de estar inactivo.
Por eso estoy pensando en crear un plugin que sepa dónde están guardados los archivos de Compose y pueda leerlos directamente desde ahí.
aees más cercano ayohi. Así que mi apuesta es Tryfik; si no, Trayfik. Si elfikes a la europea, también podría ser feek.