J’essaie de migrer un serveur Discourse existant vers un nouvel environnement basé sur AWS, en stockant les téléchargements dans S3 dans un bucket utilisant le chiffrement côté serveur avec des clés gérées par le client (SSE-C). Pendant le processus de restauration, les téléchargements n’arrivent pas dans S3 – chaque téléchargement échoue. Avec une utilisation judicieuse du débogage tap|p, j’ai découvert que le téléchargement est effectué, mais la validation de l’etag retourné échoue car l’etag retourné par S3 après le téléchargement est différent à chaque fois. Par exemple, voici la valeur de retour de l’appel put_object lors de deux tentatives de restauration différentes :
# Exécution 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>
# Exécution 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>
(Je sais qu’il s’agit des mêmes fichiers car j’imprime également la somme MD5 côté client et les options de requête put_object, qui incluent le nom du fichier)
Il s’avère que l’en-tête de réponse ETag se comporte… différemment lors de l’utilisation de SSE-C :
Les objets chiffrés par le chiffrement côté serveur avec des clés fournies par le client (SSE-C) ou des clés AWS Key Management Service (AWS KMS) (SSE-KMS) ont des ETags qui ne sont pas une analyse MD5 de leurs données d’objet.
La seule façon que je trouve pour vérifier l’intégrité des téléchargements avec SSE-C est d’envoyer l’en-tête de requête Content-MD5, et de laisser S3 détecter la corruption. Notez également que la vérification “déjà téléchargé” échouera également lors de l’utilisation de SSE-C, mais au moins cela peut être désactivé en utilisant SKIP_ETAG_VERIFY.
Je ne soumets pas de PR tout de suite car il y a deux approches différentes :
- étendre simplement
SKIP_ETAG_VERIFYpour englober la vérification post-téléchargement, ce qui est bon marché et une solution de contournement, et oblige les utilisateurs à savoir que leur utilisation de SSE-C signifie qu’ils devront l’activer ; ou - Passer à l’utilisation de l’en-tête Content-MD5 (de préférence toujours) pour la protection de l’intégrité des téléchargements, ce qui a l’avantage de fonctionner pour tout le monde, au prix d’un PR beaucoup plus important.
(Soit dit en passant, je suis plutôt troublé que personne n’ait rencontré cela auparavant – est-ce que personne n’utilise Discourse avec SSE-C pour les téléchargements ?)