S3アップロードはサーバーサイド暗号化と互換性がありません

既存の Discourse サーバーを新しい AWS ベースの環境に移行しようとしており、アップロードはサーバーサイド暗号化(SSE-C)と顧客管理キーを使用してバケットに保存しています。復元プロセス中に、アップロードが S3 に保存されません。すべてのアップロードが失敗します。tap|p デバッグを適切に使用したところ、アップロードは行われているものの、返された ETag の検証が失敗していることがわかりました。これは、アップロード後に S3 から返される ETag が毎回異なるためです。たとえば、復元を試行した 2 回の試行で、 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 リクエストオプションも出力しているため、これらが同じファイルであることはわかっています)

SSE-C を使用すると、ETag レスポンスヘッダー の動作が異なることがわかりました。

顧客提供キー(SSE-C)または AWS Key Management Service(AWS KMS)キー(SSE-KMS)でサーバーサイド暗号化されたオブジェクトの ETag は、オブジェクトデータの MD5 ダイジェストではありません。

SSE-C でアップロードの整合性検証を行う唯一の方法は、Content-MD5 リクエストヘッダーを送信し、S3 に破損検出を行わせることです。また、既にアップロードされているチェック も SSE-C を使用すると壊れることに注意してください。ただし、これは SKIP_ETAG_VERIFY を使用して無効にすることができます。

すぐに PR を提出しないのは、2 つのアプローチ方法があるためです。

  1. SKIP_ETAG_VERIFY をアップロード後の検証にも拡張する。これは安価でハックな方法であり、ユーザーは SSE-C の使用によりそれを無効にする必要があることを知っておく必要があります。または
  2. Content-MD5 ヘッダーを使用するように切り替える(できれば常に)ことで、アップロードの整合性保護を行う。これは、より大きな PR のコストで、すべての人に機能するという利点があります。

(ちなみに、誰もこれに以前ヒットしなかったことに少し動揺しています。誰もアップロードに SSE-C を使用して Discourse を使用していないのでしょうか?)

「いいね!」 4

私の推測では、「セキュアアップロード」は非常に特殊なケースでのみ使用されており、すべてのアップロードの 99.8% は anyway 公開で提供されているため、あらゆる種類の暗号化(保存時)が無意味になるということでしょうか?

マット、あなたの言うことは間違っていません。私の知る限り、これは初めて提起された問題です。

(2) が可能であれば、それが正しいアプローチだと思います。

そうでなければ、ファイルがすべて正しく存在することに自信が持てないでしょう。

すべてのアップロードを S3 バケットに格納した後、Discourse の一般的な操作は問題ありませんか? 日常的な使用のために他の変更が必要ですか (在庫などが壊れる可能性を考えています。事前署名付き URL などに変更が必要かもしれません…)

「いいね!」 5

なんとかやってみます。「etag」に言及しているすべての箇所を見つけられれば、変更が必要なコードの場所をすべて見つけられるはずです。また、テストスイートもきれいに整理されているので、実行・変更が必要な箇所を簡単に見つけられます。

他に壊れる可能性のあるものについては、まだ動作するサイトを構築できていません。進捗に合わせて報告・PRを続けていきます。インベントリは、ファイルの内容のみが暗号化され、名前は暗号化されないため、壊れることはないはずです。署名付きURLが壊れるかどうかは、使用していないため、おそらくわかりません。

「いいね!」 3

S3移行中のETagベースのアップロード検証を削除するこのPRを開きました。これはS3への移行中にのみ使用され、通常のアップロードではYOLO(You Only Live Once)で処理されることが判明しました。これにより、私の作業が大幅に楽になりました。このPRと、以前提出したACL無効化サイト設定PRにより、リストアが完了しました。次のステップは機能テストです。

「いいね!」 6

これがマージされたと思います。 :partying_face:

「いいね!」 1

このトピックは2日後に自動的に閉じられました。返信はもう許可されていません。