Uso de URL firmadas para proteger el contenido de tu CDN
Las redes de entrega de contenido (CDN, por sus siglas en inglés) son esenciales para entregar contenido de forma eficiente en todo el mundo, pero pueden exponer tu contenido a accesos no autorizados si no cuentas con las medidas de seguridad adecuadas. Este DevTip explica cómo las URL firmadas pueden mejorar la seguridad de tu CDN al garantizar que solo los usuarios autorizados puedan obtener acceso a tus recursos. Una URL firmada es una credencial al portador: cualquiera que la reciba puede usarla hasta que expire. Tu aplicación debe autorizar al usuario antes de emitirla.
Entender la seguridad de las CDN y las URL firmadas
Las CDN aumentan la velocidad de entrega de contenido y mejoran la experiencia de usuario al almacenar en caché el contenido en ubicaciones de borde. Sin embargo, sin controles de acceso robustos, tu contenido puede quedar expuesto al uso indebido o a la piratería. Implementar URL firmadas añade una capa de autenticación basada en tokens que otorga acceso temporal y seguro a los recursos protegidos.
Beneficios de usar URL firmadas:
- Restringir el acceso a contenido premium o sensible
- Evitar el hotlinking no autorizado y reducir el robo de ancho de banda
- Admitir las restricciones de acceso que exigen tus acuerdos de licencia y tus políticas de seguridad
- Limitar la duración del acceso; revocar una URL ya emitida suele requerir cambiar sus claves de firma o la configuración de acceso de la distribución
- Mejorar la seguridad del contenido sin sacrificar el rendimiento
Comparación de proveedores de CDN para URL firmadas
Los distintos proveedores de CDN implementan la funcionalidad de URL firmadas con diferentes niveles de complejidad:
| Proveedor de CDN | Soporte de URL firmadas | Auth por token | Complejidad de implementación |
|---|---|---|---|
| AWS CloudFront | Sí | Sí | Media |
| Azure CDN | Sí | Sí | Media |
| Google Cloud CDN | Sí | Sí | Media |
| Fastly | Sí | Sí | Compleja |
| Cloudflare | Sí | Sí | Simple |
Requisitos previos para la implementación
Antes de implementar URL firmadas, asegúrate de haber completado lo siguiente:
- Acceso a la consola de administración de tu CDN con privilegios administrativos.
- Los permisos adecuados (por ejemplo, los roles de IAM necesarios en AWS CloudFront) para generar y gestionar pares de claves.
- Las credenciales de API necesarias o las configuraciones del SDK junto con los datos de tu par de claves.
- HTTPS habilitado en tu dominio con un certificado SSL/TLS válido.
- Un servidor de origen configurado para la integración con la CDN, incluidas las cabeceras cache-control adecuadas.
- Un reloj del sistema sincronizado para evitar problemas con la expiración de las URL.
Implementar URL firmadas con AWS CloudFront
Ejecuta este ejemplo en tu servidor con Node.js 22 o posterior e instala
@aws-sdk/cloudfront-signer. Guárdalo como signed-url.mjs. Acepta una expiración en
segundos, con un valor predeterminado de 3600 segundos (1 hora).
Antes de usar el firmador, configura el comportamiento de caché de CloudFront para que exija URL
firmadas mediante un grupo de claves de confianza, añade tu clave pública a ese grupo y protege el
origen del acceso directo. CLOUDFRONT_KEY_PAIR_ID es el ID de esa clave pública, no una clave
de acceso de IAM. Proporciona la clave privada PEM correspondiente mediante configuración de
secretos del lado del servidor; nunca la incluyas en el código del cliente.
Consulta la configuración de URL firmadas de AWS.
import { getSignedUrl } from '@aws-sdk/cloudfront-signer'
async function generateSignedUrl(
resourceUrl,
privateKeyString,
keyPairId,
expirationSeconds = 3600,
) {
try {
const signedUrl = getSignedUrl({
url: resourceUrl,
keyPairId: keyPairId,
privateKey: privateKeyString,
dateLessThan: new Date(Date.now() + expirationSeconds * 1000).toISOString(),
})
return signedUrl
} catch (error) {
console.error('Error generating signed URL:', error)
throw error
}
}
// Usage example
const resourceUrl = 'https://your-distribution.cloudfront.net/path/to/content'
try {
const signedUrl = await generateSignedUrl(
resourceUrl,
process.env.CLOUDFRONT_PRIVATE_KEY,
process.env.CLOUDFRONT_KEY_PAIR_ID,
)
console.log('Signed URL:', signedUrl)
} catch (error) {
console.error('Failed to generate URL:', error)
}
Los desarrolladores que usen otros proveedores de CDN (como Azure CDN, Google Cloud CDN, Fastly o Cloudflare) deben consultar la documentación respectiva para implementaciones similares de URL firmadas.
Mejores prácticas de seguridad
Refuerza la seguridad de tu CDN con estas medidas:
-
Gestión de claves:
- Rota las claves de firma con regularidad (idealmente cada 90 días o según lo que defina tu política de seguridad).
- Almacena las claves privadas de forma segura con un servicio dedicado de gestión de claves o un gestor de secretos.
- Implementa el versionado de claves para asegurar transiciones fluidas sin interrupción del servicio.
-
Controles de acceso:
- Configura tiempos de expiración estrictos según la sensibilidad de tu contenido.
- Aplica restricciones basadas en IP cuando sea viable para limitar el acceso a direcciones conocidas.
- Usa autenticación basada en tokens para un control de acceso granular.
-
Monitoreo y registro:
- Habilita registros detallados en los endpoints de tu CDN para rastrear los accesos y vigilar anomalías.
- Revisa los registros de acceso con regularidad para identificar actividad inusual y responder a ella.
- Configura alertas para patrones de tráfico sospechosos o posibles brechas de seguridad.
-
Aplicación de HTTPS:
- Exige acceso exclusivamente por HTTPS a los recursos de tu CDN.
- Usa versiones actuales de TLS (TLS 1.2 o superior) para conexiones seguras.
- Gestiona los certificados SSL/TLS con diligencia para prevenir vulnerabilidades.
Solución de problemas comunes
Implementar URL firmadas a veces puede presentar dificultades. Ten en cuenta estos consejos para solucionar problemas:
-
Errores de validación de firma:
- Asegúrate de que el reloj de tu servidor esté sincronizado.
- Confirma que el ID del par de claves y la clave privada coincidan correctamente.
- Verifica que la codificación de la URL siga el formato esperado.
-
Problemas relacionados con la caché:
- Establece las cabeceras cache-control adecuadas en tu servidor de origen.
- Revisa con cuidado la configuración de caché de tu CDN para asegurarte de que se alinee con tus políticas de contenido.
- Inspecciona las cabeceras de respuesta del servidor de origen para comprobar su coherencia.
-
Problemas de CORS:
- Configura las cabeceras CORS adecuadas en tu servidor.
- Especifica con claridad los orígenes permitidos en la configuración de tu CDN.
- Gestiona correctamente las solicitudes preflight para permitir un acceso seguro entre orígenes.
-
Códigos de error comunes:
- 403: indica una firma no válida o una URL expirada.
- 400: sugiere una URL mal formada o parámetros faltantes.
- 504: apunta a un tiempo de espera agotado en el origen, lo que puede requerir ajustes del lado del servidor.
Pruebas y validación
Las pruebas exhaustivas garantizan que tu implementación de URL firmadas funcione como esperas. Aquí tienes dos escenarios:
-
Funcionalidad básica:
const testSignedUrl = async () => { const url = await generateSignedUrl( resourceUrl, process.env.CLOUDFRONT_PRIVATE_KEY, process.env.CLOUDFRONT_KEY_PAIR_ID, ) const response = await fetch(url) if (!response.ok) { throw new Error(`Failed to access content: ${response.status}`) } return response } -
Pruebas de expiración:
const testExpiration = async () => { // Generate a URL that expires in 1 second const shortLivedUrl = await generateSignedUrl( resourceUrl, process.env.CLOUDFRONT_PRIVATE_KEY, process.env.CLOUDFRONT_KEY_PAIR_ID, 1, ) // Wait for 2 seconds to ensure expiration await new Promise((resolve) => setTimeout(resolve, 2000)) const response = await fetch(shortLivedUrl) if (response.status !== 403) { throw new Error('URL did not expire as expected') } }
Conclusión
Implementar URL firmadas es una estrategia potente para proteger el contenido de tu CDN, ya que restringe el acceso únicamente a los usuarios autorizados. Si sigues los pasos de implementación actualizados, aplicas las mejores prácticas de seguridad y pruebas tu configuración a fondo, puedes aumentar significativamente la seguridad de tu contenido sin renunciar a un rendimiento de entrega óptimo.
Mientras proteges el contenido de tu CDN, considera cómo Transloadit puede mejorar tu flujo de trabajo de procesamiento de archivos.
