在boto3中创建/使用预签名URL时无法验证访问凭据

时间:2018-12-04 20:31:57

标签: python amazon-web-services amazon-ec2 boto3

我正在使用boto3将加密的EBS快照从一个区域复制到另一个区域,但是当我尝试复制时,我一直收到Invalid presigned URL条消息。我在源区域中使用boto3客户端方法generate_presigned_url生成了预签名URL,并在目标区域中调用了复制函数,如下所示:

uw2_client = non_prod.client(
    'ec2', 
    region_name="us-west-2", 
    config=Config(signature_version='s3v4')
)
presigned_url = uw2_client.generate_presigned_url(
    ClientMethod='copy_snapshot',
    Params={
        'SourceSnapshotId': og_snapshot_id,   # Original snapshot ID
        'SourceRegion': 'us-west-2',
        'DestinationRegion': 'us-east-1'
        # I also tried include all parameters from copy_snapshot.
        # It didn't make a difference.
        # 'Description': desc,
        # 'KmsKeyId': 'alias/xva-nonprod-all-amicopykey',
        # 'Encrypted': True,
    }
)

这是我创建副本的代码。

ue1_client = non_prod.client(
    'ec2', 
    region_name="us-east-1", 
    config=Config(signature_version='s3v4')
)
response = ue1_client.copy_snapshot(
    Description=desc,
    KmsKeyId='alias/xva-nonprod-all-amicopykey',   # Exists in us-east-1
    Encrypted=True,
    SourceSnapshotId=og_snapshot_id,
    SourceRegion='us-west-2',
    DestinationRegion='us-east-1',
    PresignedUrl=pre_signed_url
)

它成功返回了预签名的URL。但是,如果我尝试使用该预签名的URL复制快照,则会收到无效的URL错误。如果我尝试验证网址:

r = requests.post(presigned_url)
print(r.status_code)
print(r.text)

我得到:

<Response>
    <Errors>
        <Error>
            <Code>AuthFailure</Code>
            <Message>AWS was not able to validate the provided access credentials</Message>
        </Error>
    </Errors>
    <RequestID>3189bb5b-54c9-4d11-ab4c-762cbea32d9a</RequestID>
</Response>

您可能认为我的凭据会出现问题,但是我不确定如何...与创建预签名URL所使用的凭据相同。而且我的IAM用户可以不受限制地访问EC2。

我显然在这里做错了,但我无法弄清楚是什么。任何见识将不胜感激。

编辑

只是为了确认这不是权限问题,我使用可以访问所有内容的个人帐户尝试了此操作。仍然收到相同的错误消息。

1 个答案:

答案 0 :(得分:0)

事实证明,该文档是错误的...在同一账户内复制加密的快照时,不需要签名URL(根据AWS支持)。

来自AWS Support:

  

...为了将加密的快照从一个区域复制到另一个区域(在同一AWS账户内),实际上没有必要创建预签名URL。

但是,根据他们的文档,也无法将加密的快照复制到另一个帐户... \ _(ツ)_ /

当前的boto3.EC2.Client.copy_snapshot函数文档说:

  

PresignedUrl(字符串)-

     

使用Amazon EC2 Query API复制加密的源快照时,必须提供一个预签名的URL。对于未加密的快照,此参数是可选的。

相反,只需在目标区域中创建客户端对象并像下面这样调用copy_snapshot()方法即可完成此操作:

try:
    ec2 = boto3.client(
        service_name='ec2',
        region_name='us-east-1'
    )

    ec2.copy_snapshot(
        SourceSnapshotId='snap-xxxxxxxxxxxx',
        SourceRegion='us-west-2',
        Encrypted=True,
        KmsKeyId='DestinationRegionKeyId'
    )
except Exception as e:
    print(e)