Amazon S3 file download through curl by using IAM user credentials - shell

I have created an IAM user with access to only one bucket. I have tested the credentials and permissions through web and python boto. Its working fine.
Now I have requirement to use these credentials and download the private file from that bucket through curl.
signature="$(echo -n "GET" | openssl sha1 -hmac "f/rHQ8yCvPthxxxxxxxXxxxx" -binary | base64)"
date="$(LC_ALL=C date -u +"%a, %d %b %Y %X %z")"
curl -H "Host: my-bucket.s3.amazonaws.com" -H "Date: $date" -H "Authorization: AWS 'XXXAJX2NY3QXXX35XXX':$signature" -H "Content-Type: 'text/plain'" https://my-bucket.s3.amazonaws.com/path/to_file.txt
but i am getting the following error:
InvalidAccessKeyIdThe AWS Access Key Id you provided does not exist in our records.
Please help, how do I download the file using curl ? Is there anything am I missing or its not possible through curl command?
Thanks!

Following is the example on how you can download with s3 curl script,
#!/bin/sh
file=path/to/file
bucket=your-bucket
resource="/${bucket}/${file}"
contentType="application/x-compressed-tar"
dateValue="`date +'%a, %d %b %Y %H:%M:%S %z'`"
stringToSign="GET
${contentType}
${dateValue}
${resource}"
s3Key=xxxxxxxxxxxxxxxxxxxx
s3Secret=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
signature=`/bin/echo -en "$stringToSign" | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -H "Host: ${bucket}.s3.amazonaws.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3Key}:${signature}" \
https://${bucket}.s3.amazonaws.com/${file}
Hope it helps.

Related

Using Curl to upload files to S3 using Signature v4

I'm trying to upload a file to s3 using this curl command (can't use awscli)
src_file=/path/to/file.png
dest_file=test_image.png
bucket=mybucket.com
s3Key="<key>"
s3Secret="<secret>"
contentsha=`openssl sha256 ${src_file} | awk '{print $NF}'`
curl https://${bucket}.s3.amazonaws.com/${dest_file} \
-H "x-amz-content-sha256: ${contentsha}" \
--aws-sigv4 "aws:amz:us-east-1:s3" \
--user "${s3Key}:${s3Secret}" \
--upload-file "${src_file}" \
--insecure
but I keep getting this error:
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
What am I doing wrong?

Upload data to aws s3 using curl in c++

I'm trying to upload the data to aws s3 using following script and getting below error.
Example Script
#!/usr/bin/sh
file_to_upload="/home/sraj/Hello10.txt"
bucket="mybucket"
filepath="/${bucket}/${file_to_upload}"
contentType='application\/x-compressed-tar'
dateValue="`date +'%a, %d %b %Y %H:%M:%S %z'`"
signature_string="PUT\n\n${contentType}\n${dateValue}\n${filepath}"
s3_access_key=xxxxxxxxx
s3_secret_key=yyyyyyyyy
signature_hash=`echo -en ${signature_string} | openssl sha256 -hmac ${s3_secret_key} -binary | base64`
echo "${s3_access_key} : ${s3_secret_key} : ${signature_hash}"
curl -X PUT -T "${file_to_upload}" \
-H "Host: ${bucket}.s3.amazonaws.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3_access_key}:${signature_hash}" \
https://${bucket}.s3.amazonaws.com/${file_to_upload}
I think this is related to I AM user KMS encryption option.
Kindly help me how to solve above issue. I'm not much idea about curl and s3 also.
It will very helpful for sample code.
Some of them mentioned this is related to Signature version4 issue but I don't have much idea about fix this one.
The error says Invalid Argument.
I found this link, I have no idea if it will help.
https://www.gyanblog.com/aws/how-upload-aws-s3-curl/#curl-the-savior`
The only difference I see is the dateValue.
I do not know if that matters, but just in case, I posted this.
# about the file
file_to_upload=<file you want to upload>
bucket=<your s3 bucket name>
filepath="/${bucket}/${file_to_upload}"
# metadata
contentType="application/x-compressed-tar"
dateValue=`date -R`
signature_string="PUT\n\n${contentType}\n${dateValue}\n${filepath}"
#s3 keys
s3_access_key=<your s3 access key>
s3_secret_key=<your s3 secret key>
#prepare signature hash to be sent in Authorization header
signature_hash=`echo -en ${signature_string} | openssl sha1 -hmac ${s3_secret_key} -binary | base64`
# actual curl command to do PUT operation on s3
curl -X PUT -T "${file_to_upload}" \
-H "Host: ${bucket}.s3.amazonaws.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3_access_key}:${signature_hash}" \
https://${bucket}.s3.amazonaws.com/${file_to_upload}

curl POST -o downloads a zip file but ansible does not?

I'm executing below commands -
JOINER_CONFIG=`curl -s -S -X GET -H "Accept: application/xml" http://dbsrd3485:8001/admin/v1/server-config`;curl -s -S --digest --user admin:NPgE3sFE -X POST -o cluster-config.zip -d "group=Default" --data-urlencode "server-config=${JOINER_CONFIG}" -H "Content-type: application/x-www-form-urlencoded" http://dbsrd3510:8001/admin/v1/cluster-config
The output is cluster-config.zip. How can I use ansible to perform the same job. I tried below ansible command but it doesn't return the zip file -
ansible dbsrd3485 -m shell -a 'JOINER_CONFIG=`curl -s -S -X GET -H "Accept: application/xml" http://dbsrd3485:8001/admin/v1/server-config`;curl -s -S --digest --user admin:NPgE3sFE -X POST -o cluster-config.zip -d "group=Default" --data-urlencode "server-config=${JOINER_CONFIG}" -H "Content-type: application/x-www-form-urlencoded" http://dbsrd3510:8001/admin/v1/cluster-config'
The output is -
dbsrd3485 | SUCCESS | rc=0 >>
I would appreciate if you someone can provide a yml script to execute using ansible-playbook.

Authenticate S3 request using Authorization header

I would like to authenticate my S3 requests using this method. For this purpose I have adapted scripts presented here. Here is how it looks like:
#!/bin/sh
file="$2"
bucket="$1"
resource="/${bucket}/${file}"
contentType="$3"
dateValue="`date +'%a, %d %b %Y %H:%M:%S %z'`"
stringToSign="GET\n\n${contentType}\n${dateValue}\n${resource}"
s3Key="$AWS_ACCESS_KEY"
s3Secret="$AWS_SECRET_ACCESS_KEY"
signature=`/bin/echo -en "$stringToSign" | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -v -H "Host: ${bucket}.s3.amazonaws.com" -H "Date: ${dateValue}" -H "Content-Type: ${contentType}" -H "Authorization: AWS ${s3Key}:${signature}" https://${bucket}.s3.amazonaws.com/${file}
My file permissions are like this:
and file content type is:
Here is how do I call my script:
./getfile1.sh tmp666 7b5879dd9b894f7fc5a14b895f01abd1.png image/png
Unfortunately I am getting SignatureDoesNotMatch error although StringToSign returned by AWS is matching mine:
<StringToSign>GET
image/png
Wed, 28 Sep 2016 12:46:14 +0200
/tmp666/7b5879dd9b894f7fc5a14b895f01abd1.png</StringToSign>
My IAM user has admin permissions. What am I doing wrong? I have spent half of day trying to solve it and feel powerless.

S3 Upload via CURL fails when triggered via cronjob

I'm using a script dump-to-s3.sh to put database dumps in a S3 bucket.
When triggered manually it works perfectly but when I trigger it via this cron (as root crontab) it fails with the following error message:
crontab
31 12 * * * /home/dokku/.mongodb/dump-to-s3.sh
error from CURL
<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided.
Check your key and signing method.</Message>...
dump-to-s3.sh
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
#cd to dump-folder
cd /dump/folder
file="mydump.tar.gz"
bucket="mybucket"
resource="/${bucket}/dumps/${file}"
contentType="application/x-compressed-tar"
dateValue=`date -R`
stringToSign="PUT\n\n${contentType}\n${dateValue}\n${resource}"
s3Key="xxxxxxxxxxxxxxxx"
s3Secret="xxxxxxxxxxxxxxxx"
signature=`echo -en ${stringToSign} | openssl sha1 -hmac ${s3Secret} -binary | base64`
curl -X PUT -T "${file}" \
-H "Host: ${bucket}.s3.amazonaws.com" \
-H "Date: ${dateValue}" \
-H "Content-Type: ${contentType}" \
-H "Authorization: AWS ${s3Key}:${signature}" \
https://${bucket}.s3.amazonaws.com/dumps/${file}
I think you might need to run bash manually, e.g.
/bin/bash /home/dokku/.mongodb/dump-to-s3.sh
The -en options for echo don't work in the regular shell; it might just be a bash extension.
In sh:
$ sh
sh-3.2$ echo -en foo
-en foo
sh-3.2$
In bash:
$ bash
bash-3.2$ echo -en foo
foobash-3.2$

Resources