Ken*_*ici 7 amazon-s3 amazon-web-services
如果我使用aws-cli(即使用aws s3 cp)将数据上传到S3 ,aws-cli是否会做任何工作来确认S3中的结果文件是否与原始文件匹配,或者我是否需要自己管理?
根据这个答案和putObject()的Java API文档,看起来可以在上传后验证MD5校验和.但是,我无法找到关于aws-cli是否真的这样做的明确答案.
这对我来说很重要,因为我打算从备份过程中上传GPG加密的文件,我想确信存储在S3中的内容实际上与原始文件匹配.
hta*_*ess 10
AWS 支持页面如何确保上传到 Amazon S3 或从 Amazon S3 下载的对象的数据完整性?描述了如何实现这一点。
首先确定您要上传的文件的base64编码的md5sum:
$ md5_sum_base64="$( openssl md5 -binary my-file | base64 )"
Run Code Online (Sandbox Code Playgroud)
然后使用s3api上传文件:
$ aws s3api put-object --bucket my-bucket --key my-file-name --body my-file-path --content-md5 "$md5_sum_base64"
Run Code Online (Sandbox Code Playgroud)
请注意该标志的使用--content-md5,该标志的帮助指出:
--content-md5 (string) The base64-encoded 128-bit MD5 digest of the part data.
Run Code Online (Sandbox Code Playgroud)
这里并没有过多说明为什么要使用这个标志,但是我们可以在put object 的 API 文档中找到这些信息:
为了确保数据在网络中传输时不会被损坏,请使用 Content-MD5 标头。当您使用此标头时,Amazon S3 会根据提供的 MD5 值检查对象,如果不匹配,则返回错误。此外,您可以在将对象放入 Amazon S3 时计算 MD5,并将返回的 ETag 与计算出的 MD5 值进行比较。
使用此标志会导致 S3 验证文件哈希服务器端是否与指定值匹配。如果哈希值匹配 s3 将返回 ETag:
{
"ETag": "\"599393a2c526c680119d84155d90f1e5\""
}
Run Code Online (Sandbox Code Playgroud)
ETag 值通常是十六进制 md5sum(有关某些情况可能并非如此的情况,请参阅此问题)。
如果哈希值与您指定的哈希值不匹配,则会出现错误。
A client error (InvalidDigest) occurred when calling the PutObject operation: The Content-MD5 you specified was invalid.
Run Code Online (Sandbox Code Playgroud)
除此之外,您还可以将文件 md5sum 添加到文件元数据中作为附加检查:
$ aws s3api put-object --bucket my-bucket --key my-file-name --body my-file-path --content-md5 "$md5_sum_base64" --metadata md5chksum="$md5_sum_base64"
Run Code Online (Sandbox Code Playgroud)
上传后,您可以发出head-object命令来检查值。
$ aws s3api head-object --bucket my-bucket --key my-file-name
{
"AcceptRanges": "bytes",
"ContentType": "binary/octet-stream",
"LastModified": "Thu, 31 Mar 2016 16:37:18 GMT",
"ContentLength": 605,
"ETag": "\"599393a2c526c680119d84155d90f1e5\"",
"Metadata": {
"md5chksum": "WZOTosUmxoARnYQVXZDx5Q=="
}
}
Run Code Online (Sandbox Code Playgroud)
下面是一个 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"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4371 次 |
| 最近记录: |