📂

aws login × WinSCPでWindows PCからAmazon S3へ接続!

に公開

はじめに

突然ですが、みなさんはAmazon S3をローカルのWindows PCから使いたいと思ったことはないでしょうか?
本記事では、aws loginコマンドとWinSCPを組み合わせて、非エンジニアでもお手軽にS3を利用する方法を考えたので紹介していきます。

既存の選択肢について

はじめにWindows PCからAmazon S3を使用するにあたって、いくつかの選択肢があります。
が、それぞれ課題があります。

1. AWS Transfer Family Web App

  • 課題: 高額な費用
    • Transfer Family Web Appの料金: $0.50/時間
    • 月額換算: $0.50 × 24時間 × 30日 = 約$360/月(約54,000円/月)

小規模利用にはかなり割高な金額となってしまいます。

2. Storage Gateway - SMBマウント

  • 課題: 高額な費用 + 運用コスト
    • EC2インスタンス(m5.xlarge必須): $181/月
    • Storage Gateway料金: 最大$125/月
    • EBSボリューム(150GB): 約$14/月
    • 月額合計: 約$320/月(約48,000円/月)

こちらも高額な費用に加え、インスタンスの監視・パッチ適用などの運用負荷が発生します。

3. Linux環境 + Mountpoint for Amazon S3

  • 課題: Linux環境の管理コスト

UbuntuなどのLinux環境を別途用意・管理する必要になります。

4. サードパーティのマウントソフトウェア

  • 課題: ライセンス料

商用ソフトウェアのライセンス料が発生してしまいます。

WinSCPに着目

違う!高い!!もっとシンプルかつ安価に利用できる手段があるはずだ!!!
そこで注目したのが、Windows PCで広く使われているFTPクライアントWinSCPです。

WinSCPのメリット・デメリット

まずはWinSCPのメリット・デメリットを整理します

メリット

  • 無料のオープンソースソフトウェアである
  • Amazon S3に対応している
  • 使い慣れたGUIで直感的に操作できる

デメリット

  • アクセスキー・シークレットアクセスキーを発行する必要がある

一時的な認証情報を使用するために

WinSCPがAmazon S3の接続に対応しているのはよいのですが、アクセスキー・シークレットアクセスキーを発行する必要があるのは大きなデメリットです。

WinSCP新規接続画面WinSCPによるS3接続画面

そこでaws loginコマンドの登場です。
aws loginコマンドを使用した処理にすることで、グラフィカルなインターフェースで一時的な認証情報の取得が可能になります。

aws login

作ってみる

前提条件

  1. Amazon S3バケットが作成済みであること。
  2. WinSCPがインストール済みであること。
  3. Windows PCにAWS CLI(v2.32.0以上)がインストール済みであること。

1. IAMユーザーの作成

  1. 以下のIAMポリシーを付与したユーザーを作成します。
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::<S3バケット名>"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:Put*",
                "s3:Get*",
                "s3:Delete*"
            ],
            "Resource": "arn:aws:s3:::<S3バケット名>/*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "signin:AuthorizeOAuth2Access",
                "signin:CreateOAuth2Token"
            ],
            "Resource": "arn:aws:signin:<リージョン名>:<アカウントID>:oauth2/publicclient/*"
        }
    ]
}


  • 注意: aws loginコマンドには以下のステートメントが必要になるのでお忘れなく。
        {
            "Effect": "Allow",
            "Action": [
                "signin:AuthorizeOAuth2Access",
                "signin:CreateOAuth2Token"
            ],
            "Resource": "arn:aws:signin:<リージョン名>:<アカウントID>:oauth2/publicclient/*"
        }


2. ~/.aws/configファイルの作成

  1. ~/.aws/configファイルファイルに先程作成したIAMユーザーのARNを記載します。
[default]
login_session = <IAMユーザーARN>
region = ap-northeast-1

3. batファイルの作成

  1. batファイルを作成していきます。
@echo off
setlocal

REM 変数設定
set S3_BUCKET=<S3バケット名>
set WINSCP_PATH=C:\Program Files (x86)\WinSCP\WinSCP.exe
set AWS_PROFILE=default
set SESSION_NAME=S3Session

echo AWS WinSCP Startup Launcher

REM AWS認証
echo Authenticating with AWS...
call aws login --profile %AWS_PROFILE% || (echo ERROR: AWS login failed & pause & exit /b 1)

REM 認証情報取得
echo Retrieving credentials...
set CREDS_FILE=%USERPROFILE%\.aws\login\cache\aws_creds.json
aws configure export-credentials --profile %AWS_PROFILE% > "%CREDS_FILE%"

for /f "delims=" %%i in ('powershell -NoProfile -Command "(Get-Content '%CREDS_FILE%' | ConvertFrom-Json).AccessKeyId"') do set ACCESS_KEY=%%i
for /f "delims=" %%i in ('powershell -NoProfile -Command "(Get-Content '%CREDS_FILE%' | ConvertFrom-Json).SecretAccessKey"') do set SECRET_KEY=%%i
for /f "delims=" %%i in ('powershell -NoProfile -Command "(Get-Content '%CREDS_FILE%' | ConvertFrom-Json).SessionToken"') do set SESSION_TOKEN=%%i

REM 一時ファイル削除
del /f /q "%CREDS_FILE%"

if not defined ACCESS_KEY (echo ERROR: Failed to retrieve credentials & pause & exit /b 1)

REM WinSCP設定生成
set INI_FILE=%TEMP%\WinSCP.ini
(
echo [Configuration\Interface]
echo Interface=1
echo ConfirmClosingSession=0
echo ConfirmExitOnCompletion=0
echo [Sessions\%SESSION_NAME%]
echo HostName=s3.amazonaws.com
echo PortNumber=443
echo UserName=%ACCESS_KEY%
echo PasswordPlain=%SECRET_KEY%
echo S3SessionToken=%SESSION_TOKEN%
echo FSProtocol=7
echo RemoteDirectory=/%S3_BUCKET%
echo Ftps=1
) > "%INI_FILE%"

REM WinSCP起動
echo Starting WinSCP...
start "" "%WINSCP_PATH%" /ini="%INI_FILE%" %SESSION_NAME%

REM 5秒後にINIファイルを削除
echo Waiting 5 seconds before cleaning up INI file...
timeout /t 5 /nobreak >nul
del /f /q "%INI_FILE%" 2>nul

echo WinSCP launched successfully.

endlocal

  • わずか60行程度で書けました!

batファイルの処理について

ここでは以下の処理を実行しています。

  1. aws loginコマンドによる認証を実行(ブラウザで起動)
  2. 一時認証情報(AccessKey、SecretKey、SessionToken)を取得
  3. WinSCP用の設定ファイル(INI形式)を生成
  4. WinSCPを起動してS3バケットに接続

スクリプトについて

スクリプトについての詳細

1. 設定部分

set S3_BUCKET=<S3バケット名>
set WINSCP_PATH=C:\Program Files (x86)\WinSCP\WinSCP.exe
set AWS_PROFILE=default
set SESSION_NAME=S3Session
  • 接続先のS3バケット名とWinSCPのインストールパスを指定
  • 使用するAWSプロファイル名を指定
  • WinSCPセッション名を指定

2. AWS IAMユーザー認証

call aws login --profile %AWS_PROFILE%
  • aws loginでブラウザベースの認証を実行
  • 指定したプロファイルで認証

3. 一時認証情報の取得

set CREDS_FILE=%USERPROFILE%\.aws\login\cache\aws_creds.json
aws configure export-credentials --profile %AWS_PROFILE% > "%CREDS_FILE%"
  • AWS CLIで一時認証情報をJSON形式で出力
  • %USERPROFILE%\.aws\login\cache\にキャッシュファイルを保存
  • PowerShellでJSONをパースして各値を環境変数に格納
  • 取得後、一時ファイルは即座に削除

4. WinSCP設定ファイルの生成

echo S3SessionToken=%SESSION_TOKEN%
echo FSProtocol=7
  • セッショントークンを含む設定を動的に生成
  • FSProtocol=7はS3プロトコルを指定

5. WinSCP起動とINIファイルの削除

start "" "%WINSCP_PATH%" /ini="%INI_FILE%" %SESSION_NAME%
timeout /t 5 /nobreak >nul
del /f /q "%INI_FILE%" 2>nul
  • 生成した設定ファイルを使ってWinSCPを起動
  • 変数で指定したセッション名で接続
  • WinSCP起動後、5秒待機してからINIファイルを削除
  • 認証情報を含むINIファイルがディスクに残らないようにする

使ってみた

  1. 作成したbatファイルのショートカットをデスクトップに配置してダブルクリックします。
  • winscp_startup.batという名前のファイルのショートカットを作成しています。

デスクトップ


  1. コマンドプロンプトが起動し、処理が開始されました。

コマンドプロンプト


  1. aws loginコマンドによりWEBブラウザで認証画面が起動しました。先程作成したIAMユーザーでサインインします。

コンソールの起動


  • サインインに成功です。

サインイン成功


  1. S3バケットに接続した状態でWinSCPが起動しました。

WinSCP起動


  1. ここからは検証です。適当なファイルをドラッグアンドドロップしてアップロードしてみます。

アップロード中


  1. アップロードに成功しました。

アップロード後


  • ちゃんとS3コンソールでも確認できます。

S3コンソール画面


その他

一時認証情報の有効期限

WinSCPでの操作時間は約15分に制限されます。

aws loginコマンドで取得される一時認証情報は、AWS CLIやSDKでは15分ごとに自動的にリフレッシュされますが、WinSCPには自動リフレッシュ機能がありません。
そのため、最初に取得した認証情報が期限切れになる約15分後には、WinSCPでの操作ができなくなります。バッチファイルを再実行が必要です。

参考: AWS CLI公式ドキュメント - Login for AWS local development

バッチファイルの拡張性

変数設定により各設定がカスタマイズ可能です。

REM 変数設定
set S3_BUCKET=<S3バケット名>    # 接続先バケット名
set WINSCP_PATH=C:\Program Files (x86)\WinSCP\WinSCP.exe  # WinSCPのパス
set AWS_PROFILE=default               # 使用するAWSプロファイル
set SESSION_NAME=S3Session            # WinSCPセッション名

おわりに

  • ここまで読んでいただいた皆さんは「あれ、結局Boxみたいなサービスが欲しいの?」とお思いでしょうが...結論、その通りです!!
  • 個人的に安価で非エンジニアでも直感的に操作できるS3のインターフェースの登場に期待してます。もしくはMountPoint for Amazon S3がWindowsにも対応して頂けるとありがたいです。
  • aws loginコマンドは、これまでアクセスキーの発行が必須だったサードパーティツールへのグラフィカルな認証手段として活用できるのではないかと期待しています。

Discussion