Arquivos de proxy da AWS S3 usando nginx

Parece que a tarefa de implementar o frontend da AWS no nginx parece um caso típico do StackOverflow - afinal, não há problemas com o proxy de arquivos do S3? De fato, descobriu-se que uma solução pronta não é tão fácil de encontrar, e este artigo deve corrigir essa situação.



Por que você precisaria disso?


  1. Controle o acesso aos arquivos usando o nginx - relevante para o conceito de IaC (infraestrutura como código). Todas as alterações relacionadas ao acesso serão feitas apenas nas configurações que estão no projeto.
  2. Se você fornecer arquivos através do seu nginx, poderá armazená-los em cache e salvar os pedidos no S3.
  3. Esse proxy ajudará a ignorar o tipo de armazenamento de arquivo para diferentes instalações de aplicativos (afinal, existem outras soluções além do S3).

Formulamos a estrutura


  • O bucket de origem deve ser privado - você não pode permitir que usuários anônimos baixem arquivos diretamente do S3. Se, no seu caso, essa restrição não funcionar, use proxy_pass e você não poderá mais ler.
  • O ajuste pela AWS deve ser único, “ajustado e esquecido”, para simplificar a operação.

Estamos à procura de uma solução na testa


Se o seu bucket original for público, nenhuma dificuldade o ameaçará, solicitações de proxy para o S3 e tudo funcionará. Se for privado, você precisará se autenticar no S3 de alguma forma. O que os colegas da Internet nos oferecem:

  1. Existem exemplos de implementação do protocolo de autenticação usando o nginx. A solução é boa, mas infelizmente foi projetada para um protocolo de autenticação desatualizado ( Signature v2 ), que não funciona em alguns data centers da Amazon . Se você tentar usar esta solução, por exemplo, em Frankfurt, receberá o erro "O mecanismo de autorização que você forneceu não é suportado. Por favor, use AWS4-HMAC-SHA256 . " Uma versão mais recente do protocolo ( Signature v4 ) é muito mais difícil de implementar, mas não há soluções prontas para o nginx com ele.
  2. Há um módulo de terceiros para o nginx - ngx_aws_auth . A julgar pela fonte, ele suporta a assinatura v4. No entanto, o projeto parece abandonado: por mais de um ano não houve alterações na base de código e também há um problema de compatibilidade com outros módulos aos quais o desenvolvedor não responde. Além disso, adicionar módulos adicionais ao nginx geralmente é um passo doloroso.
  3. Você pode usar um proxy s3 separado, dos quais muitos foram escritos. Pessoalmente, gostei da solução Go - aws-s3-proxy : ela tem uma imagem pronta e bastante popular no DockerHub. Mas, neste caso, o aplicativo adquirirá outro componente com seus possíveis problemas.

Aplicar política de bucket da AWS


A AWS, via de regra, assusta os novos usuários com sua complexidade e volume de documentação. Mas se você olhar, entende que ele foi projetado de maneira muito lógica e flexível. A Amazon também encontrou uma solução para a nossa tarefa - a política de balde S3 . Esse mecanismo permite criar regras de autorização flexíveis para o bucket com base em diferentes parâmetros do cliente ou solicitação.


Interface do gerador de políticas - AWS Policy Generator

Aqui estão algumas opções interessantes às quais você pode se associar:

  • IP ( aws:SourceIp ),
  • Cabeçalho do referenciador ( aws:Referer ),
  • Cabeçalho do agente do usuário ( aws:UserAgent ),
  • o restante está descrito na documentação .

A ligação de IP é uma boa opção apenas se o aplicativo tiver um determinado local de residência e, em nosso tempo, é raro. Portanto, você precisa se apegar a outra coisa. Como solução, proponho gerar um User-Agent ou Referer secreto e fornecer arquivos apenas para os usuários que conhecem o cabeçalho secreto. Veja como é uma política semelhante:

 { "Version": "2012-10-17", "Id": "http custom auth secret", "Statement": [ { "Sid": "Allow requests with my secret.", "Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-bucket-for-habr/*", "Condition": { "StringLike": { "aws:UserAgent": [ "xxxyyyzzz" ] } } } ] } 

Uma pequena explicação:

  • "Version": "2012-10-17" é a cozinha interna da AWS que você não precisa editar;
  • Principal - quem é afetado por esta regra. Você pode especificar que ele funcione apenas para uma conta específica da AWS, mas, no nosso caso, custa "*" - isso significa que a regra funciona para todos, inclusive usuários anônimos;
  • Resource - bucket e modelo ARN (Amazon Resource Name) para arquivos dentro do bucket. No nosso caso, a política se aplica a todos os arquivos que estão no example-bucket-for-habr ;
  • Condition - aqui estão as condições que devem convergir para que a política funcione. No nosso caso, estamos comparando o cabeçalho predefinido User-Agent com a linha xxxyyyzzz .

E aqui está como o trabalho desta regra se parece do ponto de vista de um usuário anônimo:

 $ curl -I https://s3.eu-central-1.amazonaws.com/example-bucket-for-habr/hello.txt HTTP/1.1 403 Forbidden $ curl -I https://s3.eu-central-1.amazonaws.com/example-bucket-for-habr/hello.txt -H 'User-Agent: xxxyyyzzz' HTTP/1.1 200 OK 

Resta configurar o nginx para proxy:

  location /s3-media/ { limit_except GET { deny all; } set $aws_bucket "example-bucket-for-habr"; set $aws_endpoint "s3.eu-central-1.amazonaws.com:443"; set $aws_custom_secret "xxxyyyzzz"; proxy_set_header User-Agent $aws_custom_secret; rewrite ^/s3-media/(.*)$ /$aws_bucket/$1 break; proxy_buffering off; proxy_pass https://$aws_endpoint; } 

Conclusão


No total, depois que escrevemos uma política simples para o bucket, tivemos a oportunidade de fazer proxy de arquivos com segurança usando o nginx. No entanto, não estamos vinculados pelo IP e não dependemos de software adicional.

PS


Leia também em nosso blog:

Source: https://habr.com/ru/post/pt426739/


All Articles