curl で AWS の SigV4 署名ができるようになったらしいのでやってみた
きっかけ
curl 7.75.0 から "--aws-sigv4" フラグが使えるようになってるっぽい!
— Tori Hara (@toricls) 2021年9月7日
テストとかで AWS の API を呼び出すのがやりやすくなりそうだ〜これは嬉しい〜🎉💝🎁🎂🎈🥳🎊
/ "curl 7.75.0 is smaller | https://t.co/uTssjSA20z" https://t.co/N3EgXIH2T7 pic.twitter.com/ClokV45rz6
Tori さんのツイートを見て試してみたくなったのでやってみます。
HTTP API に IAM 認証を設定し、curl でアクセスしてみます。
HTTP API の作成
HTTP API を作成します。
# HTTP API の作成
$ aws apigatewayv2 create-api \
--name sigv4-test-api \
--protocol-type HTTP
{
"ApiEndpoint": "https://jdbexbtvta.execute-api.ap-northeast-1.amazonaws.com",
"ApiId": "jdbexbtvta",
"ApiKeySelectionExpression": "$request.header.x-api-key",
"CreatedDate": "2021-09-08T18:33:27+00:00",
"DisableExecuteApiEndpoint": false,
"Name": "sigv4-test-api",
"ProtocolType": "HTTP",
"RouteSelectionExpression": "$request.method $request.path"
}
# 統合の作成
# jsonplaceholder の Web API を叩きます
$ aws apigatewayv2 create-integration \
--api-id jdbexbtvta \
--integration-type HTTP_PROXY \
--integration-method GET \
--integration-uri "https://jsonplaceholder.typicode.com/todos/1" \
--payload-format-version "1.0"
{
"ConnectionType": "INTERNET",
"IntegrationId": "06cdxab",
"IntegrationMethod": "GET",
"IntegrationType": "HTTP_PROXY",
"IntegrationUri": "https://jsonplaceholder.typicode.com/todos/1",
"PayloadFormatVersion": "1.0",
"TimeoutInMillis": 30000
}
# ルートの作成
$ aws apigatewayv2 create-route \
--api-id jdbexbtvta \
--route-key "ANY /" \
--authorization-type AWS_IAM \
--target "integrations/06cdxab"
{
"ApiKeyRequired": false,
"AuthorizationType": "AWS_IAM",
"RouteId": "v4slx93",
"RouteKey": "ANY /",
"Target": "integrations/06cdxab"
}
# ステージへデプロイ
$ aws apigatewayv2 create-stage \
--api-id jdbexbtvta \
--stage-name '$default' \
--auto-deploy
{
"AutoDeploy": true,
"CreatedDate": "2021-09-08T18:50:53+00:00",
"DefaultRouteSettings": {
"DetailedMetricsEnabled": false
},
"LastUpdatedDate": "2021-09-08T18:50:53+00:00",
"RouteSettings": {},
"StageName": "$default",
"StageVariables": {},
"Tags": {}
}
$ curl -i -XGET https://jdbexbtvta.execute-api.ap-northeast-1.amazonaws.com
HTTP/2 403
date: Wed, 08 Sep 2021 18:58:05 GMT
content-type: application/json
content-length: 23
apigw-requestid: FW4lmg-ntjMEP0w=
{"message":"Forbidden"}
ステータスコードは 403 となり、IAM 認証が有効になっています。
curl でアクセスする
curl 7.75.0 での新機能とのことでしたので、
こちらのコンテナイメージを使用することにしました。
https://hub.docker.com/r/curlimages/curl
まずは sigV4 署名を行わずにリクエストを送信してみます。
$ docker run --rm curlimages/curl \
> -si -XGET https://jdbexbtvta.execute-api.ap-northeast-1.amazonaws.com/
HTTP/2 403
date: Wed, 08 Sep 2021 19:11:53 GMT
content-type: application/json
content-length: 23
apigw-requestid: FW6nAhZhtjMENVw=
{"message":"Forbidden"}
先ほどと同じレスポンスが返ることが確認できました。
次にsigV4 署名を行ってリクエストを送信してみます。
$ docker run --rm curlimages/curl \
> --aws-sigv4 "aws:amz:ap-northeast-1:execute-api" \
> --user "$(aws configure get aws_access_key_id):$(aws configure get aws_secret_access_key)" \
> -si -XGET https://jdbexbtvta.execute-api.ap-northeast-1.amazonaws.com/
HTTP/2 200
date: Wed, 08 Sep 2021 19:14:12 GMT
content-type: application/json; charset=utf-8
content-length: 83
server: cloudflare
apigw-requestid: FW68wjY9NjMEJvg=
x-powered-by: Express
x-ratelimit-limit: 1000
x-ratelimit-remaining: 999
x-ratelimit-reset: 1631127178
vary: Origin, Accept-Encoding
access-control-allow-credentials: true
cache-control: max-age=43200
pragma: no-cache
expires: -1
x-content-type-options: nosniff
etag: W/"53-hfEnumeNh6YirfjyjaujcOPPT+s"
via: 1.1 vegur
cf-cache-status: HIT
age: 1331
accept-ranges: bytes
expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
report-to: {"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v3?s=sbLIYFBbtzTVHKMSDkcB%2FC6EOWYc8w20q4PL6K3YzF25RmCUWrPHBDZpkxUemzCjJgyARLlp3346fLDdnTmGYrIydEsNFhwuvALEEF6h2txISOpUYIf3S9Dabvg2Vur9AC506VvDFsqTCMqj2VOG"}],"group":"cf-nel","max_age":604800}
nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
cf-ray: 68ba7f9d8a472061-NRT
alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400, h3-28=":443"; ma=86400, h3-27=":443"; ma=86400
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
}
jsonplaceholder の Web API からレスポンスが返りました。
--aws-sigv4 オプションについて
こちらのページに説明が記載されていました。
https://curl.se/libcurl/c/CURLOPT_AWS_SIGV4.html
provider1, provider2 (="aws:amz") は、
AWS sigV4 署名をするために必要な定数みたいですね。