--- title: "Ajustes" description: "Conecta un dominio propio con SSL a tu zona CDN, protege el contenido con URLs firmadas (Token Auth) y configura CORS para peticiones cross-origin." category: "Despliegue" language: es source: https://cubepath.com/es/docs/products/despliegue/cdn-settings-es updated: 2026-08-04 --- # Ajustes Abre la zona CDN → pestaña **Settings** en [my.cubepath.com](https://my.cubepath.com). ## Dominio personalizado Cada zona recibe un dominio generado por el sistema (`.cubecdn.io`) que funciona de inmediato. Para servir el tráfico bajo tu propio hostname: ```steps ### Apunta un CNAME a la zona En tu DNS, crea un CNAME desde tu hostname (p. ej. `cdn.example.com`) al dominio de sistema de la zona. ### Define el dominio personalizado Introduce el hostname en **Custom Domain** y guarda. ### Espera al SSL El certificado se solicita automáticamente en cuanto el CNAME resuelve. ``` > Nota: Haz el CNAME **primero**. Si el registro no está vivo cuando se pide el certificado, la emisión falla — usa **Re-request SSL** cuando el DNS haya propagado. ### SSL **SSL Status** muestra *Valid*, *Pending*, *Error* o *Not configured*. Hay dos tipos: - **Automatic (Let's Encrypt)** — gratuito, aprovisionado y renovado por nosotros. La opción correcta salvo que tengas un motivo concreto para no usarla. - **Custom Certificate** — elige uno de los tuyos en [Certificados SSL](/docs/products/ajustes/certificados-ssl), o sube uno nuevo. Disponible en planes superiores, y necesario para certificados EV o para uno que deba coincidir con el que usas en otro sitio. ## URLs firmadas (Token Auth) Token Auth sirve el contenido de la zona **solo a quien tú autorices**. Cada enlace que publicas lleva una firma criptográfica y una caducidad; quien pida sin una URL firmada válida recibe **403 Forbidden**. Es el patrón estándar para vídeo de pago, descargas restringidas, galerías privadas, enlaces temporales y para mantener el contenido fuera de los buscadores y lejos del hotlinking. ### Cómo funciona Al activar Token Auth, CubePath genera un **secreto compartido** para la zona. Tu backend calcula un HMAC-SHA256 sobre la ruta más una marca de caducidad más el secreto, lo codifica en base64url y añade `?token=...&expires=...` a la URL. El edge recalcula el mismo HMAC con su copia del secreto y compara: si coincide, sirve; si no, 403. El secreto nunca viaja en la URL. ### Activarlo Abre la tarjeta **Signed URLs (Token Auth)** y activa **Enable Token Auth**. El secreto se genera y **se muestra una sola vez**. > Aviso: Copia el secreto de inmediato a un gestor de secretos o una variable de entorno. Lo guardamos cifrado para que el edge pueda validar firmas, pero no volvemos a mostrarlo. Si lo pierdes, tu única opción es rotarlo — lo que invalida todas las URLs ya en circulación. ### Firmar URLs en tu backend La operación es `HMAC-SHA256(secreto, ruta + str(expires))`, codificado en base64url sin relleno. ```python import hmac, hashlib, base64, time SECRET = "" def sign(path: str, ttl_seconds: int = 3600) -> str: expires = int(time.time()) + ttl_seconds msg = f"{path}{expires}".encode() mac = hmac.new(SECRET.encode(), msg, hashlib.sha256).digest() token = base64.urlsafe_b64encode(mac).rstrip(b"=").decode() return f"https://tu-zona.cubecdn.io{path}?token={token}&expires={expires}" ``` ```javascript const crypto = require('crypto'); const SECRET = process.env.CDN_SECRET; function sign(path, ttlSeconds = 3600) { const expires = Math.floor(Date.now() / 1000) + ttlSeconds; const mac = crypto.createHmac('sha256', SECRET).update(`${path}${expires}`).digest(); const token = mac.toString('base64url').replace(/=+$/, ''); return `https://tu-zona.cubecdn.io${path}?token=${token}&expires=${expires}`; } ``` ```php function sign($path, $ttlSeconds = 3600) { $secret = getenv('CDN_SECRET'); $expires = time() + $ttlSeconds; $mac = hash_hmac('sha256', $path . $expires, $secret, true); $token = rtrim(strtr(base64_encode($mac), '+/', '-_'), '='); return "https://tu-zona.cubecdn.io{$path}?token={$token}&expires={$expires}"; } ``` La tarjeta de Settings incluye además un subformulario **Generate signed URL**: pegas una ruta, defines una ventana de validez y obtienes una URL lista para usar. Es para pruebas y envíos puntuales — el tráfico de producción debe firmarse en tu backend, sin una llamada a la API por URL. ### Elegir la caducidad | Validez | Caso de uso | Compromiso | |---------|-------------|------------| | **5 minutos** | Descargas puntuales, respuestas de API protegidas | Refrescar pasada la ventana obliga a volver a firmar | | **1 hora** | Sesiones de reproducción de vídeo | Los vídeos largos la superan; el reproductor debe refirmar | | **24 horas** | Rotación diaria de contenido | Una URL filtrada sirve durante un día | | **7 días** | Medios estáticos cacheables, bundles de app | Exposición larga si se filtra; considera el IP binding | La validez está limitada a **7 días (604800 s)** para acotar el daño de una filtración. ### Vincular tokens a la IP del cliente El conmutador **Bind tokens to client IP** incorpora la IP de origen a la firma, de modo que **una URL filtrada solo funciona desde la IP a la que se emitió**. Es una defensa fuerte frente a enlaces compartidos en chats y foros. El coste es real: los clientes cuya IP cambia a mitad de sesión — redes móviles con CGNAT, WiFi de hotel, VPNs, saltos entre 4G y WiFi de casa — pierden el acceso en mitad de la reproducción. > Importante: Para streaming de vídeo de consumo esto suele ser un mal negocio. Una caducidad corta consigue casi el mismo beneficio sin romperle la experiencia a los usuarios móviles. Si lo activas, pasa la IP **pública** del cliente al firmar (normalmente la primera entrada de `X-Forwarded-For` si estás detrás de un proxy). Las IPv6 deben ir en forma canónica comprimida (`2001:db8::1`, no `[2001:db8::1]`). ### Rotar el secreto ```steps ### Rota Pulsa **Rotate secret** y confirma. ### Copia el secreto nuevo Se aplica la misma regla de mostrar una sola vez. ### Actualiza tu backend Sustituye `CDN_SECRET` y redespliega para que la aplicación lo recoja. ``` La rotación es inmediata y retroactiva: todas las URLs firmadas con el secreto anterior empiezan a devolver 403 al instante, y el contenido que se esté reproduciendo en ese momento se corta. Planifica las rotaciones en una franja de poco tráfico, o mantén caducidades cortas para que la interrupción sea mínima. ### Qué no hace Token Auth - **No es un WAF.** No filtra bots, no limita la tasa, no bloquea por país — eso son las [reglas WAF](/docs/products/despliegue/cdn-waf-es). - **No es autenticación de usuarios.** Autoriza una URL contra un secreto compartido; quien tenga esa URL puede usarla, salvo que el IP binding esté activo. - **No cifra el contenido.** El transporte es HTTPS, pero los bytes son los mismos que hay en tu origen. ### Diagnóstico | Síntoma | Causa probable | |---------|----------------| | 403 en todas las URLs | Token Auth está activo pero las peticiones no llevan `?token=`, o el token se calculó con el secreto equivocado | | 403 en algunas URLs | La ruta firmada y la pedida no coinciden — barra final, mayúsculas o codificación de URL. Firma y pide exactamente la misma cadena | | 403 justo tras rotar | URLs firmadas con el secreto anterior. Vuelve a firmarlas | | Funciona en escritorio y falla en móvil | El IP binding está activo y el cliente cambió de red. Desactívalo o acorta la caducidad | | 403 aleatorios durante la reproducción | La URL caducó a mitad de stream. Alarga la caducidad, o haz que el reproductor pida una URL nueva antes de que expire | ## CORS **CORS (cross-origin fetch)** permite que JavaScript de otros dominios descargue contenido de esta zona. Lo necesitas para reproductores HLS/DASH, llamadas `fetch()` y cualquier XHR entre dominios — sin él el navegador bloquea la respuesta aunque el CDN la haya servido correctamente. Actívalo y define los **Allowed origins**: o bien `*` para cualquier origen, o una lista de orígenes completos, uno por línea o separados por comas. Cada uno debe incluir el esquema (`https://example.com`) y ninguna ruta. > Nota: Debes añadir al menos un origen permitido (o `*`) antes de poder activar el conmutador. Con CORS activo, las respuestas incluyen `Access-Control-Allow-Origin` y el edge responde por ti a las peticiones `OPTIONS` de preflight. > Consejo: Prefiere una lista explícita a `*` cuando el contenido no esté pensado para incrustarse en cualquier sitio. Con `*`, cualquier web de internet puede construir una página con tus recursos — a costa de tu ancho de banda.