Sto cercando di migrare un server Discourse esistente in un nuovo ambiente basato su AWS, memorizzando gli upload in S3 in un bucket che utilizza la crittografia lato server con chiavi gestite dal cliente (SSE-C). Durante il processo di ripristino, gli upload non vengono inseriti in S3: ogni singolo upload fallisce. Con un uso giudizioso del debug tap|p, ho scoperto che l’upload viene effettuato, ma la validazione dell’etag restituito fallisce perché l’etag restituito da S3 dopo l’upload è diverso ogni volta. Ad esempio, questo è il valore restituito dalla chiamata put_object in due diversi tentativi di ripristino:
# Esecuzione 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>
# Esecuzione 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>
(So che si tratta degli stessi file perché sto anche stampando la somma MD5 lato client e le opzioni di richiesta put_object, che includono il nome del file)
Si scopre che l’intestazione della risposta ETag si comporta… diversamente quando si utilizza SSE-C:
Gli oggetti crittografati con chiavi fornite dal cliente (SSE-C) o chiavi AWS Key Management Service (AWS KMS) (SSE-KMS) hanno ETags che non sono un digest MD5 dei loro dati oggetto.
L’unico modo che trovo per verificare l’integrità degli upload con SSE-C è inviare l’intestazione della richiesta Content-MD5, e lasciare che S3 faccia il rilevamento delle corruzioni. Si noti anche che il controllo “già caricato” si interromperà anche quando si utilizza SSE-C, ma almeno quello può essere disabilitato utilizzando SKIP_ETAG_VERIFY.
Non sto inviando una PR immediatamente perché ci sono due modi diversi per affrontare questo problema:
- estendere semplicemente
SKIP_ETAG_VERIFYper includere la verifica post-upload, che è economica e una soluzione rapida, e richiede agli utenti di sapere che il loro uso di SSE-C significa che dovranno attivarla; o - passare all’uso dell’intestazione Content-MD5 (preferibilmente sempre) per la protezione dell’integrità dell’upload, che ha il vantaggio di funzionare per tutti, al costo di una PR molto più ampia.
(Come nota a margine, sono piuttosto turbato dal fatto che nessuno abbia riscontrato questo problema prima: nessuno sta usando Discourse con SSE-C per gli upload???)