Parece que la tarea de implementar la interfaz para AWS en nginx suena como un caso t铆pico de StackOverflow: despu茅s de todo, 驴no puede haber problemas con la representaci贸n de archivos desde S3? De hecho, result贸 que una soluci贸n preparada no es tan f谩cil de encontrar, y este art铆culo deber铆a corregir esta situaci贸n.

驴Por qu茅 necesitar铆as esto?
- Controle el acceso a los archivos usando nginx: relevante para el concepto de IaC (infraestructura como c贸digo). Todos los cambios relacionados con el acceso se realizar谩n solo en las configuraciones que est谩n en el proyecto.
- Si entrega archivos a trav茅s de su nginx, puede guardarlos en cach茅 y guardar las solicitudes en S3.
- Tal proxy ayudar谩 a ignorar el tipo de almacenamiento de archivos para diferentes instalaciones de aplicaciones (despu茅s de todo, hay otras soluciones adem谩s de S3).
Formulamos el marco
- El dep贸sito de origen debe ser privado : no puede permitir que usuarios an贸nimos descarguen archivos directamente desde S3. Si en su caso esta restricci贸n no funciona, simplemente use
proxy_pass
y ya no podr谩 leer. - El ajuste por AWS debe ser de una sola vez "sintonizado y olvidado" para simplificar la operaci贸n.
Estamos buscando una soluci贸n en la frente.
Si su dep贸sito original es p煤blico, entonces no hay amenazas que lo amenacen, las solicitudes de proxy para S3 y todo funcionar谩. Si es privado, tendr谩 que autenticarse con S3 de alguna manera. 驴Qu茅 nos ofrecen los colegas de Internet?
- Hay ejemplos de implementaci贸n del protocolo de autenticaci贸n usando nginx. La soluci贸n es buena, pero desafortunadamente, est谩 dise帽ada para un protocolo de autenticaci贸n obsoleto ( Signature v2 ), que no funciona en algunos centros de datos de Amazon . Si intenta utilizar esta soluci贸n, por ejemplo, en Frankfurt, recibir谩 el error "El mecanismo de autorizaci贸n que ha proporcionado no es compatible. Utilice AWS4-HMAC-SHA256 " . Una versi贸n m谩s reciente del protocolo ( Signature v4 ) es mucho m谩s dif铆cil de implementar, pero no hay soluciones listas para usar con nginx.
- Hay un m贸dulo de terceros para nginx: ngx_aws_auth . A juzgar por la fuente, es compatible con Signature v4. Sin embargo, el proyecto parece abandonado: durante m谩s de un a帽o no ha habido cambios en la base del c贸digo, y tambi茅n hay un problema de compatibilidad con otros m贸dulos a los que el desarrollador no responde. Adem谩s, agregar m贸dulos adicionales a nginx es a menudo un paso doloroso en s铆 mismo.
- Puede usar un proxy s3 separado, del cual se ha escrito bastante. Personalmente, me gust贸 la soluci贸n Go: aws-s3-proxy : tiene una imagen lista y bastante popular en DockerHub. Pero en este caso, la aplicaci贸n adquirir谩 otro componente con sus posibles problemas.
Aplicar la pol铆tica de AWS Bucket
AWS, por regla general, asusta a los nuevos usuarios con su complejidad y volumen de documentaci贸n. Pero si miras, entiendes que est谩 dise帽ado de manera muy l贸gica y flexible. Amazon tambi茅n encontr贸 una soluci贸n para nuestra tarea:
S3 Bucket Policy . Este mecanismo le permite crear reglas de autorizaci贸n flexibles para el dep贸sito en funci贸n de diferentes par谩metros del cliente o solicitud.
Interfaz del generador de pol铆ticas: generador de pol铆ticas de AWSAqu铆 hay algunas opciones interesantes a las que puede unirse:
- IP (
aws:SourceIp
), - Referer header (
aws:Referer
), aws:UserAgent
agente de usuario ( aws:UserAgent
),- El resto se describe en la documentaci贸n .
El enlace de IP es una buena opci贸n solo si la aplicaci贸n tiene un cierto lugar de residencia, y en nuestro tiempo es raro. En consecuencia, debe apegarse a otra cosa. Como soluci贸n, propongo
generar un Usuario-Agente o Referente secreto y dar archivos solo a aquellos usuarios que conocen el encabezado secreto. As铆 es como se ve una pol铆tica similar:
{ "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" ] } } } ] }
Una peque帽a explicaci贸n:
"Version": "2012-10-17"
es la cocina interna de AWS que no necesita editar;Principal
: qui茅n se ve afectado por esta regla. Puede especificar que solo funciona para una cuenta de AWS espec铆fica, pero en nuestro caso cuesta "*"
, esto significa que la regla funciona para todos, incluidos los usuarios an贸nimos;Resource
: dep贸sito y plantilla ARN (nombre de recurso de Amazon) para archivos dentro del dep贸sito. En nuestro caso, la pol铆tica se aplica a todos los archivos que se encuentran en el example-bucket-for-habr
;Condition
: estas son las condiciones que deben converger para que la pol铆tica funcione. En nuestro caso, estamos comparando el encabezado User-Agent predefinido con la l铆nea xxxyyyzzz
.
Y as铆 es como se ve el trabajo de esta regla desde el punto de vista de un usuario 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
Queda por
configurar 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; }
Conclusi贸n
En total, una vez que escribimos una pol铆tica simple para bucket, tuvimos la oportunidad de usar archivos proxy con seguridad usando nginx. Sin embargo, no estamos atados por IP y no dependemos de software adicional.
PS
Lea tambi茅n en nuestro blog: