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 署名をするために必要な定数みたいですね。