Hoy he tenido problemas con el script PEARL para la API de S3 que se puede bajar en http://aws.amazon.com/code/128 . Este script permite operar con CURL con la API de S3.
En mi caso necesitaba que una instancia en EC2 obtuviera unos contenidos de S3 justo al arrancarse. Pero esos contenidos són privados por lo que necesitaba una línea de comando que me permitiera enviar las credenciales de la cuenta. Para ello Amazon tiene colgado en su documentación el script s3curl.py.
Para instalarlo simplemente tienes que dar permisos de ejecución al archivo .pl y crear un archivo llamado .s3curl
en la home con el Account Key Id y la Account Secret Key de la cuenta de AWS. El archivo de credenciales queda una cosa así:
%awsSecretAccessKeys = ( # personal account vancast => { id => '***************', key => '****************************************', }, );
Pero al hacer pruebas en mi pc intentando obtener un objecto con el comando:
$ ./s3curl.pl --id vancast -- https://s3-eu-west-1.amazonaws.com/[bucket]/[object]
Siempre obtenía el mismo error:
AccessDenied
AWS authentication requires a valid Date or x-amz-date header
0AD76C7526A30A04
rGTAEMil7zGbMAS2SZeUqLmZNGjbyxNb2ijBJmqOlHoq9Hla7XhJVQMYXlRJ0N1G
Ni en el README, ni en la documentación de S3 y en ningún foro o blog encontraba el motivo del error. La única pista que tenía es que AWS se quejaba de que estaba enviando una fecha enquivocada a la hora de autentificarme.
Entonces ejecutanto en modo debug
:
$ ./s3curl.pl --debug --id vancast -- https://s3-eu-west-1.amazonaws.com/[bucket]/[object]
En la respuesta me llama la atención que la la zona horaria que se enviaba era GMT +0, pero la hora coincidia con la de mi pc, que ahora mismo es GMT +1.
s3curl: StringToSign='GETnnndj, 03 nov 2011 16:16:48 +0000n/bucket/object'
S3 necesita la fecha de solicitud para crear un fecha de expiración, pero la hora que estaba enviando no era coherente.
Para solucionarlo cambié la línea dónde se obtine la fecha. Substituí el método POSIX strftime
por el método time2str
del paquete HTTP:Date.
use HTTP::Date; ... #my $httpDate = POSIX::strftime("%a, %d %b %Y %H:%M:%S +0000", gmtime ); my $httpDate = time2str();
Con el cambio ya conseguía ejecutar los comandos del script y acceder a los buckets de la cuenta AWS.