--- title: "Cómo instalar Traefik v3 como proxy inverso en Ubuntu 24.04" description: "Instala Traefik v3 en Ubuntu 24.04 como servicio de systemd, publica una aplicación con HTTPS de Let's Encrypt y protege el dashboard con autenticación básica." category: "Proxy y Equilibrio de Carga" language: es source: https://cubepath.com/es/docs/proxy-y-equilibrio-de-carga/instalacion-del-proxy-inverso-traefik updated: 2026-09-25 --- # Cómo instalar Traefik v3 como proxy inverso en Ubuntu 24.04 Traefik es un proxy inverso y balanceador de carga escrito en Go que obtiene certificados de Let's Encrypt automáticamente y recarga sus rutas en caliente, sin reiniciar el proceso. Aunque es muy popular con Docker y Kubernetes, también funciona perfectamente como binario independiente delante de aplicaciones que corren en el propio servidor. En este tutorial instalarás Traefik v3 en Ubuntu 24.04 como servicio de systemd con un usuario sin privilegios, publicarás una aplicación local con HTTPS y protegerás el dashboard con usuario y contraseña. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. - Un usuario no root con privilegios `sudo`. - Un dominio con dos registros DNS de tipo A apuntando a la IP del servidor: `your_domain` (para la aplicación) y `traefik.your_domain` (para el dashboard). - Los puertos 80 y 443 libres: si tienes Nginx o Apache instalados, detenlos antes de empezar. A lo largo de la guía sustituye **`your_domain`** por tu dominio y **`admin@your_domain`** por un correo real, que Let's Encrypt usa para avisos de caducidad. ## Paso 1: Descargar el binario de Traefik Traefik se distribuye como un único binario en las releases de GitHub. Obtén el número de la última versión publicada: ```bash TRAEFIK_VERSION=$(curl -fsSL https://api.github.com/repos/traefik/traefik/releases/latest | grep -Po '"tag_name": "\K[^"]+') echo "$TRAEFIK_VERSION" ``` ```output v3.7.13 ``` Comprueba que empieza por `v3`. Descarga el archivo para tu arquitectura (`amd64` en la mayoría de servidores, `arm64` en ARM) junto con su archivo de sumas de verificación: ```bash cd /tmp curl -fsSLO "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_linux_amd64.tar.gz" curl -fsSLO "https://github.com/traefik/traefik/releases/download/${TRAEFIK_VERSION}/traefik_${TRAEFIK_VERSION}_checksums.txt" sha256sum --ignore-missing -c "traefik_${TRAEFIK_VERSION}_checksums.txt" ``` ```output traefik_v3.7.13_linux_amd64.tar.gz: OK ``` Extrae el binario e instálalo en `/usr/local/bin`: ```bash tar -xzf "traefik_${TRAEFIK_VERSION}_linux_amd64.tar.gz" traefik sudo install -m 0755 traefik /usr/local/bin/traefik traefik version ``` ```output Version: 3.7.13 Codename: langres Go version: go1.26.8 Built: 2026-09-04T12:32:22Z OS/Arch: linux/amd64 ``` ## Paso 2: Crear el usuario y los directorios Traefik no necesita ejecutarse como root. Crea un usuario de sistema sin shell ni directorio personal: ```bash sudo useradd --system --no-create-home --shell /usr/sbin/nologin traefik ``` Crea el directorio de configuración, uno para la configuración dinámica y otro para guardar los certificados: ```bash sudo mkdir -p /etc/traefik/dynamic /var/lib/traefik sudo chown -R root:traefik /etc/traefik sudo chmod 750 /etc/traefik /etc/traefik/dynamic sudo chown traefik:traefik /var/lib/traefik sudo chmod 700 /var/lib/traefik ``` Traefik guarda los certificados y sus claves privadas en un archivo JSON y se niega a usarlo si otros usuarios pueden leerlo. Créalo vacío con permisos `600`: ```bash sudo install -o traefik -g traefik -m 600 /dev/null /var/lib/traefik/acme.json ``` ## Paso 3: Escribir la configuración estática Traefik separa dos tipos de configuración: - **Estática** (`traefik.yml`): puntos de entrada, proveedores y resolvedores de certificados. Se lee al arrancar. - **Dinámica** (archivos en `/etc/traefik/dynamic/`): routers, servicios y middlewares. Traefik la recarga automáticamente al detectar cambios. Crea la configuración estática: ```bash sudo nano /etc/traefik/traefik.yml ``` ```yaml entryPoints: web: address: ":80" http: redirections: entryPoint: to: websecure scheme: https websecure: address: ":443" certificatesResolvers: letsencrypt: acme: email: admin@your_domain storage: /var/lib/traefik/acme.json httpChallenge: entryPoint: web providers: file: directory: /etc/traefik/dynamic watch: true api: dashboard: true log: level: INFO accessLog: {} ``` Qué hace cada bloque: - `entryPoints`: Traefik escucha en los puertos 80 y 443 y redirige todo el tráfico HTTP a HTTPS. - `certificatesResolvers`: define `letsencrypt`, que obtiene certificados mediante el reto HTTP-01 en el puerto 80. - `providers.file`: lee rutas desde archivos YAML y las recarga al cambiar. - `api.dashboard`: activa el dashboard, que solo será accesible a través del router protegido que crearás en el paso 6. - `log` y `accessLog`: sin archivo de destino, ambos van a la salida estándar y los recoge el journal de systemd. ## Paso 4: Crear el servicio de systemd Crea la unidad de systemd. `AmbientCapabilities=CAP_NET_BIND_SERVICE` permite al usuario `traefik` escuchar en los puertos 80 y 443 sin ser root, y las opciones `Protect*` limitan lo que el proceso puede modificar en el sistema: ```bash sudo nano /etc/systemd/system/traefik.service ``` ```ini [Unit] Description=Traefik reverse proxy Documentation=https://doc.traefik.io/traefik/ Wants=network-online.target After=network-online.target [Service] User=traefik Group=traefik ExecStart=/usr/local/bin/traefik --configFile=/etc/traefik/traefik.yml Restart=on-failure AmbientCapabilities=CAP_NET_BIND_SERVICE CapabilityBoundingSet=CAP_NET_BIND_SERVICE NoNewPrivileges=true ProtectSystem=strict ProtectHome=true PrivateTmp=true ReadWritePaths=/var/lib/traefik LimitNOFILE=1048576 [Install] WantedBy=multi-user.target ``` Abre los puertos en el firewall. Si UFW está activo, recuerda permitir también SSH para no perder el acceso: ```bash sudo ufw allow OpenSSH sudo ufw allow 80/tcp sudo ufw allow 443/tcp ``` Arranca Traefik y habilítalo al inicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now traefik sudo systemctl status traefik --no-pager ``` ```output ● traefik.service - Traefik reverse proxy Loaded: loaded (/etc/systemd/system/traefik.service; enabled; preset: enabled) Active: active (running) since Thu 2026-09-25 10:04:12 UTC; 3s ago ``` Comprueba que escucha en ambos puertos: ```bash sudo ss -tlnp | grep traefik ``` ```output LISTEN 0 4096 *:443 *:* users:(("traefik",pid=2215,fd=8)) LISTEN 0 4096 *:80 *:* users:(("traefik",pid=2215,fd=7)) ``` ## Paso 5: Publicar una aplicación con HTTPS Para la prueba necesitas una aplicación escuchando en local. Si todavía no tienes una, abre una segunda terminal y arranca un servidor HTTP de prueba con Python en el puerto 8080, solo en `127.0.0.1`: ```bash mkdir -p ~/demo && echo "Hola desde el backend" > ~/demo/index.html python3 -m http.server 8080 --bind 127.0.0.1 --directory ~/demo ``` De vuelta en la primera terminal, crea la configuración dinámica. Un **router** decide qué peticiones atiende (por el nombre de host) y un **servicio** define a qué backend las envía: ```bash sudo nano /etc/traefik/dynamic/app.yml ``` ```yaml http: routers: app: rule: "Host(`your_domain`)" entryPoints: - websecure service: app tls: certResolver: letsencrypt services: app: loadBalancer: servers: - url: "http://127.0.0.1:8080" ``` Asigna el archivo al grupo `traefik` para que pueda leerlo: ```bash sudo chown root:traefik /etc/traefik/dynamic/app.yml sudo chmod 640 /etc/traefik/dynamic/app.yml ``` No hace falta reiniciar nada: Traefik detecta el archivo nuevo, crea el router y solicita el certificado. Sigue el proceso en el journal: ```bash sudo journalctl -u traefik -f ``` Si ves errores de ACME, revisa la sección de solución de problemas. Cuando el certificado esté listo, pulsa `Ctrl+C` y prueba la aplicación: ```bash curl -I http://your_domain curl https://your_domain ``` La primera petición devuelve una redirección permanente (código 301 o 308) a `https://your_domain/`, y la segunda el contenido del backend: ```output Hola desde el backend ``` Para repartir carga entre varios backends basta con añadir más entradas a `servers`. Traefik las usa en round robin. ## Paso 6: Proteger el dashboard El dashboard muestra todos los routers, servicios y middlewares activos, por lo que nunca debe quedar abierto. Instala `htpasswd` para generar la contraseña cifrada con bcrypt: ```bash sudo apt install apache2-utils htpasswd -nB admin ``` Introduce una contraseña robusta cuando la pida. El comando imprime una línea como esta, que usarás en la configuración: ```output admin:$2y$05$3Q2m8kYx1vQ7bq0Jd1Hk9eQyA3Zb7x1bJ0Vn8S1pD8m2Qf0nWkZ5G ``` Crea el router del dashboard con un middleware de autenticación básica: ```bash sudo nano /etc/traefik/dynamic/dashboard.yml ``` ```yaml http: routers: dashboard: rule: "Host(`traefik.your_domain`)" entryPoints: - websecure service: api@internal middlewares: - dashboard-auth tls: certResolver: letsencrypt middlewares: dashboard-auth: basicAuth: users: - 'admin:$2y$05$3Q2m8kYx1vQ7bq0Jd1Hk9eQyA3Zb7x1bJ0Vn8S1pD8m2Qf0nWkZ5G' ``` Sustituye el hash por el que generaste. Usa comillas simples para que el `$` no se interprete. `api@internal` es el servicio interno de Traefik que sirve el dashboard y la API. ```bash sudo chown root:traefik /etc/traefik/dynamic/dashboard.yml sudo chmod 640 /etc/traefik/dynamic/dashboard.yml ``` Comprueba que sin credenciales se rechaza el acceso y con ellas no: ```bash curl -s -o /dev/null -w "%{http_code}\n" https://traefik.your_domain/dashboard/ curl -s -o /dev/null -w "%{http_code}\n" -u admin https://traefik.your_domain/dashboard/ ``` ```output 401 200 ``` Abre `https://traefik.your_domain/dashboard/` en el navegador (la barra final es necesaria) para ver los routers `app` y `dashboard` en verde. ## Paso 7: Añadir cabeceras de seguridad Los middlewares se reutilizan entre routers. Añade uno que envíe HSTS y otras cabeceras de seguridad a la aplicación editando `/etc/traefik/dynamic/app.yml`: ```bash sudo nano /etc/traefik/dynamic/app.yml ``` ```yaml http: routers: app: rule: "Host(`your_domain`)" entryPoints: - websecure service: app middlewares: - security-headers tls: certResolver: letsencrypt middlewares: security-headers: headers: stsSeconds: 31536000 stsIncludeSubdomains: true contentTypeNosniff: true frameDeny: true referrerPolicy: "strict-origin-when-cross-origin" services: app: loadBalancer: servers: - url: "http://127.0.0.1:8080" ``` Verifica las cabeceras: ```bash curl -sI https://your_domain | grep -iE 'strict-transport|x-frame|x-content' ``` ```output strict-transport-security: max-age=31536000; includeSubDomains x-content-type-options: nosniff x-frame-options: DENY ``` ## Solución de problemas - **`acme: error: 400 ... Timeout during connect` o `Connection refused` en el journal**: Let's Encrypt no llega al puerto 80. Comprueba el registro DNS con `dig +short your_domain` y que el puerto 80 esté abierto en UFW y en el firewall del proveedor. - **`permissions 644 for /var/lib/traefik/acme.json are too open`**: ejecuta `sudo chmod 600 /var/lib/traefik/acme.json` y reinicia con `sudo systemctl restart traefik`. - **`bind: permission denied` al arrancar**: falta `AmbientCapabilities=CAP_NET_BIND_SERVICE` en la unidad, o no ejecutaste `daemon-reload` después de editarla. - **404 page not found**: ningún router coincide con la petición. Revisa la regla `Host()` y comprueba en el journal que Traefik no ha rechazado el archivo YAML por un error de sintaxis. - **502 Bad Gateway**: Traefik no conecta con el backend. Verifica que la aplicación escucha en la dirección configurada con `curl http://127.0.0.1:8080`. ## Conclusión Tienes Traefik v3 funcionando como servicio de systemd sin privilegios de root, publicando una aplicación con certificados de Let's Encrypt que se renuevan solos, redirección de HTTP a HTTPS, cabeceras de seguridad y un dashboard protegido. Como siguientes pasos, puedes añadir más aplicaciones con un archivo por servicio en `/etc/traefik/dynamic/`, usar el reto DNS-01 para obtener certificados comodín, o activar el proveedor de Docker para que Traefik descubra contenedores a partir de sus etiquetas.