OCIのREST APIをCurlで使ってみる:バケット内のオブジェクト一覧
最近、OCIでREST APIを使ってバケットを操作する必要があったのですが、Curlで直接APIを叩きにいくような使い方は推奨されていないようでした。
最終的に何とかなったものの、実現に苦労したので、手順を書き残しておくことにしました。
以下のコマンドを順番に実行していくことで、REST APIによってバケット内のオブジェクト一覧を取得することができます。
※Linuxのbashを環境を想定しています。また、IAMポリシーなどの設定は完了していることが前提となります。
テナンシのOCIDの設定
tenancy_ocid="<テナンシのOCID>"
ユーザのOCIDの設定
user_ocid="<ユーザのOCID>"
APIキー(公開鍵)のフィンガープリントの設定
key_fingerprint="<公開鍵のフィンガープリント(OCI画面上で確認可能)>"
APIキー(秘密鍵)のパス/ファイル名の設定
private_key_path="<秘密鍵のパス/ファイル名>"
なお、秘密鍵・公開鍵はユーザ画面の「APIキー」の項目に登録されている必要があります。
OCIで生成して秘密鍵をダウンロード、または、手元で生成して公開鍵をアップロード、のどちらでも問題ありませんが、特に理由がなければ、OCIで生成するのが無難でしょう。
リクエスト先ホストの設定
host="objectstorage.ap-tokyo-1.oraclecloud.com"
ホスト及びエンドポイントはリージョンによって異なり、上記のホストは東京リージョンの場合です。
Curlのメソッド及びリクエスト・ターゲットの設定
request_target="(request-target): get /n/<ネームスペース>/b/<バケット>/o"
APIのエンドポイントURLの設定
endpoint="https://objectstorage.ap-tokyo-1.oraclecloud.com/n/<ネームスペース>/b/<バケット>/o"
endpoint, host について、FQDNをVCNに配置したプライベートエンドポイントのものにして、プライベート環境でREST APIを使うことも可能です。(ネットワーク関係の設定が完了している必要があります)
現在時刻(UTC)の取得
date_value=`date -u "+%a, %d %b %Y %H:%M:%S GMT"`
ここで取得した時刻は認証情報の一部となり、リクエスト実行時、OCI側の時刻との差が5分以内でなければなりません。
5分を超えていると、その旨のメッセージが表示されて、APIの実行はエラーとなります。
署名対象の文字列の設定
signing_string="date: $date_value\nhost: $host\n$request_target"
\n を入れているのは、次の署名生成の際に改行コードを読み込ませて、上記の文字列をjsonの形式にするためです。
署名の生成
signed_string=$(echo -en "$signing_string" | openssl dgst -sha256 -sign "$private_key_path" | openssl enc -e -base64 | tr -d '\n')
署名対象の文字列に秘密鍵で署名して、base64で暗号化しています。
base64暗号化後に改行が含まれていると署名として機能しないため、最後に改行の削除を行っています。
認証ヘッダの作成
authorization_header="Signature version=\"1\",keyId=\"$tenancy_ocid/$user_ocid/$key_fingerprint\",algorithm=\"rsa-sha256\",headers=\"date host (request-target)\",signature=\"$signed_string\""
認証ヘッダの headers= には、署名対象の文字列を設定した際の項目と同じものが入りますが、ヘッダに含める項目名だけでなく、項目を記載する順序まで一致している必要があります。
APIリクエストの実行
curl -X GET -H "Host: $host" -H "Date: $date_value" -H "Authorization: $authorization_header" $endpoint
ここまでの処理が正しく行われていれば、バケット内のオブジェクト名を取得できるはずです。