흐르는 시간의 블로그...

AWS를 사용하는데 가장 좋은 방안은 SDK를 사용하는 것이다.

하지만 모든 SDK를 제공하지도 않으며 현재 테스트할 작업에서는 AWS REST API가 적절하다 생각하여 테스트를 했다.

하지만 짧은 영어탓과 제대로 이해하지 못하여 원하는 결과를 내지는 못했다.

그 과정을 정리해본다.


AWS REST API에서 첫번째 관문은 인증이다.

당연한 문제이기도 하다.

인증 방식 중 Signature Version 4를 사용하는 방법을 찾았다.


Authenticating Requests (AWS Signature Version 4)

위의 링크에서 확인할 수 있듯이 HTTP Authorization header과 Query string parameters를 사용할 수 있다.

query string 방식은 미리 인증된 URL을 사용하며 그 링크는 7일간 유효하다.

긴 시간 일관된 방식으로 서비스하기에는 적절하지 않다.

따라서 HTTP Authorization header를 사용하려고 시도하였다.



Authenticating Requests: Using the Authorization Header (AWS Signature Version 4)

인증의 시작은 바로 위의 링크의 내용을 따라 진행한다.

관련하여 Amazone S3 REST API with curl 의 블로그가 매우 잘 설명하고 있다.


인증을 위한 기본 키가 필요한데 해당 내용은 AWS IAM에서 진행한다

AWS IAM Service --> Users --> ID 선택 --> Security credentials 탭 --> Access Key 생성


저 과정을 통해서 KEY ID와 Security Key를 얻어서 사용할 수 있다.

아래의 내용은 위의 내용들과 인터넷에서 구한 쉘 스크립트를 이용해 "GET / "를 작동시켜보았다.

결과로 버킷 내의 모든 파일의 키값과 크기등의 정보를 XML로 반환한다.


#!/bin/bash
function hmac_sha256 {
  key="$1"
  data="$2"
  echo -n "$data" | openssl dgst -sha256 -mac HMAC -macopt "$key" | sed 's/^.* //'
}

#filename=$1
#filesize=$(stat -c%s "$filename")

date=$(date -u +"%Y%m%dT%H%M%SZ")
datek=$(date -u +"%Y%m%d")

reqmethod="GET"
canonicaluri="/"
canonicalquerystring=""
canonicalheaders="host:ubikhan-vod3.s3.amazonaws.com\nx-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-amz-date:$date"
signedheaders="host;x-amz-content-sha256;x-amz-date"
#hashedpayload=$(openssl dgst -sha256 $filename | sed 's/^.* //')
#echo "hashedpayload:"$hashedpayload
hashedpayload="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"

canonicalrequest=$reqmethod"\n"$canonicaluri"\n"$canonicalquerystring"\n"$canonicalheaders"\n\n"$signedheaders"\n"$hashedpayload

echo -e $canonicalrequest

keyid="XXXXXXXXXXXXXXXXXXX"
secret="securityYYYYYYYYYYYYYYYYYYYY"
region="ap-northeast-1"
service="s3"

awsreq="aws4_request"
algorithm="AWS4-HMAC-SHA256"
credentialscope=$datek/$region/$service/$awsreq
hashedcanonicalrequest=$(echo -e -n "$canonicalrequest" | openssl dgst -sha256 | sed 's/^.* //')
strtosign=$algorithm"\n"$date"\n"$credentialscope"\n"$hashedcanonicalrequest

echo -e $strtosign

# Four-step signing key calculation
dateKey=$(hmac_sha256 key:"AWS4$secret" $datek)
dateRegionKey=$(hmac_sha256 hexkey:$dateKey $region)
dateRegionServiceKey=$(hmac_sha256 hexkey:$dateRegionKey $service)
signingKey=$(hmac_sha256 hexkey:$dateRegionServiceKey "aws4_request")
signature=$(hmac_sha256 hexkey:$signingKey $strtosign)
echo $signature

request="https://ubikhan-vod3.s3.amazonaws.com/ -H \"Authorization: AWS4-HMAC-SHA256 Credential=$keyid/$datek/ap-northeast-1/s3/aws4_request, SignedHeaders=$signedheaders, Signature=$signature\" -H \"x-amz-content-sha256: $hashedpayload\" -H \"x-amz-date: $date\" "

echo $request
curl -v $request


canonical request와 payload에 대한 명확하게 이해한다면 REST API를 이용하여 PUT을 해볼 수 있을 것이다.

다만 PUT을 위한 이 부분을 아직도 이해 못하고 있는 상황이다.