【发布时间】:2021-07-07 18:54:46
【问题描述】:
我有一个名为 protected-bucket 的版本化 S3 存储桶,我想以编程方式删除对象或版本(有时只是某些版本)。 Bucket 附加了以下策略,强制 MFA 在即将执行 Delete* 操作时出现:
{
"Sid": "RequireMFAForDelete",
"Effect": "Deny",
"Principal": {
"AWS": "*"
},
"Action": "s3:Delete*",
"Resource": "arn:aws:s3:::protected-bucket/*",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "false"
}
}
}
我还尝试按照https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-use-case-7 页面上的建议使用存储桶策略中的"Condition": { "Null": { "aws:MultiFactorAuthAge": true }}。从下面遇到同样的问题...
这是一个最小的 Python3 代码,它应该删除我上面提到的存储桶中的对象版本:
#!/usr/bin/env python3
import boto3
from datetime import datetime
mfa_totp = input("Enter the MFA code: ")
session_name='my-test-session-' + str(int(datetime.utcnow().timestamp()))
client=boto3.client('sts', 'us-east-1')
ar_res = client.assume_role(
RoleArn='arn:aws:iam::123456789102:role/test-role',
RoleSessionName=session_name,
DurationSeconds=900,
SerialNumber='arn:aws:iam::987654321098:mfa/my_user_name',
TokenCode=mfa_totp,
)
print(ar_res)
tmp_creds = ar_res["Credentials"]
s3_client = boto3.client("s3", "us-east-1",
aws_access_key_id=tmp_creds["AccessKeyId"],
aws_secret_access_key=tmp_creds["SecretAccessKey"],
aws_session_token=tmp_creds["SessionToken"])
s3_bucket = "protected-bucket"
s3_key = "test/test4.txt"
s3_version = "XYZXbHbi3lpCNlOM8peIim6gi.IZQJqM"
# If I put code here that lists objects in
if s3_version:
response = s3_client.delete_object(Bucket=s3_bucket,
Key=s3_key,
VersionId=s3_version)
else:
response = s3_client.delete_object(Bucket=s3_bucket,Key=s3_key)
print(response)
我得到的错误如下:
Traceback (most recent call last):
File "./del_test.py", line 37, in <module>
response = s3_client.delete_object(Bucket=s3_bucket,
File "/home/dejan/py/myproj/lib64/python3.8/site-packages/botocore/client.py", line 386, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/home/dejan/py/myproj/lib64/python3.8/site-packages/botocore/client.py", line 705, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDenied) when calling the DeleteObject operation: Access Denied
注意事项:
- 我假设的角色是不同的帐户(有些人可能已经注意到 Python 代码中的不同帐号。
- 该角色在附加到该角色的策略中允许删除* 操作。当我删除存储桶策略中的 MFA 保护时,上面的 Python 3 代码可以工作 - 它可以删除对象和版本。
【问题讨论】:
-
文档说
TokenCode是“MFA 设备提供的值,如果代入角色的信任策略需要 MFA。”该角色的信任策略是否需要 MFA?角色上的 MFA 可能不会转换为实际 API 调用的 MFA。您可能需要调用get_session_token()来对 MFA 设备进行身份验证。 -
我也有同样的怀疑,但我不知道如何证实我的怀疑...我需要承担角色,因为只有该角色才能删除存储桶中的对象。那么您是否建议我使用 get_session_token(),然后承担返回凭据的角色?我一直觉得假设角色()做同样的事情,唯一的区别是几个额外的参数(假设的角色等)......
-
您可能需要执行相反的操作...假设 IAM 角色具有必要的权限,然后 GetSessionToken 保留相同的权限集但允许指定 MFA 令牌。然后,使用生成的凭据执行删除。
-
GetSessionToken不能使用会话凭据调用。我相信反过来:首先获取 MFA 会话,然后将这些凭据传递给新的 STS 客户端以执行AssumeRole,然后使用这些新凭据进行删除。
标签: amazon-web-services amazon-s3 boto3