
En resumen. Pangolin es una alternativa a Cloudflare Tunnels o Tailscale. Alojas el servidor de Pangolin en un VPS con IP pública, instalas el cliente Newt en tu red privada y enrutas el tráfico de forma segura a través de túneles WireGuard. No necesitas abrir ningún puerto en tu router. La configuración toma menos de 30 minutos con Docker Compose. Pangolin gestiona certificados SSL, reverse proxying y control de acceso desde un solo dashboard.
Requisitos previos
Antes de instalar Pangolin, verifica que tienes lo siguiente:
- Un VPS con IP pública. Un Contabo VPS de nivel básico maneja todo el stack sin problema y tiene capacidad para correr servicios adicionales junto a él.
- Ubuntu 22.04, 24.04 o 26.04 (se recomienda una instalación limpia).
- Docker y el plugin de Docker Compose instalados.
- Un dominio o subdominio con un registro A apuntando a la IP del VPS. Necesitas acceso a la gestión de zona DNS de tu dominio.
- Los puertos 22/TCP, 80/TCP, 443/TCP, 51820/UDP y 21820/UDP abiertos en tu firewall. Puedes configurarlo fácilmente con el Contabo Firewall.
En el lado de tu red privada — tu servidor casero, máquina de oficina o cualquier dispositivo remoto — solo necesitas Docker o el binario de Newt. Sin puertos abiertos, sin reenvío de puertos, sin IP pública en esa máquina.
Paso 1: Preparar el VPS
Conéctate por SSH como root y actualiza el sistema antes de continuar.
- Conéctate:
ssh root@<tu-ip-del-vps> - Actualiza:
apt update && apt upgrade -y - Instala Docker y el plugin de Compose desde el repositorio oficial de Docker:
apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \
| tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-pluginVerifica con docker compose version. Deberías ver una versión 2.x.
Luego abre los puertos que necesita Pangolin. Cada Contabo VPS y VDS incluye un firewall integrado gratuito que administras directamente desde el Customer Control Panel, sin instalar software adicional. Abre la guía del Contabo Firewall y agrega reglas de entrada para: 22/TCP, 80/TCP, 443/TCP, 51820/UDP y 21820/UDP.
Paso 2: Instalar Pangolin con Docker Compose
El stack del servidor de Pangolin corre como tres contenedores. Pangolin se encarga del dashboard, la API y el control de acceso. Gerbil administra la interfaz de WireGuard en el VPS y gestiona los puertos expuestos. Traefik corre dentro del namespace de red de Gerbil, no directamente en el host. Traefik termina TLS, aprovisiona certificados de Let’s Encrypt de forma automática y enruta el tráfico HTTP al destino correcto. CrowdSec puede agregarse después como plugin opcional de Traefik para bloqueo basado en reputación.
Crea el directorio del proyecto y los subdirectorios necesarios:
mkdir -p /opt/pangolin/config/db \
/opt/pangolin/config/letsencrypt \
/opt/pangolin/config/traefik/logs
cd /opt/pangolinGenera un secret para la firma de sesiones de Pangolin. Necesitarás el resultado en config.yml:
openssl rand -hex 32Crea los cuatro archivos de configuración a continuación. Escribe cada uno en la ruta indicada antes de pasar al siguiente.
docker-compose.yml
name: pangolin
services:
pangolin:
image: docker.io/fosrl/pangolin:latest
container_name: pangolin
restart: unless-stopped
volumes:
- ./config:/app/config
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
interval: "10s"
timeout: "10s"
retries: 15
gerbil:
image: docker.io/fosrl/gerbil:latest
container_name: gerbil
restart: unless-stopped
depends_on:
pangolin:
condition: service_healthy
command:
- --reachableAt=http://gerbil:3004
- --generateAndSaveKeyTo=/var/config/key
- --remoteConfig=http://pangolin:3001/api/v1/
volumes:
- ./config/:/var/config
cap_add:
- NET_ADMIN
- SYS_MODULE
ports:
- 51820:51820/udp
- 21820:21820/udp
- 443:443
- 80:80
- 22:22
traefik:
image: docker.io/traefik:v3.6
container_name: traefik
restart: unless-stopped
network_mode: service:gerbil
depends_on:
pangolin:
condition: service_healthy
command:
- --configFile=/etc/traefik/traefik_config.yml
volumes:
- ./config/traefik:/etc/traefik:ro
- ./config/letsencrypt:/letsencrypt
- ./config/traefik/logs:/var/log/traefik
networks:
default:
driver: bridge
name: pangolinconfig/traefik/traefik_config.yml — reemplaza [email protected] con tu dirección de correo real:
api:
insecure: true
dashboard: true
providers:
http:
endpoint: "http://pangolin:3001/api/v1/traefik-config"
pollInterval: "5s"
file:
filename: "/etc/traefik/dynamic_config.yml"
experimental:
plugins:
badger:
moduleName: "github.com/fosrl/badger"
version: "v1.4.0"
log:
level: "INFO"
format: "common"
maxSize: 100
maxBackups: 3
maxAge: 3
compress: true
certificatesResolvers:
letsencrypt:
acme:
httpChallenge:
entryPoint: web
email: "[email protected]"
storage: "/letsencrypt/acme.json"
caServer: "https://acme-v02.api.letsencrypt.org/directory"
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
transport:
respondingTimeouts:
readTimeout: "30m"
http:
tls:
certResolver: "letsencrypt"
encodedCharacters:
allowEncodedSlash: true
allowEncodedQuestionMark: true
serversTransport:
insecureSkipVerify: true
ping:
entryPoint: "web"config/traefik/dynamic_config.yml — reemplaza cada instancia de pangolin.example.com con el hostname de tu dashboard:
http:
middlewares:
badger:
plugin:
badger:
disableForwardAuth: true
redirect-to-https:
redirectScheme:
scheme: https
routers:
main-app-router-redirect:
rule: "Host(`pangolin.example.com`)"
service: next-service
entryPoints:
- web
middlewares:
- redirect-to-https
- badger
next-router:
rule: "Host(`pangolin.example.com`) && !PathPrefix(`/api/v1`)"
service: next-service
entryPoints:
- websecure
middlewares:
- badger
tls:
certResolver: letsencrypt
api-router:
rule: "Host(`pangolin.example.com`) && PathPrefix(`/api/v1`)"
service: api-service
entryPoints:
- websecure
middlewares:
- badger
tls:
certResolver: letsencrypt
ws-router:
rule: "Host(`pangolin.example.com`)"
service: api-service
entryPoints:
- websecure
middlewares:
- badger
tls:
certResolver: letsencrypt
services:
next-service:
loadBalancer:
servers:
- url: "http://pangolin:3002"
api-service:
loadBalancer:
servers:
- url: "http://pangolin:3000"
tcp:
serversTransports:
pp-transport-v1:
proxyProtocol:
version: 1
pp-transport-v2:
proxyProtocol:
version: 2config/config.yml — reemplaza los tres dominios de ejemplo y pega el secret generado con openssl:
gerbil:
start_port: 51820
base_endpoint: "pangolin.example.com"
app:
dashboard_url: "https://pangolin.example.com"
log_level: "info"
telemetry:
anonymous_usage: true
domains:
domain1:
base_domain: "example.com"
server:
secret: "paste-your-openssl-output-here"
cors:
origins: ["https://pangolin.example.com"]
methods: ["GET", "POST", "PUT", "DELETE", "PATCH"]
allowed_headers: ["X-CSRF-Token", "Content-Type"]
credentials: false
flags:
require_email_verification: false
disable_signup_without_invite: false
disable_user_create_org: false
allow_raw_resources: truePaso 3: Iniciar Pangolin y acceder al dashboard
- Inicia el stack:
docker compose up -d - Verifica que los tres contenedores estén corriendo:
docker compose ps. Gerbil y Traefik esperan a que el healthcheck de Pangolin pase antes de arrancar, así que dale unos 30 segundos. - Obtén el token de configuración inicial desde los logs de Pangolin:
docker compose logs pangolinBusca el bloque === SETUP TOKEN GENERATED === y copia el token.
- Abre
https://pangolin.example.com/auth/initial-setupen el navegador. La primera solicitud de certificado de Let’s Encrypt puede tardar hasta 60 segundos. Si ves una advertencia de certificado al cargar por primera vez, espera un minuto y recarga la página. - Pega el token de configuración, define tu correo y contraseña de administrador y crea tu primera organización.
Si Traefik no puede obtener un certificado, confirma que tu registro A de DNS ya propagó y que ningún otro proceso está usando los puertos 80 o 443 en el host.
Paso 4: Conectar una red privada con Newt sobre WireGuard
Newt es el agente conector de sitios de Pangolin. Corre en tu red privada, establece una conexión WireGuard saliente hacia el hub de Pangolin y reenvía el tráfico a tus servicios locales. Como Newt inicia la conexión de forma saliente, tu router no necesita puertos abiertos, reenvío de puertos ni IP pública.
En el dashboard de Pangolin, ve a Sites, haz clic en Add Site, elige Newt Tunnel y dale un nombre al sitio. Pangolin te muestra tres credenciales: la URL del endpoint, el Newt ID y el Newt secret. Cópialos todos. Solo se muestran una vez.
En tu servidor casero, despliega Newt con Docker Compose:
services:
newt:
image: fosrl/newt
container_name: newt
restart: unless-stopped
environment:
- PANGOLIN_ENDPOINT=https://pangolin.example.com
- NEWT_ID=<tu-newt-id>
- NEWT_SECRET=<tu-newt-secret>Inícialo con docker compose up -d. En segundos, el indicador del sitio en el dashboard de tu Pangolin cambia a verde y muestra Online.
Paso 5: Exponer tu primer servicio con reverse proxy
Con el túnel de Newt activo, no necesitas editar ningún archivo de configuración para exponer un servicio. Todo se hace desde el dashboard de Pangolin:
- Abre tu sitio y haz clic en Add Resource.
- Dale un nombre a la resource y elige una subdominio.
- En Target Configuration, ingresa la dirección interna del servicio tal como Newt la ve. Para un servicio en 192.168.1.10:3000 en tu red local, ingresa
http://192.168.1.10:3000. Para un servicio en la misma red Docker que Newt, usa el nombre del contenedor y el puerto. - Activa HTTPS. Traefik aprovisiona el certificado de forma automática.
- Define una política de acceso: pública, protegida por contraseña o restringida a usuarios o dominios de correo específicos.
La resource queda disponible en su subdominio en cuestión de segundos. Si agregas un registro A wildcard (*.pangolin.example.com apuntando a la IP del VPS), cada nueva resource es accesible de inmediato sin necesidad de un registro DNS separado por servicio.
Paso 6: Acceso SSH/RDP desde el navegador (desde v1.19)
Desde Pangolin 1.19, SSH, RDP y VNC son tipos de resource públicos de primera clase junto a HTTP. El usuario abre la URL de la resource, se autentica a través de Pangolin y obtiene una sesión interactiva completa en el navegador. No se requiere un cliente SSH separado, una app de escritorio remoto ni un visor de VNC.
Para habilitar SSH desde el navegador en un VPS, haz clic en Add Resource, selecciona SSH como protocolo y elige el modo Pangolin SSH. Este modo solo requiere que Newt corra como root en la máquina destino. No hacen falta cambios en sshd_config ni configuración de PAM. Asigna una subdominio y una política de acceso, y el terminal queda disponible en el navegador.
Para RDP, selecciona RDP como protocolo, apunta el destino a la IP del host Windows y el puerto 3389, y asigna un dominio. La sesión se renderiza en el navegador con soporte completo de portapapeles y transferencia de archivos.
SSH, RDP y VNC desde el navegador requieren Newt 1.13.0 o posterior. Ejecuta docker compose pull && docker compose up -d en tu servidor casero antes de habilitar estos tipos de resource.
Lista de verificación de seguridad
Antes de exponer algo sensible, revisa esta lista:
- Define una contraseña de administrador fuerte y cámbiala de inmediato si usaste una débil durante la configuración inicial.
- Restringe el acceso al dashboard a direcciones IP conocidas mediante una política de acceso de Pangolin.
- Mantén actualizadas las imágenes de Pangolin, Gerbil y Traefik. Ejecuta
docker compose pull && docker compose up -ddesde/opt/pangolinde forma regular. Desde Pangolin 1.19 hay actualizaciones automáticas opcionales de Newt que puedes activar por sitio desde el dashboard. - Confirma que las reglas de tu Contabo Firewall solo permiten los puertos que realmente necesitas.
- Habilita CrowdSec como plugin opcional de Traefik si tus resources reciben tráfico público. Bloquea IPs con mala reputación en el borde antes de que las solicitudes lleguen a tus servicios.
- Haz backup del directorio
config/en el VPS de forma regular. Contiene la base de datos SQLite, los certificados TLS y toda la configuración de resources.
FAQ: Alojar Pangolin por tu cuenta
Los contenedores de Pangolin, Gerbil y Traefik juntos consumen solo unos cientos de MB de RAM en reposo. Un VPS con 4 GB de RAM cubre el stack sin problema y tiene margen para varios túneles activos. Si planeas correr servicios adicionales en el mismo VPS — un stack de monitoreo, una wiki o una base de datos — sube a 8 GB o más para que los servicios no compitan bajo carga.
Con la configuración estándar, no. Traefik usa el HTTP-01 challenge de Let’s Encrypt para aprovisionar certificados, lo que requiere un dominio con un registro A válido apuntando al VPS. Un dominio cuesta solo unos euros al año y vale la pena para cualquier setup de acceso remoto permanente. Pangolin Cloud es una alternativa si quieres el plano de control gestionado sin correr un VPS.
Newt es el conector de sitios de Pangolin: un cliente WireGuard en espacio de usuario que corre en tu red privada y establece una conexión cifrada saliente hacia el servidor de Pangolin. Como Newt inicia la conexión de forma saliente, tu router no necesita abrir ningún puerto, ni siquiera el UDP 51820 por defecto de WireGuard. Newt también actúa como proxy TCP/UDP, reenviando el tráfico del reverse proxy de Pangolin a servicios en cualquier parte de tu red local.
Desde el directorio /opt/pangolin, ejecuta docker compose pull && docker compose up -d. Haz siempre un backup del directorio config/ primero. Contiene la base de datos SQLite y los certificados TLS, y no hay un camino sencillo de reversión una vez que las migraciones ya corrieron. Para Newt en tu servidor casero, aplica el mismo proceso. Desde Pangolin 1.19 hay actualizaciones automáticas opcionales de Newt: actívalas en el dashboard a nivel de organización o por sitio para mantener los dispositivos edge actualizados sin intervención manual.