🗄

WinSCPなどのAmazon S3互換クライアントでGoogle Cloud Storageにアクセスする方法

2023/04/05に公開

こんにちは。Google Cloudのカスタマーエンジニアの有賀です。

Google Cloud Storage(GCS)へGUIでアクセスできるソフトウェアとしてはCloudBerry ExplorerCyberduckなどがありますが、これまで使っていたWinSCPなどのAmazon S3互換クライアントでアクセスしたい、という場合も多いかと思います。

そこで、この記事ではAmazon S3互換クライアントの1つであるWinSCPでGCSにアクセスする方法をご紹介します。

(ちなみにCloud StorageそのものについてはG-genさんの記事「Cloud Storage(GCS)を徹底解説」が詳しいです。)

Amazon S3 APIアクセス

WinSCPはその名の通りSSH/SCP/SFTPでアクセスするのがデフォルトですが、その他にもFTP、WebDAV、そしてAmazon S3のAPIでもアクセスできます

そしてGCSは実はAmazon S3互換のAPIでのアクセスもサポートしているので、WinSCPのAmazon S3サポートと組み合わせて使うと、WinSCPからGCSに簡単にアクセスできます。

WinSCPがアクセスするための認証情報

WinSCPでAmazon S3にアクセスするには認証情報としてアクセスキーIDとシークレットアクセスキーが必要になります。GCSではサービスアカウントを用意して、互換モードを設定することでアクセスキーとシークレットキーを入手できます。

サービスアカウントの作成

それではさっそくサービスアカウントを用意します。

  1. Cloud Consoleの左上の ≡ メニューで「IAMと管理 - サービスアカウント」を選びます。
  2. 上にある「+ サービスアカウントを作成」をクリック。


サービスアカウント

  1. サービスアカウント名などを設定したら、他は後で設定するので「作成して続行」の代わりに一番下の「完了」をクリックしてサービスアカウントの作成を終了します。


サービスアカウントの作成

サービスアカウント「sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com」ができました。


できたサービスアカウント

GCSバケットの作成

次にGCSのバケットを作成します。

  1. 同じく左上の ≡ メニューから「ストレージ」カテゴリにある「Cloud Storage - バケット」を選びます。
  2. 上にある「+ 作成」をクリック。


Google Cloud Storage

  1. バケットに名前を付けます。「グローバルに一意」とあるように、他のユーザーのバケットと重複しないように名前をつけます。


バケットに名前を付ける

  1. バケットの保存場所を選択します。「Multi-region」「Dual-region」「Region」から選べます。(それぞれの特徴はドキュメントにまとまってます)ここでは東京リージョンに作ります。


東京リージョンに保存する

  1. データのストレージクラスを選択します。バケットに保存するオブジェクトがどんな使われ方をするか分からない場合は「Autoclass」を選んでおくと楽です。「Autoclass」については「Cloud Storageの新機能Autoclassについて」という記事が詳しいです。


ストレージクラスの選択

  1. バケット内のオブジェクトへのアクセスを制御する方法を選択します。アクセス制御には「均一」(Uniform)と「きめ細かい管理」(Fine-grained)の2つがあります。「推奨されるバケット アーキテクチャ」にもあるように、異なるアクセス権のオブジェクトを1つのバケットに混ぜるのは推奨されないので、通常は「均一」(Uniform)の方を選んでおくとよいでしょう。なお、デフォルトで公開アクセスを防止するために「このバケットに対する公開アクセス禁止を適用する」にチェックが入っています。公開する予定がなければそのままにしておきましょう。


アクセス制御の選択

  1. 最後にバケット内のオブジェクトを保護する方法を選択します。この場合の「保護」は誤ってオブジェクトを削除してしまわないようにする、といった意味合いでの保護になります。方法としては「オブジェクトのバージョニング」と「保持ポリシー」があります。バージョニングではオブジェクトの更新時に指定された分だけバージョンを保持し、保持ポリシーでは指定した期間オブジェクトを削除・置き換えできなくなります。また、オブジェクトの暗号化もここで指定できます。今回はテストなので「なし」を指定します。


オブジェクトの保護

  1. 最後に「作成」をクリックすると、アクセスを制御する方法の項目で「このバケットに対する公開アクセス禁止を適用する」にチェックを入れてた場合、「公開アクセスの防止」 というダイアログが表示され、バケットが公開されないように設定されているが問題ないか?という確認がされます。(「公開アクセスの防止」という機能が後から追加され、デフォルトが公開アクセスの禁止に変わったためだと思われます。)


公開アクセスの防止の確認

  1. 以上でGCSのバケット「gcs-bucket-for-winscp」が作成できました。


バケットの作成完了

バケットへのアクセス権をサービスアカウントへ付与

バケットができたので、先に作ったサービスアカウント「sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com」にバケットへのアクセス権を付与します。

  1. バケットのページにある「権限」タブを選択し、「アクセス権を付与」をクリックします。


アクセス権を付与

  1. 「新しいプリンシパル」にサービスアカウント「sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com」を記入します。


プリンシパルを設定

次にこのサービスアカウントにどのような権限を与えるかを考えた上で適切なロールを選びます。

GCS用にデフォルトで用意されてるロールには以下のようなロールがあります。(一部省略)

ロール名 従来 対象 説明
ストレージオブジェクト閲覧者 バケット、プロジェクト オブジェクトとそのメタデータ(ACL を除く)を閲覧するためのアクセス権を付与します。バケット内のオブジェクトを一覧表示することもできます。
ストレージオブジェクト作成者 バケット、プロジェクト ユーザーによるオブジェクトの作成を許可します。オブジェクトの表示、削除または置き換えを行う権限は付与されません。
ストレージオブジェクト管理者 バケット、プロジェクト オブジェクトの一覧表示、作成、表示、削除など、オブジェクトのすべてを管理できる権限を付与します。
ストレージ管理者 バケット、プロジェクト バケットとオブジェクトのすべてを管理する権限を付与します。個々のバケットに適用した場合、指定したバケットとその中のオブジェクトに対してのみ操作が適用されます。
ストレージレガシーオブジェクト読み取り 従来 バケットのみ オブジェクトとそのメタデータ(ACL を除く)を閲覧する権限を付与します。
ストレージレガシーバケット読み取り 従来 バケットのみ バケットのコンテンツを一覧表示し、バケットのメタデータ(IAM ポリシーを除く)を読み取るための権限を付与します。また、オブジェクトを一覧表示するときにオブジェクト メタデータ(IAM ポリシーを除く)を読み取るための権限を付与します。
ストレージレガシーオブジェクトオーナー 従来 バケットのみ オブジェクトとそのメタデータ(ACL を含む)を閲覧し、編集する権限を付与します。
ストレージレガシーバケット書き込み 従来 バケットのみ バケット内のオブジェクトを作成、置き換え、削除するためのアクセス権、一覧表示するときに、オブジェクトのメタデータ(IAM ポリシーを除く)を読み取るためのアクセス権、バケットのメタデータ(IAM ポリシーを除く)を読み取るためのアクセス権を付与します。
ストレージレガシーバケット オーナー 従来 バケットのみ オブジェクトを作成、置き換え、削除するための権限、バケット内のオブジェクトを一覧表示する権限、タグ バインディングの作成、削除、一覧表示を行う権限、一覧表示の際にオブジェクト メタデータ(IAM ポリシーを除く)を読み取るための権限、IAM ポリシーを含むバケットのメタデータの読み取りと編集を行うための権限を付与します。

大きく現行のロールと、従来(レガシー)のロールに分かれており、現行のロールはプロジェクト、バケットにいずれにも設定できますが、従来のロールはバケットにだけ設定できます。(ロールの適用対象についてはドキュメント「プロジェクトレベルのロールとバケットレベルのロール」を確認してください。)

簡単にまとめるとこんな感じになります。ご覧の通り「従来のロール」は単体ではかなり限定された権限になっています。

ロール できること
ストレージオブジェクト閲覧者 オブジェクトの閲覧と一覧だけ可
ストレージオブジェクト作成者 オブジェクトの作成だけ可
ストレージオブジェクト管理者 オブジェクトの操作はすべて可
ストレージ管理者 バケット・オブジェクト含めすべての操作が可
ストレージレガシーオブジェクト読み取り オブジェクトの閲覧だけ可
ストレージレガシーバケット読み取り オブジェクトの一覧だけ可
ストレージレガシーオブジェクトオーナー オブジェクトの閲覧と更新だけ可
ストレージレガシーバケット書き込み オブジェクトの作成・置き換え・削除と一覧だけ可
ストレージレガシーバケットオーナー オブジェクトの作成・置き換え・削除、バケットの操作が可

今回は特定のバケットへのすべての権限(閲覧、作成、更新、削除)を付与したいので、「ストレージオブジェクト管理者」を選びます。(プロジェクトレベルで設定するのではなくバケットレベルで設定するので、他のバケットにはアクセスできません。)

  1. ロールに「Storageオブジェクト管理者」を選んで保存します。


ロールを設定して保存

無事、サービスアカウント「sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com」にバケット「gcs-bucket-for-winscp」でのロール「Storageオブジェクト管理者」を付与することができました。


バケットに設定されたサービスアカウント

アクセスキーとシークレットキーの取得

最後にAmazon S3との互換モードのためにアクセスキーとシークレットキーを取得します。

  1. 画面左のメニューからギヤアイコンの「設定」を選択します。


「設定」を選択

  1. ページ上部の「相互運用性」タブをクリック


「相互運用性」を選択

  1. あとでWinSCPに設定するのでリクエストエンドポイントの「storage.googleapis.com」を覚えておきつつ、「サービスアカウントHMAC」のセクションにある「+サービスアカウント用にキーを作成」ボタンをクリックします。


サービスアカウント用にキーを作成

  1. 先に作成したサービスアカウント「sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com」を選んで「キーを作成」をクリック。


キーを作成

  1. 表示されたアクセスキーとシークレットキーをコピーして保存しておきます。(注意書きにもあるように、ここでメモしておかないと後で分からなくなります。)


アクセスキーとシークレットキーをメモ

これでGoogle Cloud側の準備は完了です。


サービスアカウントのアクセスキーが作成された

コマンドラインでの設定

ここまではCloud Consoleでの設定例を紹介しましたが、参考までにコマンドラインでの設定もまとめて紹介します。

サービスアカウントの作成
$ gcloud iam service-accounts create sa-for-winscp
Created service account [sa-for-winscp].
バケットの作成
$ gcloud storage buckets create gs://gcs-bucket-for-winscp \
      --enable-autoclass \
      --location=asia-northeast1 \
      --public-access-prevention \
      --uniform-bucket-level-access
Creating gs://gcs-bucket-for-winscp/...
サービスアカウントへの権限の付与
$ gcloud storage buckets add-iam-policy-binding gs://gcs-bucket-for-winscp \
      --member=serviceAccount:sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com \
      --role=roles/storage.objectAdmin
bindings:
(中略)
- members:
  - serviceAccount:sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com
  role: roles/storage.objectAdmin
etag: CAI=
kind: storage#policy
resourceId: projects/_/buckets/gcs-bucket-for-winscp
version: 1
アクセスキー/シークレットキーの作成
$ gsutil hmac create sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com
Access ID:   GOOG1EW...
Secret:      rXjNaF7...

gcloud storageコマンドが対応してなかったので、これだけgsutilコマンドです)

WinSCPの設定とアクセス

最後に以下の通りWinSCPの設定をします。

  • 転送プロトコル:Amazon S3
  • ホスト名:storage.googleapis.com(「相互運用性」のページに出てきた「リクエストエンドポイント」です)
  • ポート番号:443
  • アクセスキーID:(上でメモしたアクセスキー)
  • シークレットキー:(上でメモしたシークレットキー)


WinSCPの設定

これで設定を保存してさっそくアクセスをしたいところですが、実はこれでアクセスをすると次のようなエラーになります。


WinSCPのエラー

エラーをよく読むと「Details: sa-for-winscp@zenn-sample-project.iam.gserviceaccount.com does not have storage.buckets.list access to the Google Cloud project. Permission 'storage.buckets.list' denied on resource (or it may not exist).」と書かれていて、権限の問題のようです。

実はWinSCPはデフォルトでは接続後にバケットの一覧を表示しようとする(storage.buckets.list)のですが、今回設定した「ストレージオブジェクト管理者」は(その名の通り)オブジェクトの管理者なので、バケットを一覧する権限がなく、エラーになっています。

そこでWinSCPがバケットの一覧を表示しなくてすむように、作成したバケットに直接アクセスするように設定します。

WinSCPの設定画面の「設定」ボタンで「高度なサイトの設定」を開き、「環境 - ディレクトリ」の設定にある「リモートディレクトリ」に、今回作成したバケット「/gcs-bucket-for-winscp」を設定します。(/で始めるのがポイントです)


リモートディレクトリの設定

設定を保存して再度アクセスすると今度は無事アクセスできました。ファイルのアップロード、削除などを試して問題ないことを確認してください。


WinSCPでGCSへのアクセスが成功

おわりに

上に書いたように「相互運用性」の設定は一度おこなえばバケットごとに設定する必要はありません。アクセスキー/シークレットキーを安全に保管しておけば、他のバケットへのアクセスもサービスアカウントへのロールの付与で簡単にコントロールできます。(サービスアカウントへのロールの付与をプロジェクト単位でおこなえば、プロジェクト内のすべてのバケットに同じ権限でアクセスできます。)

WinSCP以外にもAmazon S3へのアクセスをサポートしているGUIのクライアントはあると思いますが、そういった使い慣れたクライアントを使ってGoogle Cloud Storageにもアクセスしたい場合は本記事を参考にしてもらえると幸いです。

Google Cloud Japan

Discussion