I need to access an object from S3 using presigned URL. The problem is that the client doesn't have a public IPv4, so I need to use IPv6. Usually you can just add dualstack
to the URL (see https://docs.aws.amazon.com/AmazonS3/latest/userguide/dual-stack-endpoints.html) but a presigned URL includes the certificate only for the one generated. So if you try what I just mentioned, you get this in your response:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
<AWSAccessKeyId>ACCESSKEY</AWSAccessKeyId>
<StringToSign>foo</StringToSign>
<SignatureProvided>foo</SignatureProvided>
<StringToSignBytes>41 [ ... ] 55 68 </StringToSignBytes>
<CanonicalRequest>GET /FILE.zip X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=FOO/eu-central-1/s3/aws4_request&X-Amz-Date=20220901T103255Z&X-Amz-Expires=120&X-Amz-Security-Token=TOKEN_FOO&X-Amz-SignedHeaders=host&response-content-disposition=inline host:bucket.s3.dualstack.eu-central-1.amazonaws.com host UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 [ ... ] 41 44</CanonicalRequestBytes>
<RequestId>RFGJSDFK454B9967</RequestId>
<HostId>FOO</HostId>
</Error>
I know there are workarounds without using presigned URL, but I'd like to keep the simplicity of the solution
CodePudding user response:
How are you generating the presigned URL? Have you configured the CLI/SDK to use the dual stack endpoints?
boto3 example:
import boto3
from botocore.config import Config
client = boto3.client("s3", config=Config(s3={'use_dualstack_endpoint': True}))
url = client.generate_presigned_url("get_object", Params={"Bucket": "sampleipv6bucket", "Key": "test.json"})
Result:
https://sampleipv6bucket.s3.dualstack.us-east-1.amazonaws.com/test.json?AWSAccessKeyId=ASIA.....