Evitar links externos con Amazon S3

Amazon Web Services, PHP, Programación, S3 por fillito el 14-09-2008

Etiquetado como : , , ,

Si hemos elegido Amazon S3 como sistema de almacenamiento virtual , quizás nos interese tener almacenados archivos que se puedan descargar libremente por cualquier usuario, y que además puedan ser linkados desde cualquier sitio. Pero en la mayoría de los casos tendremos almacenados nuestros archivos y no nos gustará que nadie nos enlace directamente y tener que soportar los gastos de transferencia y almacenamiento por él.

Voy a explicar cómo, con un sencillo script en php conseguiremos que nuestros archivos de S3 estén totalmente protegidos y que sólo puedan ser accesibles desde nuestro dominio.

Lo primero de todo, es conocer dos características que Amazon nos prové con sus APIs:
- Los ACL (Access Control List) : que nos permite definir los permisos de lectura-escritura-ejecución de nuestros bucket y objetos.
- Las URLs Firmadas : que nos permite acceder temporalmente a nuestros archivos protegidos, a través de una url que incluye una firma y un tiempo de expiración de los permisos. Éstas URLs las podremos generar con nuestro script, y llevarán como parámetro nuestra firma generada en tiempo de ejecución, que lleva implicita el tiempo de caducidad de la url.

La primera medida es aplicar permisos exclusivo de lectura para nuestro usuario (usando los ACLs) a todos los archivos que queramos proteger, para que sea imprescindible una validación al acceder a ellos.
Para generar nuestro script , necesitaremos echar mano de la clase Crypt/HMAC para construir el hash en sha1 que Amazon S3 requiere.
Lo primero será crear nuestra función para  generar nuestra firma:

PHP:
  1. require_once 'Crypt/HMAC.php';
  2. function hex2b64($str) {
  3.    $raw = '';
  4.    for ($i=0; $i <strlen($str); $i+=2) {
  5.       $raw .= chr(hexdec(substr($str, $i, 2)));
  6.    }
  7.    return base64_encode($raw);
  8. }
  9. function makeSig($str) {
  10.    $secretKey="Llave secreta que nos proporciona Amazon para nuestra cuenta";
  11.    $hasher =& new Crypt_HMAC($secretKey, "sha1");
  12.    $signature = hex2b64($hasher->hash($str));
  13.    return($signature);
  14. }

Lo siguiente, será crearnos una función para construir nuestra URL firmada :

PHP:
  1. function getSignedURL($bucket, $key, $expires=120){
  2.    $accessKeyId="accessKeyId que nos proporciona Amazon con nuestra cuenta";
  3.    $expires = time() + $expires;
  4.    $resource = $bucket."/".urlencode($key);
  5.    $stringToSign = "GET\n\n\n$expires\n/$resource";
  6.    $signature = urlencode(makeSig($stringToSign));
  7.    $signedUrl="http://s3.amazonaws.com/$resource?AWSAccessKeyId=$accessKeyId&Expires=$expires&Signature=$signature";
  8.    return $signedUrl;
  9. }

Ésta función nos devolverá la url firmada, que estará disponible durante el tiempo (en segundos) que hayamos establecido en el parametro $expires (120seg por defecto)

Ahora ya sólamente nos falta un script que nos lance al contenido, pero que nos proteja de links externos a nuestro dominio.
Para ésto simplemente comprobaremos si existe el campo HTTP_REFERER en nuestra variable $_SERVER , que nos indicará que estamos accediendo a ésta url desde otra url de referencia , y que nuestro dominio (extraido desde $_SERVER['HTTP_HOST']) esté contenido en él.

PHP:
  1. function get_amazon_url($amazon_bucket,$amazon_object){
  2.    if(isset($_SERVER['HTTP_REFERER']) && strstr($_SERVER['HTTP_REFERER'],$_SERVER['HTTP_HOST']))   {
  3.       $url=getSignedURL($amazon_bucket,$amazon_object,60);
  4.       header('Location:'.$url);
  5.    }else{
  6.       echo 'Éste contenido ha sido enlazado ilegalmente';
  7.    }
  8. }

Al llamar a ésta función, seremos automáticamente redirigidos al contenido en amazon siempre que el link provenga desde nuestro mismo dominio. Por supuest, si quisieramos permitir el acceso desde una determinada lista de dominios, simplemente tendríamos que modificar un poco la condición if , para que compruebe que cada uno de los dominios están incluido en el HTTP_REFERER.

Espero que sea útil.
Un Saludo !!

Amazon lanza Elastic Block Store

Amazon Web Services por fillito el 21-08-2008

Etiquetado como : , ,

Amazon no deja de trabajar para seguir ofreciendo los mejores servicios web, y después de lanzar Elastic IPs, lanza ahora EBS (Elastic Block Store), un servicio complementario a EC2 (Elastic Computing Cloud) que nos permite mantener nuestros datos de forma persistente.

Dos de los inconvenientes más grandes del servicio de procesamiento EC2 eran que al arrancar una instancia de procesado, ésta no disponía de una IP (sino que accedíamos a ella a través de un nombre de domino), y que al apagarla, toda la información que no formara parte de la imagen que instanciamos se volatilizaba. Esto era un problema grande, ya que en caso de un fallo en el servicio y caida perderíamos toda la información de la instancia, y hacía EC2 un servicio totalmente inútil si lo que buscamos es montar por ejemplo un servidor de bases de datos.
Todo ésto queda solventado con EBS, que nos permite instanciar múltiples bloques de entre 1GB y 1TB de almacenamiento que pueden ser montados como un dispositivo en nuestro sistema operativo. Cada bloque instanciado se monta como una unidad RAW sin formato, por lo que serán perfectamente compatible con cualquier sistema operativo que estemos usando en nuestra instancia y formatearla con el sistema de gestión de ficheros que mejor nos venga.
Además Amazon asegura la replicación automática de los datos dentro de la "Zona de Disponibilidad" de nuestra instancia, lo que garantiza la preservación de nuestros datos en caso de fallo hardware en las máquinas.
Otra de las características que me ha sorprendido gratamente es que cada bloque de datos es autónomo e independiente de la instancia, lo que los hace accesible desde cualquiera de nuestras intancias (aunque sólo a una de ellas al mismo tiempo).

En cuanto a los costes, Amazon mantiene su política de varios criterios de tarificación según transferencia, accesos y datos almacenados. Aunque como dato orientativo el almacenamiento nos costará 0,10$/GB cada mes.

Una gran mejora para EC2 que lo hace aún más útil. Esperemos que Amazon siga con el ritmo de mejoras para sus servicios, que están revolucionando el desarrollo web y facilitando que pequeños proyectos puedan crecer y crear grandes aplicaciones con unos costes más que asequibles.

S3 Amazon - Articulo en Maestros del Web

Amazon Web Services, Programación, S3, Trabajos/Proyectos por fillito el 05-03-2008

Etiquetado como : ,

En el pasado evento sobre Facebook nos encontramos con Christian Van Der Henst, fundador de Maestros del Web, y nos comentó que querían publicar un artículo sobre el servicio S3 de Amazon y me ofrecieron escribirlo.
Me encantó la idea, ya  que es un servicio con el que  llevo meses trabajando y me ilusionaba mucho la idea de que un artículo mio fuese publicado  :D

Y vaya sitio... para el que no conozca Maestros del Web, es la comunidad de desarrolladores web de habla hispana más importante del mundo.

Aquí podeis leer el artículo sobre S3 de Amazon . Se aceptan críticas y todo tipo de comentarios.

Gracias desde aquí a Christian y a todo su equipo por la oportunidad.