689 - Cinco recomendaciones para exprimir tu proxy

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

1:25
-3:15

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,

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *