Aws-cli: Suporte à geração de URLs assinados para acesso S3

Criado em 2 nov. 2013  ·  40Comentários  ·  Fonte: aws/aws-cli

feature-request

Comentários muito úteis

Impressionante - em 3 anos a ferramenta CLI oficial não obteve suporte para url assinada implementada, embora exista em boto e s3cmd

Todos 40 comentários

Sim, acho que seria um ótimo recurso. Estou pensando que este seria um novo subcomando s3? Tenho trabalhado em algumas mudanças internas no código do comando s3 para facilitar a adição de subcomandos. Estou usando isso para começar a refatorar o comando ls para corrigir vários dos problemas relatados com ls .

Ainda não foi totalmente concluído, mas aqui está o que fiz até agora:
https://github.com/jamesls/aws-cli/compare/s3-ls-permissions#diff -b88a66f4bd148577a9390cb980d7eeb9R321

Sim, isso eu estava procurando. Por favor, permita especificar a expiração não apenas por duração, mas também por uma data e hora específica. Exigindo fuso horário UTC, formato ISO, segundos completos, a string que termina com "Z" parece-me bem utilizável (por exemplo, "2014-05-30T00: 00: 00Z").

No caso de você realmente precisar gerar tmpurl a partir da linha de comando, eu poderia recomendar minha ferramenta de linha de comando s3tmpgen

De qualquer forma, eu realmente convidaria essa funcionalidade no AWS CLI, que se tornou uma ferramenta valiosa para meu trabalho diário com AWS S3.

+1

+1

Estou tentando usar o S3 para hospedar pacotes de código a serem implantados no Heroku e este seria um recurso incrível :)

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

+1

+1 seria ótimo ter isso no AWS CLI

Apenas uma observação para quem acabar aqui: você pode fazer isso sozinho trivialmente acessando a biblioteca boto : https://boto.readthedocs.org/en/latest/ref/s3.html#boto .s3.key.Key.generate_url

Obrigado pelo feedback. Vou dar uma olhada nisso, concordo que seria um ótimo recurso para adicionar ao AWS CLI.

Obrigado, @johnboxall. Boto é certamente uma opção, embora para pessoas que implantam o binário cli sem implantações nativas do Python (pense em usuários do Windows), seguir esse caminho é tão trabalhoso quanto puxar para baixo o SDK do PowerShell e fazer as coisas por meio do SDK do .NET. Ainda gostaria de ver este nativo na CLI. :sorriso:

Apenas para quem deseja usar o boto diretamente por enquanto, até que ele seja adicionado ao aws-cli, pensei em adicionar um exemplo de instrução rápida. Eu já procurei por isso algumas vezes e preferia tê-lo junto com este tíquete e o comentário de @johnboxall . Isso pode ser extremamente óbvio para alguns, mas não para desenvolvedores não-python

Em uma caixa que já tem o 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'

Com base no exemplo de @ isleshocky77 ... adicionando argumentos e verificação de erros menores:

Roteiro

$ 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'

Exemplo de uso e ajuda

$ ./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

Olá a todos
Após outra verificação sobre o status desse problema, fiz uma atualização para o pacote Python ttr.aws.utils.s3 fornecendo a ferramenta s3tmpgen . A atualização permite gerar a url não apenas usando https, mas (com a opção -http ) também http.

Ainda estou ansioso para substituir isso pela solução awscli.

: +1:

+1 para s3 assinado url para fazer parte de cli

: +1:

+1

Eu acho, eu entendo, por que leva tanto tempo: as coisas devem acontecer em ordem e o bom é que parece que está no roteiro.

Como o AWS CLI é baseado em botocore , ele deve ser resolvido lá primeiro. boto / botocore # 291 está pedindo por isso.

Pull request boto / botocore # 504 já foi mesclado no branch clients-only e o roadmap (mencionado no README em https://github.com/boto/botocore) afirma, o botocore está atualmente apenas uma etapa antes de fundir o branch clients-only em desenvolvimento (então beta, GA e AWS CLI tem uma ferramenta "nativa" para fornecer funcionalidade para nós).

@vlcinsky

Sim, uma vez que o branch somente para clientes for mesclado com o botocore, poderemos pegar a geração de urls assinadas na CLI. Então, a principal quantidade de trabalho que teria que ser feito no lado da CLI é criar uma boa API que expõe o recurso.

: +1: seria um recurso útil, de fato

+1

Como @kyleknap observou, uma das coisas a fazer é projetar uma boa API para esse recurso.

Vejo os seguintes casos de uso:

  • "tmpGET": cria tmpurl para solicitação GET
  • "tmpPOST": cria tmpurl para solicitação POST
  • "tmp ???": existe mais algum método de suporte? Eu não estou ciente de (e nunca usei outro que não
    GET e POST)

O "tmpGET" é realmente fácil, pois a única saída é url e a única entrada é intervalo / chave e expiração
data (tempo de expiração).

O "tmpPOST" é muito mais complexo, pois é necessário definir uma política de postagem.

Uma questão a resolver é onde colocar essas ações, parece haver duas alternativas:

  • aws s3
  • aws s3api

Não vou lidar hoje com o "tmpPOST" mais complexo e vou me concentrar no "tmpGET" mais simples

Solução rápida: adicione aws s3 tmpurl

Tal solução seria bastante fácil de implementar, ajudaria em 80% do real
situações de uso (publicar um objeto para AWS S3 e fornecer url temporário para compartilhar
com alguém).

O conceito seria baseado em aws s3 ls com as seguintes diferenças:

  • adicione uma opção --expires para definir a data e hora em que o url expira ou --expires-in para
    especifique o número de segundos até a expiração
  • produziria apenas tmpurls, uma linha por objeto listado

Infelizmente, atualmente não há uma maneira fácil de criar um url tmp para o momento exato, então inicial
A versão ofereceria apenas a opção --expires-in com valor padrão de 3600 segundos.

Prós e contras

Prós

É muito fácil criar um monte de urls tmp para o número de objetos existentes no AWS S3. Salva o
obstáculo com a obtenção de valores de nome de intervalo / chave exatos.

Contras

A desvantagem desta abordagem baseada em aws s3 ls é que não se pode criar url tmp para um objeto, que
ainda não existe.

De qualquer forma, isso poderia ser resolvido mais tarde com a solução aws s3api .

Muito bem colocado lá. Considerando que uma postagem é algo que quase certamente seria construído em torno de alguma manipulação dos dados postados no lado do servidor, os casos de uso do método get são geralmente muito mais fáceis. Quando você diz que cobriria a maioria dos casos de uso, eu concordo totalmente.

Eu queria acrescentar, porém, não acho que o URL temporário deva ter algo a ver com a localização dos arquivos no s3. Se alguém deseja gerar conjuntos inteiros de URLs assinados, essa é a lógica que cli não precisa fazer mais para agrupar. O primitivo tmpurl é o produto mínimo viável em minha mente.

Implementei (não totalmente) o URL predefinido para objetos s3 em meu branch local.

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

Este é um wrapper fino para botocore.generate_presigned_url , e ainda não está pronto para produção. Como @vlcinsky observou, precisamos de um bom design de API como AWSCLI . Uma vez que isso seja corrigido, posso implementar isso.

Uma coisa que observo é que generate_presigned_url requer o parâmetro client_method , que especifica a API S3 (por exemplo, get_object ) para assinar. Na minha implementação atual, ele é exposto ao usuário, mas seria melhor ser amigável, como fornecer diferentes subcomandos ( aws s3 geturl , aws s3 uploadurl ) ou opções de troca ( --type upload )

Uso

fazer upload de objetos para 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

obter 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

O python acima gera um url como: 'https: //.s3.amazonaws.com / dir / dir / arquivo

Quando tento curvar o arquivo, obtenho um problema com o certificado SSL: Cadeia de certificados inválida
Se eu enrolar com a opção -k, posso passar por isso, mas também sei que se o url for semelhante a: ' https: // s3-.amazonaws.com // dir / dir / arquivo '
o cert é válido, existe uma maneira de alterar o url ou alguma outra correção?
Obrigado,
Garry

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

Update, usando boto3 foi capaz de gerar o url assinado corretamente.

+1

Impressionante - em 3 anos a ferramenta CLI oficial não obteve suporte para url assinada implementada, embora exista em boto e s3cmd

1+

+1

+1

alguma atualização disso? Surpreendido que ainda não esteja disponível.

+1

Eu escrevi um como uma solução alternativa e funciona conforme o esperado: https://github.com/gdbtek/aws-tools

Olá a todos, obrigado pelo feedback. Isso é algo que está em nossa carteira. Ainda não tenho as datas exatas, mas farei um link para esse problema assim que tivermos uma solicitação de pull.

Excelente! Obrigado!

É possível obter um url predefinido para uma pasta s3 inteira? Incluindo uma interface da web para navegar pela pasta?

@tommeda Não é possível. o url pré-assinado está sempre relacionado a um único objeto armazenado. O que você fala é semelhante a um site estático, mas para controlar o acesso a ele (se baseado no AWS S3), é necessário escrever algum proxy. Já existem poucas tentativas, nenhuma me pareceu (pesquisada há cerca de um ano) fácil.

Você sempre pode gerar uma página da web que forneça uma interface e inclua urls pré-assinadas para cada objeto e, em seguida, coloque a interface em s3 e retorne uma url pré-assinada para a interface. Não é exatamente fácil e a interface deve ser específica para o uso

Esta página foi útil?
0 / 5 - 0 avaliações