Cargas S3 incompatibles con cifrado del lado del servidor

Estoy intentando migrar un servidor Discourse existente a un nuevo entorno basado en AWS, almacenando subidas en S3 en un bucket que utiliza cifrado del lado del servidor con claves administradas por el cliente (SSE-C). Durante el proceso de restauración, las subidas no llegan a S3; cada subida falla. Con el uso juicioso de la depuración tap|p, he descubierto que la subida se realiza, pero la validación del etag devuelto falla porque el etag devuelto por S3 después de la subida es diferente cada vez. Por ejemplo, este es el valor de retorno de la llamada put_object en dos intentos de restauración diferentes:

# Ejecución 1
#
# <struct Aws::S3::Types::PutObjectOutput expiration=nil, etag="\"d49ec2006cfd6fe957af2f711edd9a4b\"", checksum_crc32=nil, checksum_crc32c=nil, checksum_sha1=nil, checksum_sha256=nil, server_side_encryption="aws:kms", version_id="xAF23wQ.zwpoxVmmGiTjxfX0svMZbHAe", sse_customer_algorithm=nil, sse_customer_key_md5=nil, ssekms_key_id="**redacted**", ssekms_encryption_context=nil, bucket_key_enabled=true, request_charged=nil>

# Ejecución 2:
#
# <struct Aws::S3::Types::PutObjectOutput expiration=nil, etag="\"05edffee421c6aef950b3d4418ada293\"", checksum_crc32=nil, checksum_crc32c=nil, checksum_sha1=nil, checksum_sha256=nil, server_side_encryption="aws:kms", version_id="H2_8SVh.Yx2LKB4GIjhyPbVoj_.Vc1E2", sse_customer_algorithm=nil, sse_customer_key_md5=nil, ssekms_key_id="**redacted**", ssekms_encryption_context=nil, bucket_key_enabled=true, request_charged=nil>

(Sé que son los mismos archivos porque también estoy imprimiendo la suma MD5 del lado del cliente y las opciones de solicitud de put_object, que incluyen el nombre del archivo).

Resulta que la cabecera de respuesta ETag se comporta… de manera diferente cuando se utiliza SSE-C:

Los objetos cifrados por el cifrado del lado del servidor con claves proporcionadas por el cliente (SSE-C) o claves de AWS Key Management Service (AWS KMS) (SSE-KMS) tienen ETags que no son un resumen MD5 de sus datos de objeto.

La única forma que encuentro para verificar la integridad de las subidas con SSE-C es enviar la cabecera de solicitud Content-MD5, y dejar que S3 haga la detección de corrupción. Tenga en cuenta también que la comprobación de ya subido también fallará al usar SSE-C, pero al menos eso se puede deshabilitar usando SKIP_ETAG_VERIFY.

No estoy enviando un PR de inmediato porque hay dos formas diferentes de abordar esto:

  1. Simplemente extender SKIP_ETAG_VERIFY para que abarque la verificación posterior a la subida, lo cual es barato y un hackeo, y requiere que los usuarios sepan que su uso de SSE-C significa que tendrán que activarlo; o
  2. Cambiar al uso de la cabecera Content-MD5 (preferiblemente siempre) para la protección de la integridad de la subida, lo que tiene el beneficio de funcionar para todos, a costa de un PR mucho más grande.

(Como aparte, me perturba bastante que nadie haya encontrado esto antes: ¿nadie está usando Discourse con SSE-C para las subidas?)

4 Me gusta

Mi suposición es que las “cargas seguras” se utilizan solo en casos muy específicos, lo que hace que el 99,8 % de todas las cargas se sirvan públicamente de todos modos, lo que hace inútil cualquier tipo de cifrado en reposo.

No te equivocas, Matt, que yo sepa es la primera vez que se plantea esto.

El punto (2) me parece el enfoque correcto si puedes conseguirlo.

De lo contrario, supongo que no tendrás la confianza de que todos los archivos estén ahí correctamente.

Una vez que tengas todas las cargas en tu bucket de S3, ¿funciona correctamente la operación general de Discourse? ¿Se necesitan otros cambios para el uso diario (pensando en cosas como que el inventario pueda romperse, quizás se necesiten cambios para las URL pre-firmadas, etc.)?

5 Me gusta

Intentaré hacerlo. Afortunadamente, encontrar todo lo que menciona “etag” debería ser suficiente para encontrar todas las ubicaciones de código que necesitan cambiarse, y el conjunto de pruebas está bien organizado para que pueda encontrar lo que necesita ejecutarse y cambiarse con bastante facilidad.

En cuanto a otras cosas que puedan romperse, todavía no he logrado que el sitio funcione, y seguiré informando/enviando PR a medida que avance. El inventario no debería romperse, porque solo el contenido del archivo está cifrado, no los nombres. Probablemente no descubriré si las URL pre-firmadas se romperán, ya que no las estoy utilizando.

3 Me gusta

He abierto este PR que elimina la verificación de carga basada en ETag durante la migración a S3. Resulta que solo se usa durante la migración a S3; en la carga normal, simplemente se hace a lo YOLO, lo que me facilitó mucho la vida. Con este PR, y el PR de desactivación de ACL como ajuste del sitio enviado previamente, ahora tengo una restauración completa. Siguiente paso: probar las funciones.

6 Me gusta

Creo que esto ya se ha fusionado. :partying_face:

1 me gusta

Este tema se cerró automáticamente después de 2 días. Ya no se permiten nuevas respuestas.