أحاول ترحيل خادم Discourse موجود إلى بيئة جديدة مستندة إلى AWS، مع تخزين التحميلات في S3 في حاوية باستخدام التشفير من جانب الخادم باستخدام مفاتيح مدارة بواسطة العميل (SSE-C). أثناء عملية الاستعادة، لا تصل التحميلات إلى S3 - فشل كل تحميل. باستخدام الاستخدام الحكيم لتصحيح الأخطاء tap|p، اكتشفت أن التحميل يتم، ولكن التحقق من صحة etag المُعاد يفشل لأن etag المُعاد من S3 بعد التحميل يختلف في كل مرة. على سبيل المثال، هذه هي القيمة المُعادة من استدعاء put_object في محاولتين مختلفتين للاستعادة:
# التشغيل 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>
# التشغيل 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>
(أعلم أن هذه هي نفس الملفات لأنني أقوم أيضًا بطباعة مجموع MD5 من جانب العميل وخيارات طلب put_object، والتي تتضمن اسم الملف)
اتضح أن رأس استجابة ETag يتصرف … بشكل مختلف عند استخدام SSE-C:
تتمتع الكائنات المشفرة بواسطة التشفير من جانب الخادم باستخدام مفاتيح مقدمة من العميل (SSE-C) أو مفاتيح AWS Key Management Service (AWS KMS) (SSE-KMS) بقيم ETag ليست تجزئة MD5 لبيانات كائنها.
الطريقة الوحيدة التي يمكنني العثور عليها للتحقق من سلامة التحميلات باستخدام SSE-C هي إرسال رأس طلب Content-MD5، والسماح لـ S3 بإجراء اكتشاف التلف. لاحظ أيضًا أن فحص الملف الذي تم تحميله بالفعل سيتعطل أيضًا عند استخدام SSE-C، ولكن على الأقل يمكن تعطيل ذلك باستخدام SKIP_ETAG_VERIFY.
أنا لا أقدم طلب سحب (PR) مباشرة لأن هناك طريقتين مختلفتين للتعامل مع هذا:
- فقط قم بتوسيع
SKIP_ETAG_VERIFYليشمل التحقق بعد التحميل، وهو أمر رخيص وغير فعال، ويتطلب من المستخدمين معرفة أن استخدامهم لـ SSE-C يعني أنهم سيضطرون إلى تشغيل ذلك؛ أو - التبديل إلى استخدام رأس Content-MD5 (يفضل دائمًا) لحماية سلامة التحميل، والذي له فائدة العمل للجميع، بتكلفة طلب سحب أكبر بكثير.
(جانباً، أنا منزعج إلى حد ما لأن لا أحد واجه هذا من قبل - هل لا أحد يستخدم Discourse مع SSE-C للتحميلات؟!)