Google Cloud Storage を利用した FTP サーバーを構築し、安全にファイルを共有する方法
はじめに
このブログ記事では、Google Cloud を利用して FTP サーバーを構築し、ファイルを安全に共有する方法を説明します。この方法では、Cloud Storage バケット、Compute Engine インスタンス、vsftpd、nginx、Identity-Aware Proxy(IAP) を組み合わせることで、以下の要件を満たすことができます。
- ファイルの公開範囲を制御
- 特定のユーザーのみがファイルにアクセスできるように制限できます
- 安全なファイル転送
- SFTPなどでファイル転送を暗号化することができます
- 使いやすさ
- FTP クライアントを使用してファイルを簡単にアップロードおよびダウンロードできます
構成イメージ
- FTP サーバー(Compute Engine)とストレージ(Cloud Storage)
- Web サーバー(Cloud Run)とストレージ(Cloud Storage)および認証(IAP)
手順
1. Cloud Storage でバケットを作成
Google Cloud Storage でバケットを作成します。このバケットには、FTP サーバーで共有するファイルを格納します。バケットを作成する際には、公開アクセス防止を削除 を選択して、バケットを公開可能な状態とし、すべてのユーザー(allusers) にStorageオブジェクト閲覧者のアクセス権を付与します。
バケット名は任意ですが、一時的に公開されることを考慮して今回は特定されにくいランダムな文字列の最大桁数63文字で作成します。これはバケットの公開 URL が、「storage.googleapis.com/バケット名/ファイル名」で推測されやすいためです。
2. Compute Engine インスタンスを作成
Compute Engine インスタンスを作成します。このインスタンスは、FTP サーバーとして機能します。
権限については、最低限の権限を持つサービスアカウントを作成して設定することをお勧めしますが、今回はアクセススコープにてAPI ごとにアクセス権を設定します。
インスタンス設定
- マシンの構成:e2-micro
- OS:dbian
- 権限:アクセススコープ - API ごとにアクセス権を設定 - ストレージ - フル
- ネットワーク タグ:ftp-server
ファイアウォールルール
- 名前:任意
- ターゲットタグ:ftp-server
- トラフィックの方向:上り
- IP範囲:0.0.0.0/0
- 指定したプロトコル:TCP
- 指定したポート:21,10000-10009
3. Compute Engine に vsftpd をインストール
Compute Engine インスタンスに vsftpd をインストールします。 vsftpd は、FTP サーバーとして動作するソフトウェアです。
sudo apt-get update
sudo apt -y install vsftpd
4. vsftpd を構成
vsftpd を構成して、Cloud Storage バケットをマウントしたディレクトリを共有するように設定します。今回はFTPで構成してしまっていますが、SFTPなどでファイル転送を暗号化した方が良いです。
vsftp.conf 設定
- コメント解除
- chroot_local_user=YES
- chroot_list_enable=YES
- chroot_list_file=/etc/vsftpd.chroot_list
- ls_recurse_enable=YES
- write_enable=YES
- ascii_upload_enable=YES
- ascii_download_enable=YES
- 値変更
- listen=YES
- listen_ipv6=NO
- パッシブモード追加
- pasv_enable=YES
- pasv_addr_resolve=YES
- pasv_address=localhost #外部IPアドレスなど
- pasv_min_port=10000
- pasv_max_port=10009
- pasv_promiscuous=YES
テストユーザー作成
sudo adduser testftp
ユーザーを許可
sudo echo 'testftp' | sudo tee -a /etc/vsftpd.chroot_list
5. Compute Engine に gcsfuse をインストール
Compute Engine インスタンスに Cloud Storage FUSE(gcsfuse) をインストールします。 gcsfuse は、Cloud Storage バケットをローカルのファイルシステムのようにマウントできるツールです。
-
gcsfuse インストール
- 上記リンクの手順に沿って gcsfuse をインストールします
-
gcsfuse マウント
- マウントの際、FTPユーザーを指定することでFTPクライアントからファイルを読み書きできます
gcsfuse --uid testftp --gid testftp -o allow_other --implicit-dirs $BUCKET_NAME /home/testftp/
6. FTP クライアントからファイルをアップロード
FTP クライアントを使用して、ファイルを Compute Engine インスタンスにアップロードします。アップロードしたファイルは、gcsfuse によって自動的に Cloud Storage バケットに同期されます。ファイルは以下の簡単なHTMLファイルとします。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
Hello, World!
</body>
</html>
7. ファイルの確認
Cloud Storage バケットにファイルがアップロードされていることを確認します。また、公開設定により、誰でもファイルにアクセスできることも確認します。
セキュリティを強化
上記の方法はファイルを公開する方法として有効ですが、セキュリティ面では十分ではありません。ファイルをより安全に共有するには、以下の対策を追加することをお勧めします。
8. 公開バケットの停止
セキュリティを強化するために、公開アクセスの防止を選択します。
この結果、先ほどまでアクセスできていたファイルにはアクセスできなくなります。
9. Cloud Run と gcsfuse を利用した Web サーバー
Cloud Run は、サーバーレスコンピュートプラットフォームです。 gcsfuse を使用して Cloud Storage バケットを Cloud Run コンテナにマウントし、Nginx などの Web サーバーソフトウェアを使用してファイルを公開することができます。
- Cloud Storage ボリュームのマウントの構成
- Cloud Run デプロイコマンドのサンプル
gcloud beta run deploy $SERVICE_NAME \
--image nginx \
--port=80 \
--region=us-central1 \
--execution-environment=gen2 \
--add-volume=name=gcs,type=cloud-storage,bucket=$BUCKET_NAME,readonly=true \
--add-volume-mount=volume=gcs,mount-path=/$MOUNT_PATH
10. 外部ロードバランサーと Identity-Aware Proxy(IAP)
クライアントと Web サーバーの間に外部ロードバランサーを配置することで、可用性とスケーラビリティを向上させることができます。さらに IAP を使用して Web サーバーへのアクセスを許可するユーザーを制限することができます。
- IAP の OAuth クライアントの作成
- OAuth 構成をカスタマイズして IAP を有効にする
- IAP for Cloud Run の有効化
- アプリケーション ロードバランサを設定する
- 外部 HTTP(S) ロードバランサで IAP を有効にする
11. ファイルへのアクセス制御を確認
ロードバランサーを設置したためファイルの URL が変わりますが、IAP で有効なユーザーでログインした状態であるとファイルにアクセスすることができ、そうでないと拒否されるようになりました。
- ログイン画面
- 有効なユーザーのログインを許可
- 無効なユーザーのログインを拒否
そのほかのセキュリティ強化方法
今回は IAP を試したかったため採用していませんが、そのほかのセキュリティ強化方法としては以下のような方法があります。
VPC Servive Controls と Access Context Manager
組織レベルで VPC ネットワーク上にサービス境界を作成し、API ベースのサービスに IPアドレスでのアクセス制限をかける方法です。Cloud Storage は API ベースのサービスなのでこの方法が利用できます。
Cloud CDN と Cloud Armor エッジ セキュリティ ポリシー
外部ロードバランサーのバックエンドバケットに Cloud CDN と Cloud Armor エッジセキュリティポリシーを利用することで、バケットの公開範囲を許可IPで制限した状態にすることができます。ただ、取得したいオブジェクトの認証済み URL を予め知っている必要があります。
Cloud CDN と 署名付きCookie
外部ロードバランサーのバックエンドバケットに署名付きCookieで通信するCDNを設定します。署名付きCookieを発行する認証サーバーをCloud Runなどで作成します。Basic 認証のような簡易な認証でよければこの方法でも良さそうです。
Cloud Run の認証
Cloud IAM を使用して承認済みユーザーを管理します。
Basic 認証
IAPなどで認証するまでもないが、何らかの認証は欲しいとき。Cloud Storage に「.htpasswd」のファイルを置いて、Cloud Run にある Nginx などの Web サーバーソフトウェアを使用して、Basic認証を設定します。
さいごに
Google Cloud Storage を利用した FTP サーバーは思ったよりも簡単に構築することができました。しかし、セキュリティ対策を怠ると、データ漏洩などのリスクがあります。今回はできませんでしたが FTP サーバーにも追加のセキュリティ対策が必要です。
Cloud Storage へは直接ファイルをアップロードできる方法が幾つかあります。どうしても FTP でないとダメというわけではないのであれば、別の方法をとりましょう。
また、Cloud Storage で共有したいファイルの性質にもよりますが、基本的には公開バケットの使用は避け、IAM や Cloud Armor、IAP と Cloud Run の組み合わせなどの方法でアクセスを制限することがリスク回避となります。
Discussion