Эта страница поддержки AWS - Как обеспечить целостность данных объектов, загруженных или загруженных из Amazon S3? - описывает более надежный способ проверки целостности ваших резервных копий s3.
Сначала определите в кодировке Base64 md5sum файла, который вы хотите загрузить:
$ md5_sum_base64="$( openssl md5 -binary my-file | base64 )"
Затем используйте s3api для загрузки файла:
$ aws s3api put-object --bucket my-bucket --key my-file --body my-file --content-md5 "$md5_sum_base64"
Обратите внимание на использование --content-md5
флаг, справка для этого флага гласит:
--content-md5 (string) The base64-encoded 128-bit MD5 digest of the part data.
Это мало что говорит о , почему использовать этот флаг, но мы можем найти эту информацию в документации API дляput object :
Чтобы данные не были повреждены при прохождении через сеть, используйте заголовок Content-MD5.Когда вы используете этот заголовок, Amazon S3 проверяет объект по предоставленному значению MD5 и, если они не совпадают, возвращает ошибку.Кроме того, вы можете вычислить MD5 при помещении объекта в Amazon S3 и сравнить возвращенный ETag с вычисленным значением MD5.
При использовании этого флага S3 проверяет, что хеш файла на стороне сервера соответствует указанному значению,Если совпадение хэшей s3 вернет ETag:
{
"ETag": "\"599393a2c526c680119d84155d90f1e5\""
}
Значение ETag обычно будет шестнадцатеричным значением md5sum (см. этот вопрос для некоторых сценариев, где это может быть не так).
Если хэш не соответствует указанному вами, вы получаете сообщение об ошибке.
A client error (InvalidDigest) occurred when calling the PutObject operation: The Content-MD5 you specified was invalid.
В дополнение к этому вы также можете добавить файл md5sum к метаданным файла в качестве дополнительной проверки:
$ aws s3api put-object --bucket my-bucket --key my-file --body my-file --content-md5 "$md5_sum_base64" --metadata md5chksum="$md5_sum_base64"
После загрузки вы можете выполнить команду head-object
для проверки значений.
$ aws s3api head-object --bucket my-bucket --key my-file
{
"AcceptRanges": "bytes",
"ContentType": "binary/octet-stream",
"LastModified": "Thu, 31 Mar 2016 16:37:18 GMT",
"ContentLength": 605,
"ETag": "\"599393a2c526c680119d84155d90f1e5\"",
"Metadata": {
"md5chksum": "WZOTosUmxoARnYQVXZDx5Q=="
}
}
Вот скрипт bash, который использует контент md5 и добавляет метаданные, а затем проверяет, чтозначения, возвращаемые S3, соответствуют локальным хешам:
#!/bin/bash
set -euf -o pipefail
# assumes you have aws cli, jq installed
# change these if required
tmp_dir="$HOME/tmp"
s3_dir="foo"
s3_bucket="stack-overflow-example"
aws_region="ap-southeast-2"
aws_profile="my-profile"
test_dir="$tmp_dir/s3-md5sum-test"
file_name="MailHog_linux_amd64"
test_file_url="https://github.com/mailhog/MailHog/releases/download/v1.0.0/MailHog_linux_amd64"
s3_key="$s3_dir/$file_name"
return_dir="$( pwd )"
cd "$tmp_dir" || exit
mkdir "$test_dir"
cd "$test_dir" || exit
wget "$test_file_url"
md5_sum_hex="$( md5sum $file_name | awk '{ print $1 }' )"
md5_sum_base64="$( openssl md5 -binary $file_name | base64 )"
echo "$file_name hex = $md5_sum_hex"
echo "$file_name base64 = $md5_sum_base64"
echo "Uploading $file_name to s3://$s3_bucket/$s3_dir/$file_name"
aws \
--profile "$aws_profile" \
--region "$aws_region" \
s3api put-object \
--bucket "$s3_bucket" \
--key "$s3_key" \
--body "$file_name" \
--metadata md5chksum="$md5_sum_base64" \
--content-md5 "$md5_sum_base64"
echo "Verifying sums match"
s3_md5_sum_hex=$( aws --profile "$aws_profile" --region "$aws_region" s3api head-object --bucket "$s3_bucket" --key "$s3_key" | jq -r '.ETag' | sed 's/"//'g )
s3_md5_sum_base64=$( aws --profile "$aws_profile" --region "$aws_region" s3api head-object --bucket "$s3_bucket" --key "$s3_key" | jq -r '.Metadata.md5chksum' )
if [ "$md5_sum_hex" == "$s3_md5_sum_hex" ] && [ "$md5_sum_base64" == "$s3_md5_sum_base64" ]; then
echo "checksums match"
else
echo "something is wrong checksums do not match:"
cat <<EOM | column -t -s ' '
$file_name file hex: $md5_sum_hex s3 hex: $s3_md5_sum_hex
$file_name file base64: $md5_sum_base64 s3 base64: $s3_md5_sum_base64
EOM
fi
echo "Cleaning up"
cd "$return_dir"
rm -rf "$test_dir"
aws \
--profile "$aws_profile" \
--region "$aws_region" \
s3api delete-object \
--bucket "$s3_bucket" \
--key "$s3_key"