Tutorial

Pangolin en VPS: exponer un servicio detrás de NAT sin puertos

Despliegue11 min de lectura11 pasos

Tienes un servicio corriendo en un NAS, una Raspberry Pi o una VM local, y quieres que sea accesible desde Internet — sin abrir un puerto en el router, sin IP fija, y sin entregar tu tráfico a un SaaS externo. Pangolin, junto con Gerbil, resuelve exactamente este problema: un relay WireGuard que operas tú mismo en un VPS, con HTTPS automático y una interfaz web para gestionar todo.

Contenido· El problema: exponer un servicio detrás de NAT1/11
  1. 01El problema: exponer un servicio detrás de NAT
  2. 02Lo que Pangolin aporta frente a las alternativas
  3. 03Arquitectura: VPS relay, Gerbil y Newt
  4. 04Requisitos previos
  5. 05Despliegue de Pangolin y Gerbil en el VPS
  6. 06Añadir un túnel con Newt en la máquina origen
  7. 07Exposición de un servicio: ejemplo Nextcloud detrás de NAT
  8. 08Seguridad: tokens, rotación y control de acceso
  9. 09Solución de problemas
  10. 10Pangolin vs Cloudflare Tunnel vs Tailscale/Headscale
  11. 11Ir más allá

El problema: exponer un servicio detrás de NAT

La mayoría de las conexiones residenciales y empresariales colocan tus máquinas detrás de un NAT: ningún puerto entrante es accesible desde el exterior sin configuración explícita en el router. E incluso cuando esa configuración es posible, abre un camino directo hacia tu red local.

Los escenarios reales son frecuentes: un NAS con Nextcloud que quieres compartir con clientes, un homelab en Proxmox con una docena de servicios, una Raspberry Pi para domótica, o una VM de desarrollo local que quieres probar desde fuera. En todos estos casos, la solución habitual — el port forwarding — tiene dos problemas: depende del router y abre un camino directo hacia tu red privada.

Las alternativas comunes tienen sus propias limitaciones: Cloudflare Tunnel pasa todo tu tráfico por los servidores de Cloudflare, lo que plantea dudas de privacidad y crea una dependencia de su infraestructura. Tailscale/Headscale crea una red mesh entre tus máquinas, excelente para acceso punto a punto, pero no está diseñado para exponer públicamente un servicio HTTP(S) con un subdominio dedicado. Pangolin ocupa un espacio diferente: un relay WireGuard self-hosted, con gestión de certificados y subdominios, que controlas completamente desde tu VPS.

Lo que Pangolin aporta frente a las alternativas

  • Completamente self-hosted — tu tráfico solo transita por tu VPS, ningún tercero ve tu tráfico de aplicación.
  • Sin puerto entrante necesario — la conexión se inicia desde la máquina origen hacia el VPS (saliente), el NAT nunca es un obstáculo.
  • HTTPS automático via Let's Encrypt — Pangolin gestiona certificados para cada subdominio expuesto, sin intervención manual.
  • Interfaz web integrada — añade túneles y gestiona recursos y usuarios desde un panel web, sin editar archivos de configuración.
  • Cifrado WireGuard de extremo a extremo — el túnel entre la máquina origen y el VPS está cifrado a nivel de transporte, independientemente del HTTPS de aplicación.
  • Multi-sitio — una única instancia de Pangolin en el VPS puede relayar decenas de servicios desde máquinas distintas, bajo subdominios independientes.

Arquitectura: VPS relay, Gerbil y Newt

Pangolin se apoya en tres componentes que se reparten los roles:

[Máquina origen]                   [VPS ServOrbit]               [Internet]
  service:8080                      Pangolin (orquestación)
  newt (cliente) ←─WireGuard UDP─→  Gerbil  (túnel WG)    ←─HTTPS──→  visitante
                                    Traefik (reverse proxy)

Pangolin es el plano de control: gestiona túneles, subdominios, certificados y usuarios a través de una API REST y una interfaz web. Corre en el VPS.

Gerbil es el par WireGuard del lado del servidor. Abre un puerto UDP, establece túneles con los clientes y enruta el tráfico entrante hacia los servicios expuestos. También corre en el VPS, junto a Pangolin.

Newt es el cliente ligero que corre en la máquina origen (NAS, Pi, VM local). Se conecta a Gerbil en el puerto UDP WireGuard, mantiene el túnel activo y reenvía el tráfico recibido al servicio local en el puerto configurado.

El flujo concreto: un visitante llega a nextcloud.yourdomain.com → Traefik (gestionado por Pangolin) recibe la petición HTTPS → la reenvía a través de Gerbil por el túnel WireGuard activo → Newt la recibe y la relayea hacia localhost:8080 en la máquina origen. El servicio responde por el mismo camino en sentido inverso.

Requisitos previos

En el lado del VPS:
- VPS con acceso root e IPv4 dedicada — el plan {{vps.start.name}} es suficiente para empezar (1 vCPU, 1 GB RAM para cargas ligeras, 2 GB recomendados para múltiples túneles activos).
- Ubuntu 22.04 o 24.04 (Debian 12 también funciona).
- Un puerto UDP libre para WireGuard (por defecto 51820, configurable).
- Un nombre de dominio con acceso a la gestión DNS — necesitarás crear un registro A wildcard *.yourdomain.com apuntando a la IP del VPS.
- Docker y Docker Compose instalados (apt install docker.io docker-compose-plugin).

En el lado de la máquina origen:
- Una máquina Linux (Raspberry Pi, NAS con DSM 7+, VM en Proxmox, servidor físico) con acceso UDP saliente al puerto WireGuard del VPS — la mayoría de ISPs lo permiten.
- Un servicio escuchando en un puerto local (Nextcloud, Gitea, Home Assistant, etc.).

Versión actual: Pangolin 1.23.0 (publicado el 16 de septiembre de 2026).

Despliegue de Pangolin y Gerbil en el VPS

  1. Preparar el VPS y abrir el puerto WireGuard

    Conéctate como root al VPS e instala Docker si no está presente:

    apt update && apt install -y docker.io docker-compose-plugin ufw

    Abre el puerto UDP para WireGuard (51820 por defecto) y asegura que los puertos HTTP/HTTPS son accesibles:

    ufw allow 80/tcp
    ufw allow 443/tcp
    ufw allow 51820/udp
    ufw enable

    Para restringir el acceso al panel de administración (puerto 3000 por defecto), limítalo a tu IP:

    ufw allow from TU_IP to any port 3000
  2. Crear el archivo docker-compose.yml

    Crea un directorio de trabajo y el archivo de configuración:

    mkdir -p /opt/pangolin && cd /opt/pangolin

    Crea docker-compose.yml con el siguiente contenido:

    cat > docker-compose.yml <<'EOF'
    services:
      pangolin:
        image: fosrl/pangolin:1.23.0
        container_name: pangolin
        restart: unless-stopped
        volumes:
          - ./config:/app/config
          - ./data:/app/data
        ports:
          - "3000:3000"
        networks:
          - pangolin_net
    
      gerbil:
        image: fosrl/gerbil:latest
        container_name: gerbil
        restart: unless-stopped
        cap_add:
          - NET_ADMIN
        volumes:
          - ./data:/var/lib/gerbil
        ports:
          - "51820:51820/udp"
        networks:
          - pangolin_net
        depends_on:
          - pangolin
    
    networks:
      pangolin_net:
        driver: bridge
    EOF

    Adapta el número de versión de la imagen pangolin al último release disponible en GitHub.

  3. Configurar Pangolin e iniciar el stack

    Crea el directorio de configuración y un config.yml mínimo:

    mkdir -p /opt/pangolin/config
    cat > /opt/pangolin/config/config.yml <<'EOF'
    app:
      base_domain: yourdomain.com
      admin_email: [email protected]
      port: 3000
    
    wireguard:
      port: 51820
      subnet: 10.0.0.0/24
    
    acme:
      enabled: true
      staging: false
    EOF

    Reemplaza yourdomain.com por tu dominio real. Inicia el stack:

    cd /opt/pangolin && docker compose up -d
    docker compose logs -f pangolin

    Pangolin genera una contraseña de administrador en el primer arranque — anótala desde los logs. La interfaz web está disponible en http://IP_VPS:3000.

  4. Configurar el registro DNS wildcard

    En tu zona DNS, crea un registro A wildcard apuntando a la IP del VPS:

    *.yourdomain.com  →  A  →  IP_VPS

    En Cloudflare, crea este registro con el proxy desactivado (DNS-only, nube gris) para que los certificados Let's Encrypt puedan emitirse correctamente mediante el desafío HTTP-01 que usa Pangolin.

  5. Crear una unidad systemd para reinicio automático

    Docker con restart: unless-stopped suele ser suficiente, pero si prefieres una unidad systemd dedicada:

    cat > /etc/systemd/system/pangolin.service <<'EOF'
    [Unit]
    Description=Pangolin reverse tunnel stack
    After=docker.service
    Requires=docker.service
    
    [Service]
    Type=oneshot
    RemainAfterExit=yes
    WorkingDirectory=/opt/pangolin
    ExecStart=/usr/bin/docker compose up -d
    ExecStop=/usr/bin/docker compose down
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    systemctl daemon-reload
    systemctl enable pangolin

Añadir un túnel con Newt en la máquina origen

  1. Crear un túnel en la interfaz Pangolin

    Inicia sesión en la interfaz web de Pangolin en http://IP_VPS:3000 con las credenciales de administrador. Ve a Sites → Add site, dale un nombre (p. ej. homelab) y anota el site token generado. Luego en Resources → Add resource, elige el sitio, escribe el subdominio deseado (nextcloud.yourdomain.com) y el puerto local de la máquina origen (p. ej. 8080).

  2. Instalar Newt en la máquina origen

    En la máquina que aloja tu servicio, descarga el binario Newt para tu arquitectura:

    # Linux x86_64
    curl -Lo /usr/local/bin/newt \
      https://github.com/fosrl/newt/releases/latest/download/newt-linux-amd64
    chmod +x /usr/local/bin/newt

    Para Raspberry Pi (ARM64):

    curl -Lo /usr/local/bin/newt \
      https://github.com/fosrl/newt/releases/latest/download/newt-linux-arm64
    chmod +x /usr/local/bin/newt
  3. Configurar e iniciar Newt

    Lanza Newt con el site token obtenido en el paso anterior:

    newt \
      --server https://yourdomain.com:3000 \
      --token TU_SITE_TOKEN \
      --target localhost:8080

    Para arranque automático, crea una unidad systemd:

    cat > /etc/systemd/system/newt.service <<'EOF'
    [Unit]
    Description=Newt WireGuard tunnel client
    After=network.target
    
    [Service]
    ExecStart=/usr/local/bin/newt \
      --server https://yourdomain.com:3000 \
      --token TU_SITE_TOKEN \
      --target localhost:8080
    Restart=always
    RestartSec=5
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    systemctl daemon-reload
    systemctl enable --now newt
  4. Verificar la conectividad de extremo a extremo

    En el VPS, verifica que el túnel WireGuard está establecido:

    docker exec gerbil wg show

    Deberías ver un peer con un latest handshake reciente. Desde cualquier navegador o línea de comandos:

    curl -I https://nextcloud.yourdomain.com

    Respuesta esperada: HTTP/2 200 (o la página de login de tu servicio). El certificado Let's Encrypt se emite automáticamente en el primer acceso.

Exposición de un servicio: ejemplo Nextcloud detrás de NAT

  1. Configurar Nextcloud para aceptar el dominio proxy

    Nextcloud bloquea peticiones de dominios no declarados. Añade el dominio público a config.php:

    # Desde la máquina origen, en el directorio de Nextcloud
    nano config/config.php

    Añade en el array trusted_domains:

    'trusted_domains' =>
      array (
        0 => 'localhost',
        1 => 'nextcloud.yourdomain.com',
      ),
    'overwritehost' => 'nextcloud.yourdomain.com',
    'overwriteprotocol' => 'https',
  2. Verificar el acceso público y el certificado

    Espera 30-60 segundos tras el primer acceso para que Let's Encrypt emita el certificado, luego:

    curl -v https://nextcloud.yourdomain.com 2>&1 | grep -E 'subject|issuer|HTTP'

    El certificado está firmado por Let's Encrypt y la URL pública es ahora accesible desde cualquier red, sin ningún puerto abierto en el lado de la red local.

Seguridad: tokens, rotación y control de acceso

Rotación de site token — genera un nuevo token desde la interfaz Pangolin y actualiza la unidad systemd de Newt en la máquina origen. El token anterior queda invalidado inmediatamente. Programa esta rotación cada 90 días o ante cualquier cambio de personal con acceso a la máquina origen.

Whitelist de IPs en Pangolin — para cada recurso expuesto, puedes definir una lista blanca de IPs en Resources → Access Policy. Útil para restringir el acceso al backoffice o herramientas internas a tu rango de IP de oficina.

Acceso autenticado — Pangolin soporta proveedores OIDC (Authentik, Keycloak, Zitadel) para añadir una capa de autenticación delante de cualquier recurso expuesto, sin modificar la aplicación detrás del túnel.

Restringir el puerto de administración — el puerto 3000 de Pangolin no debe ser accesible públicamente. Restríngelo a tu IP con ufw allow from TU_IP to any port 3000 && ufw deny 3000.

Solución de problemas

El túnel no se establece — UDP bloqueado por el ISP. Algunos operadores filtran UDP saliente en puertos no estándar. Prueba desde la máquina origen: nc -u -v IP_VPS 51820. Si la conexión es rechazada, cambia el puerto WireGuard en config.yml a 443 (UDP) o 53 (UDP) — estos puertos pasan casi universalmente. Actualiza ufw en el VPS en consecuencia.

MTU mismatch — latencia o desconexiones aleatorias. WireGuard añade overhead de encapsulación (aproximadamente 60 bytes). Si tu servicio transfiere archivos grandes y observas desconexiones, reduce el MTU de la interfaz WireGuard en la configuración de Gerbil: mtu = 1380 es un valor seguro en la mayoría de enlaces.

Servicio no accesible pese al túnel activo. Primero verifica que el servicio local escucha en 0.0.0.0 y no solo en 127.0.0.1: ss -tlnp | grep 8080. Luego confirma que el puerto configurado en Pangolin coincide con el puerto real del servicio. Finalmente revisa los logs de Newt: journalctl -u newt -f.

Certificado Let's Encrypt no emitido. Pangolin usa el desafío HTTP-01, que requiere que el puerto 80 del VPS sea accesible desde Internet. Verifica que ufw allow 80/tcp está activo y que ningún otro servicio ocupa el puerto 80 (ss -tlnp | grep :80). En Cloudflare, asegúrate de que el registro wildcard está en DNS-only (nube gris).

Interfaz Pangolin inaccesible tras reinicio. Si Docker se reinicia antes de que la red esté disponible, Pangolin puede arrancar sin interfaz de red. Añade network-online.target en la dependencia systemd, o simplemente ejecuta de nuevo docker compose up -d desde /opt/pangolin.

Pangolin vs Cloudflare Tunnel vs Tailscale/Headscale

Desplace la tabla

CriterioPangolin + GerbilCloudflare TunnelTailscale / Headscale
AlojamientoSelf-hosted en tu VPSSaaS de CloudflareSaaS (Tailscale) o self-hosted (Headscale)
CosteSolo el coste del VPSGratis hasta ciertos límites, luego suscripciónGratis (uso personal), suscripción para equipos
Cifrado E2EWireGuard entre máquina y VPS, HTTPS hasta el visitanteTLS hasta los servidores de Cloudflare (descifrado en tránsito)WireGuard entre todos los nodos (mesh completo)
Exposición HTTP públicaSí, con HTTPS automático y subdominios personalizadosSí, con certificados gestionados por CloudflareNo diseñado para ello (requiere un reverse proxy adicional)
Complejidad de administraciónMedia — un stack Docker a mantener, una interfaz webBaja — el connector es un único binario, todo gestionado por CloudflareBaja (Tailscale) a Media (Headscale self-hosted)
Privacidad del tráficoTráfico visible solo en tu VPSTráfico descifrado por Cloudflare en sus servidoresTráfico mesh cifrado, nunca centralizado

Ir más allá

Pangolin 1.23.0 introduce soporte de alta disponibilidad en la edición Enterprise y gestión multi-administrador del servidor — funcionalidades útiles en cuanto tu infraestructura crece más allá del uso personal.

Para exponer servicios no-HTTP (SSH privado, bases de datos, protocolos UDP de aplicación), Pangolin soporta ahora recursos privados TCP/UDP accesibles mediante el cliente Newt — sin exponerlos públicamente en una URL, pero haciéndolos accesibles desde tu red WireGuard.

Si tu necesidad es distinta — coordinar el acceso entre varias máquinas sin exposición pública — Headscale en VPS es la herramienta adecuada. Para exposición sin VPS intermedio usando la infraestructura de Cloudflare, Cloudflare Tunnel sigue siendo la opción más sencilla. Y para sentar las bases del cifrado de red en un VPS, la guía de WireGuard en VPS cubre la instalación y configuración de la interfaz WireGuard nativa.

Un VPS con acceso root e IPv4 dedicada

Pangolin y Gerbil necesitan un puerto UDP abierto y una IPv4 dedicada para escuchar las conexiones WireGuard entrantes. Los VPS ServOrbit ofrecen ambos, con elección de sistema operativo y acceso root completo.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva