Загрузка S3 несовместима с серверным шифрованием

Я пытаюсь мигрировать существующий сервер 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 (SSE-KMS), имеют ETag, который не является дайджестом MD5 их данных.

Единственный способ, который я нашёл для проверки целостности загрузок при использовании SSE-C, — это отправлять заголовок запроса Content-MD5 и доверить S3 обнаружение повреждений. Обратите также внимание, что проверка уже загруженных файлов также сломается при использовании SSE-C, но хотя бы её можно отключить с помощью SKIP_ETAG_VERIFY.

Я пока не отправляю PR, потому что есть два разных подхода к решению этой проблемы:

  1. Просто расширить SKIP_ETAG_VERIFY, чтобы он охватывал проверку после загрузки. Это дёшево и немного хаки, но требует от пользователей знать, что использование SSE-C означает необходимость включить эту опцию; или
  2. Перейти на использование заголовка Content-MD5 (предпочтительно всегда) для защиты целостности загрузок. Это имеет преимущество работы для всех, но потребует гораздо большего PR.

(Кстати, меня несколько беспокоит, что никто до сих пор не столкнулся с этой проблемой — неужели никто не использует Discourse с SSE-C для загрузок?!?)

4 лайка

Мне кажется, что «безопасная загрузка» применяется лишь в очень специфических случаях, из-за чего 99,8% всех файлов всё равно предоставляются в открытом доступе, что делает бессмысленным любое шифрование в состоянии покоя?

Матт, вы здесь не ошибаетесь, насколько мне известно, это первый раз, когда это было поднято.

(2) кажется мне правильным подходом, если вы сможете это реализовать.

В противном случае, я полагаю, у вас не будет уверенности, что все файлы находятся там, как надо.

Как только вы загрузите все файлы в свой бакет S3, общая работа Discourse в порядке? Нужны ли какие-либо другие изменения для повседневного использования (например, могут возникнуть проблемы с инвентаризацией — возможно, потребуются изменения для предподписанных URL-адресов и т. д.)?

5 лайков

Я постараюсь это уладить. К счастью, достаточно найти все упоминания «etag», чтобы определить все места в коде, требующие изменений, а тестовая suite хорошо структурирована, поэтому я легко найду, что нужно запустить и изменить.

Что касается других возможных проблем, я пока не дошёл до рабочего сайта, но буду продолжать сообщать о проблемах и создавать pull-запросы по мере продвижения. Инвентарь не должен сломаться, так как шифруется только содержимое файлов, а не их имена. Скорее всего, я не узнаю, сломаются ли предподписанные URL, так как я их не использую.

3 лайка

Я только что открыл этот PR, который удаляет проверку загрузки на основе ETag во время миграции в S3. Оказалось, что она используется только при миграции в S3; при обычной загрузке всё делается «на авось» (YOLO), что значительно упростило мне жизнь. С этим PR и ранее отправленным PR по отключению настройки сайта ACL у меня теперь есть полностью восстановленная система. Следующий шаг: тестирование функций.

6 лайков

Думаю, это уже объединено. :partying_face:

1 лайк

Эта тема была автоматически закрыта через 2 дня. Новые ответы больше не принимаются.