Aws-cli: Admite la generación de URL firmadas para el acceso a S3

Creado en 2 nov. 2013  ·  40Comentarios  ·  Fuente: aws/aws-cli

feature-request

Comentario más útil

Impresionante: en 3 años, la herramienta CLI oficial no obtuvo soporte para la implementación de URL firmadas, aunque existe en boto y s3cmd

Todos 40 comentarios

Sí, creo que esta sería una gran característica. Estoy pensando que este sería un nuevo subcomando s3. He estado trabajando en algunos cambios internos en el código de comando s3 para facilitar la adición de subcomandos. He estado usando esto para comenzar a refactorizar el comando ls para solucionar varios de los problemas reportados con ls .

Todavía no está completamente hecho, pero esto es lo que tengo hasta ahora:
https://github.com/jamesls/aws-cli/compare/s3-ls-permissions#diff -b88a66f4bd148577a9390cb980d7eeb9R321

Sí, esto lo estaba buscando. Por favor, permita especificar la caducidad no solo por duración, sino también por una fecha y hora específica. Al requerir zona horaria UTC, formato ISO, segundos completos, la cadena que termina en "Z" me parece bien utilizable (por ejemplo, "2014-05-30T00: 00: 00Z").

En caso de que realmente necesite generar tmpurl desde la línea de comando, podría recomendar mi herramienta de línea de comando s3tmpgen

De todos modos, realmente invitaría esa funcionalidad en AWS CLI, que se convirtió en una herramienta valiosa para mi trabajo diario con AWS S3.

+1

+1

Estoy buscando usar S3 para alojar paquetes de código para implementar en Heroku y esta sería una característica increíble :)

https://blog.heroku.com/archives/2014/5/22/introducing_the_app_json_application_manifest

+1

+1 sería genial tener esto en AWS CLI

Solo una nota para cualquiera que termine aquí, puede hacerlo usted mismo de manera trivial al ingresar a la biblioteca boto : https://boto.readthedocs.org/en/latest/ref/s3.html#boto .s3.key.Key.generate_url

Gracias por la respuesta. Echaré un vistazo a esto, estoy de acuerdo en que sería una gran característica para agregar a la AWS CLI.

Gracias, @johnboxall. Boto es sin duda una opción, aunque para las personas que implementan el binario cli sin implementaciones nativas de Python (piense en los usuarios de Windows), seguir esa ruta es tanto trabajo como eliminar el SDK de PowerShell y hacer las cosas a través del SDK de .NET. Todavía me gustaría ver este nativo en la CLI. :sonrisa:

Solo para cualquiera que busque usar boto directamente por ahora hasta que esto se agregue a aws-cli, pensé que agregaría una instrucción de muestra rápida. He buscado esto un par de veces y preferiría tenerlo junto con este ticket y el comentario de @johnboxall . Esto puede ser extremadamente obvio para algunos, pero no para los desarrolladores que no son de Python.

En una caja que ya tiene Python instalado

$ python --version
Python 2.7.6
$ sudo pip install boto
$ python
>>> import boto
>>> s3 = boto.connect_s3()
>>> bucket = s3.get_bucket('your-bucket-name')
>>> key = bucket.get_key('the-prefix/the-name-of-the-object.mp4')
>>> key.generate_url(3600)
'https://your-bucket-name.s3.amazonaws.com/the-prefix/the-name-of-the-object.mp4?Signature=CgDfFa45DBXFiMfASxSTpiSuHKM%3D&Expires=1415913273&AWSAccessKeyId=ABCDEDKSY344ACVDG'

Sobre la base del ejemplo de

Texto

$ cat boto-get-signed-url.py
#!/usr/bin/python
import boto
import argparse

parser = argparse.ArgumentParser(description='Generate an S3 signed URL')
parser.add_argument('-b', '--bucket', help='bucket name')
parser.add_argument('-k', '--key', help='prefix/key')
parser.add_argument('-s', '--seconds', type=int, help='time in seconds until the URL will expire')
args = parser.parse_args()

s3 = boto.connect_s3()
bucket = s3.get_bucket(args.bucket)
key = bucket.get_key(args.key)
if bucket.get_key(args.key):
  print key.generate_url(args.seconds)
else:
  print 's3://' + args.bucket + '/' + args.key + ' does not exist'

Ejemplo de uso y ayuda

$ ./boto-get-signed-url.py -b superbucket -k "test" -s 60
https://superbucket.s3.amazonaws.com/test?Signature=n6cO8RH%2FbNwQhuZVNNazo3q04x0%3D&Expires=1416695021&AWSAccessKeyId=AKIEXAMPLEKEYNOTREAL

$ boto-get-signed-url.py --help
usage: boto-get-signed-url.py [-h] [-b BUCKET] [-k KEY] [-s SECONDS]

Generate an S3 signed URL

optional arguments:
  -h, --help            show this help message and exit
  -b BUCKET, --bucket BUCKET
                        bucket name
  -k KEY, --key KEY     prefix/key
  -s SECONDS, --seconds SECONDS
                        time in seconds until the URL will expire

Hola a todos
Después de otra verificación sobre el estado de este problema, realicé una actualización del paquete de Python ttr.aws.utils.s3 que proporciona la herramienta s3tmpgen . La actualización permite generar la URL no solo usando https, sino (con la opción -http ) también http.

Todavía estoy deseando reemplazar esto con la solución awscli.

: +1:

+1 para que la URL firmada con s3 sea parte de cli

: +1:

+1

Creo, entiendo, por qué lleva tanto tiempo: las cosas deben suceder en orden y lo bueno es que parece estar en la hoja de ruta.

Como la AWS CLI se basa en botocore , primero se resolverá allí. boto / botocore # 291 lo está pidiendo.

La solicitud de extracción boto / botocore # 504 ya se fusionó en la rama clients-only y la hoja de ruta (mencionada en README en https://github.com/boto/botocore) afirma, botocore está actualmente solo un paso antes de fusionar la rama clients-only en desarrollo (luego beta, GA y AWS CLI tiene una herramienta "nativa" para brindarnos funcionalidad).

@vlcinsky

Sí, una vez que la rama solo para clientes se fusione en botocore, podremos recoger la generación de URL firmadas en la CLI. Luego, la principal cantidad de trabajo que tendría que hacerse en el lado de la CLI es crear una buena API que exponga la función.

: +1: sería una característica útil

+1

Como señaló @kyleknap , una de las cosas por hacer es diseñar una buena API para esta función.

Veo los siguientes casos de uso:

  • "tmpGET": crea tmpurl para la solicitud GET
  • "tmpPOST": crea tmpurl para la solicitud POST
  • "tmp ???": ¿hay algún otro método de soporte? No tengo conocimiento (y nunca he usado otra cosa que no sea
    OBTENER y PUBLICAR)

El "tmpGET" es realmente fácil ya que la única salida es la URL y la única entrada es el depósito / clave y el vencimiento.
fecha (hora de vencimiento).

El "tmpPOST" es mucho más complejo ya que uno tiene que definir una política para publicar.

Una pregunta a resolver es, dónde colocar estas acciones, parece haber dos alternativas:

  • aws s3
  • aws s3api

Hoy no me ocuparé del "tmpPOST" más complejo y me centraré en "tmpGET" más simple

Solución rápida: agregue aws s3 tmpurl

Una solución de este tipo sería bastante fácil de implementar, ayudaría en el 80% de los
situaciones de uso (publique un objeto en AWS S3 y proporcione una URL temporal para compartir
con alguien).

El concepto se basaría en aws s3 ls con las siguientes diferencias:

  • agregue una opción --expires para definir la fecha y hora en la que vence la URL o --expires-in para
    especificar el número de segundos hasta el vencimiento
  • generaría solo tmpurls, una línea por objeto listado

Me temo que actualmente no existe una manera fácil de crear una URL tmp para el momento exacto, por lo que inicial
La versión ofrecería solo la opción --expires-in con un valor predeterminado de 3600 segundos.

Pros y contras

Pros

Es muy fácil crear un montón de URL tmp para una cantidad de objetos existentes en AWS S3. Salva el
obstáculo para obtener valores exactos de nombre de cubo / clave.

Contras

La desventaja de este enfoque basado en aws s3 ls es que no se puede crear una URL tmp para un objeto, que
aún no existe.

De todos modos, esto podría resolverse más adelante con la solución aws s3api .

Muy bien puesto allí. Mientras que una publicación es algo que casi con certeza se construiría alrededor del manejo del lado del servidor de los datos publicados, los casos de uso del método get suelen ser mucho más fáciles. Cuando dices que cubriría la mayoría de los casos de uso, estoy totalmente de acuerdo.

Sin embargo, quise agregar, no creo que la URL temporal deba tener nada que ver con la ubicación de los archivos en s3. Si alguien quiere generar conjuntos completos de URL firmadas, esa es la lógica que la cli no necesita hacer más para ajustar. La primitiva tmpurl es el producto mínimo viable en mi mente.

Implementé (no completamente) una URL predefinida para objetos s3 en mi sucursal local.

https://github.com/quiver/aws-cli/tree/s3-presigned-url

Esta es una envoltura delgada por botocore.generate_presigned_url , y aún no está lista para producción. Como señaló @vlcinsky , necesitamos un buen diseño de API como AWSCLI . Una vez que esté arreglado, puedo implementarlo.

Una cosa que noto es que generate_presigned_url requiere el parámetro client_method , que especifica la API de S3 (por ejemplo, get_object ) para firmar. En mi implementación actual, está expuesto al usuario, pero sería mejor que fuera fácil de usar, como proporcionar diferentes subcomandos ( aws s3 geturl , aws s3 uploadurl ) o cambiar opciones ( --type upload )

Uso

subir objetos a S3

$ echo hello world > test.txt

$ aws s3 url s3://BUCKET/test.txt --client-method put_object --expires-in 180
https://BUCKET.s3.amazonaws.com/test.txt?AWSAccessKeyId=AKIAIXXXXXXXXXXXXXXX&Expires=1451449621&Signature=KgwO9lBx942fFvln0JW0NX7mKS0%3D

$ URL=`aws s3 url s3://BUCKET/test.txt --client-method put_object --expires-in 180`

$ curl -D - -X PUT --upload-file test.txt $URL
HTTP/1.1 100 Continue

HTTP/1.1 200 OK
x-amz-id-2: /90B1axPysBg3P8kv8BlR8RoqdO1JfajCN5BM5/TxIT3VjGphKmyGX8EgCQEtCXYhuNkVne5+GM=
x-amz-request-id: 685F03CA6C84FAC0
Date: Wed, 30 Dec 2015 05:18:38 GMT
ETag: "6f5902ac237024bdd0c176cb93063dc4"
Content-Length: 0
Server: AmazonS3

$ aws s3 cp s3://BUCKET/test.txt -
hello world

obtener objetos de S3

$ URL=`aws s3 url s3://BUCKET/test.txt --client-method get_object --expires-in 180`

$ curl -D - -X GET $URL
HTTP/1.1 200 OK
x-amz-id-2: WuRokcBm9wnDMaRkD8kNeGijuKEzVp3eagi7JbpPXmmchEljsiP4wZX5w1TaeuK94n2526FGKMI=
x-amz-request-id: 1EBCAA7A691A577D
Date: Wed, 30 Dec 2015 05:20:14 GMT
Last-Modified: Wed, 30 Dec 2015 05:19:15 GMT
ETag: "6f5902ac237024bdd0c176cb93063dc4"
Accept-Ranges: bytes
Content-Type: binary/octet-stream
Content-Length: 12
Server: AmazonS3

hello world

El pitón anterior genera una URL como: 'https: //.s3.amazonaws.com / dir / dir / archivo

Cuando intento curvar el archivo, aparece un problema con el certificado SSL: Cadena de certificado no válida
Si me rizo con la opción -k, puedo superar esto, pero también sé que si la URL se ve así: ' https: // s3-.amazonaws.com // dir / dir / archivo '
el certificado es válido, ¿hay alguna forma de cambiar la URL o alguna otra solución?
Gracias,
Garry

por ejemplo: ' https://s3-us-west-1.amazonaws.com/bucket/dir/dir/file '

Actualización, el uso de boto3 fue capaz de generar la URL correctamente firmada.

+1

Impresionante: en 3 años, la herramienta CLI oficial no obtuvo soporte para la implementación de URL firmadas, aunque existe en boto y s3cmd

1+

+1

+1

¿Algún avance en esto? Sorprendido, esto aún no está disponible.

+1

Escribí uno como solución alternativa y funciona como se esperaba: https://github.com/gdbtek/aws-tools

Hola a todos, gracias por los comentarios. Este algo que está en nuestra cartera de pedidos. Todavía no tengo las fechas exactas, pero vincularé este problema una vez que tengamos una solicitud de extracción.

¡Excelente! ¡Gracias!

¿Es posible obtener una URL pre-firmada para una carpeta s3 completa? ¿Incluye una interfaz web para navegar por la carpeta?

@tommeda No es posible. La URL pre-firmada siempre está relacionada con un único objeto almacenado. De lo que habla es similar al sitio web estático, pero para controlar el acceso a él (si se basa en AWS S3), es necesario escribir algún proxy. Ya existen pocos intentos, ninguno me pareció fácil (investigado hace aproximadamente un año).

Siempre puede generar una página web que proporcione una interfaz e incluya URL previamente firmadas para cada objeto, y luego ponga la interfaz en s3 y devuelva una URL previamente firmada a la interfaz. No es exactamente fácil, y la interfaz le gustaría ser específica para el uso

¿Fue útil esta página
0 / 5 - 0 calificaciones