AWS Transfer FamilyのSFTPコネクタを使い、SFTPサーバーとAmazon S3間のファイル送信をやってみた

記事タイトルとURLをコピーする

こんにちは。ES課で研修中の深瀬です。

当記事では、SFTPコネクタを使いSFTPサーバーとAmazon S3間でファイルの送信ができることを確認します。

本記事はサーバーワークスAdvent Calendar 2024の13日目の記事です。 qiita.com

Transfer Family のSFTPコネクタとは

SFTPサーバーとAmazon S3間でファイルを送信することができるAWSのマネージドサービスです。 SFTPのやり取りが可能なサーバーであれば、プログラムは必要なく簡単にAmazon S3へファイルを送信できます。 データセンター内にあるサーバーのファイルをAmazon S3に送信することで、AWSで稼働しているシステムへのファイル連係や、データ分析、AIの学習などさまざまな用途で利用できます。

料金

東京リージョンでは以下の通りです。(2024/12/11現在)

料金 備考
コネクタコール当たりのコスト 0.001USD 次のSFTPコネクタAPIコマンドを使用する回数(※)
- StartFileTransfer API
- StartDirectoryListingAPI
- ListFIleTransferResults API
データ転送のGBあたりのコスト 0.40USD/送受信したGB

(※) 各APIコマンドについて

  • StartFileTransfer API
    • リモートSFTPサーバーとの間でファイル転送を行うためのAPIです。
  • StartDirectoryListing API
    • リモートSFTPサーバーのディレクトリのファイル一覧を表示します。
    • 1回の実行で最大1,000項目取得でき、1,000項目超えるごとに0.001USDが発生します。
  • ListFileTransferResults API
    • ファイル転送オペレーションの現在のステータスを表示します。

動作検証用の環境構築

動作検証を行うため、今回はAWS上にSFTPサーバーを構築します。 SFTPサーバーからAmazon S3、Amazon S3からSFTPサーバーにファイルが送信できることを確認します。

システム構成図

事前準備

以下を構築します。当記事では割愛します。

  • VPC、サブネット構築
  • EC2構築(Amazon Linux 2023,t3.mediumを使用)
  • セキュリティグループ設定(SFTPコネクタのIPアドレスからSSHを許可)
  • Amazon S3(設定はすべてデフォルト)

注意点は以下の通りです。

  • EC2をパブリックサブネットに配置するため、適切な設定を行わない場合、悪意あるユーザーに不正アクセスを受ける可能性があります。
  • 通信の向きは常にSFTPコネクタからSFTPサーバーになります。SFTPコネクタには静的IPアドレスが割り振られるため、SFTPコネクタのIPアドレスのみSSHを許可するセキュリティグループをSFTPサーバーに設定してください。

SFTPサーバーの設定

SFTPユーザーの作成

SFTPサーバーにSFTPユーザーを作成します。 SFTPサーバーの操作はAWS Systems Managerのセッションマネージャーを使用します。

$ sudo useradd sftpuser
$ sudo passwd sftpuser

SSHキーの作成

SFTPで使用するSSHキーを作成します。 なお、ssh-keygenでキーペアを作成する際、パスフレーズは設定しないでください。 SFTPコネクタの仕様上、パスフレーズは設定できません。

$ sudo su - sftpuser
$ mkdir .ssh
$ chmod 700 .ssh
$ cd .ssh

# 公開鍵/秘密鍵キーペア作成
$ ssh-keygen -t rsa -b 4096 -m PEM -f [キー名] -N ""

# 公開鍵をauthorized_keyに保存
$ cat [キー名].pub >> authorized_keys
$ chmod 600 authorized_keys

# 秘密鍵をメモ。Seacret Managerに保管するための形式で表示。
$ jq -sR . [キー名]

ホストキーの確認

接続先のSFTPサーバーを識別するため、ホストキーを確認します。

$ ssh-keyscan [SFTPサーバーのパブリックドメイン名]
# ドメイン名:22 SSH-2.0-OpenSSH_8.7
ドメイン名 ecdsa-sha2-nistp256 XXXXXXXXXXXXXXXXXXXX
# ドメイン名:22 SSH-2.0-OpenSSH_8.7
# ドメイン名:22 SSH-2.0-OpenSSH_8.7
ドメイン名 ssh-ed25519 XXXXXXXXXXXXXXXXXXXX
# ドメイン名:22 SSH-2.0-OpenSSH_8.7
# ドメイン名:22 SSH-2.0-OpenSSH_8.7

「ドメイン名 ecdsa-sha2-nistp256 XXXXXXXXXXXXXXXXXXXX」が今回使用するホストキーです。

シークレットの作成

AWS Secrets Managerを利用し、SFTPサーバーの情報を格納します。シークレットを作成する際、「Other type of secret」を選択し、「Key/value」ではなく「Plaintext」で以下を入力してください。

{"Username":"sftpuser","Password":"[sftpuserのパスワード]","PrivateKey":"SFTP用秘密鍵(jq -sRで出力した文字列)"}

SFTPコネクタ用IAMロールの作成

SFTPコネクタがAmazon S3とシークレットにアクセスできるよう、IAMロールを作成します。 まずはポリシーを作成します。

ポリシーの作成

ポリシー作成画面で以下のJSONを入力し、ポリシーを作成します。

{
  "Version": "2012-10-17",
  "Statement": [
    {
        "Sid": "AllowListingOfUserFolder",
        "Action": [
            "s3:ListBucket",
            "s3:GetBucketLocation"
        ],
        "Effect": "Allow",
        "Resource": [
            "arn:aws:s3:::[バケット名]"
        ]
    },
    {
        "Sid": "HomeDirObjectAccess",
        "Effect": "Allow",
        "Action": [
            "s3:PutObject",
            "s3:GetObject",
            "s3:DeleteObject",
            "s3:DeleteObjectVersion",
            "s3:GetObjectVersion",
            "s3:GetObjectACL",
            "s3:PutObjectACL"
        ],
        "Resource": "arn:aws:s3:::[バケット名]/*"
    },
    {
        "Sid": "GetConnectorSecretValue",
        "Effect": "Allow",
        "Action": [
            "secretsmanager:GetSecretValue"
        ],
        "Resource": "[シークレットのARN]"
    }
  ]
}

ロールの作成

次にロールを作成します。 Use Caseでは「Transfer」を選択します。

ポリシーの選択画面では、先ほど作成したポリシーを選択します。

SFTPコネクタの作成

AWS Transfer Familyコンソールを開き、左側のナビゲーションペインからConnectorsをクリックします。

「Create connector」をクリックします。

「SFTP」を選択し、「Next」をクリックします。

「Create Connector」では、以下の情報を入力し、「Create connector」をクリックします。

  • URL:sftp://[SFTPサーバーのパブリックドメイン名]:22
  • Role:前段で作成したロール名
  • Connector credentials:前段で作成したシークレット名
  • Trusted host keys:ssh-keyscanで確認したホストキー

作成されました。

セキュリティグループにSFTPコネクタ用の設定追加

SFTPコネクタのIPアドレスを確認します。

SFTPサーバーのセキュリティグループのインバウンドに、上記IPアドレスからのSSHを許可します。 ※手順は省略します。

動作検証

接続テスト(CloudShell)

接続テスト用コマンドをCloudShellで実行します。

$ aws transfer test-connection --region ap-northeast-1 --connector-id [Connector ID]
{
    "Status": "OK",
    "StatusMessage": "Connection succeeded"
}

問題ないようです。

SFTPサーバーからAmazon S3へファイル送信

SFTPサーバーにファイルを作成

SFTPサーバーにAmazon S3へのデータ転送用ファイルを作成します。

$ cd /home/sftpuser
$ mkdir sftptest
$ cd sftptest
$ echo "sftp server to s3" > sftpServerToS3.txt

SFTPサーバーのリストを作成(CloudShell)

Amazon S3にSFTPサーバーのリストを作成してみます。

aws transfer start-directory-listing --region ap-northeast-1 --connector-id [Connector ID] --remote-directory-path /home/sftpuser/sftptest --output-directory-path /[バケット名]
{
    "ListingId": "bcb30188-615c-44c1-9317-637a485b4a22",
    "OutputFileName": "c-b5319e1ecd0b4c9eb-bcb30188-615c-44c1-9317-637a485b4a22.json"
}

Amazon S3にOutputFileが作成されています。

OutputFileの内容は以下の通りです。

  "files" : [ {
    "filePath" : "/home/sftpuser/sftptest/sftpServerToS3.txt",
    "modifiedTimestamp" : "2024-12-11T08:25:09Z",
    "size" : 18
  } ],
  "paths" : [ ],
  "truncated" : false
}

SFTPサーバーからAmazon S3へのファイル送信(CloudShell)

SFTPサーバーで作成したファイルをAmazon S3に送信します。

$ aws transfer start-file-transfer --region ap-northeast-1 --connector-id [Connector ID] --retrieve-file-paths /home/sftpuser/sftptest/sftpServerToS3.txt --local-directory-path /[バケット名]
{
    "TransferId": "1ec7b444-559d-46a4-a5ea-1920593fd217"
}

転送結果

転送結果に問題がないことを確認します。

$ aws transfer list-file-transfer-results --region ap-northeast-1 --connector-id [Connector ID] --transfer-id 1ec7b444-559d-46a4-a5ea-1920593fd217
{
    "FileTransferResults": [
        {
            "FilePath": "/home/sftpuser/sftptest/sftpServerToS3.txt",
            "StatusCode": "COMPLETED"
        }
    ]
}

ファイルの確認

Amazon S3を確認します。

SFTPサーバーのファイルがAmazon S3に送信されていました!

ファイルの内容は以下の通りでした。

sftp server to s3

Amazon S3からSFTPサーバーへのファイル送信

Amazon S3にファイルを格納(Amazon S3)

SFTPサーバーへのデータ送信用に、Amazon S3にファイルを格納します。 ローカル端末でファイルを作成し、管理コンソールからアップロードします。(ファイル名:S3ToSftpServer.txt)

ファイルの内容は以下の通りです。

s3 to sftp server

Amazon S3からSFTPサーバーへのファイル送信(CloudShell)

Amazon S3からSFTPサーバーへファイルを送信します。

$ aws transfer start-file-transfer --region ap-northeast-1 --connector-id [Connector ID] --send-file-paths /[バケット名]/S3ToSftpServer.txt --remote-directory-path /home/sftpuser/sftptest
{
    "TransferId": "70ce5bb5-96b9-45e9-9c8a-0dae15161ac8"
}

転送結果

転送結果に問題がないことを確認します。

$ aws transfer list-file-transfer-results --region ap-northeast-1 --connector-id [Connector ID] --transfer-id 70ce5bb5-96b9-45e9-9c8a-0dae15161ac8
{
    "FileTransferResults": [
        {
            "FilePath": "/sftp-connect-test/S3ToSftpServer.txt",
            "StatusCode": "COMPLETED"
        }
    ]
}

ファイルの確認

SFTPサーバーにファイルが格納されていることを確認します。

$ ls -l
total 8
-rw-rw-r--. 1 sftpuser sftpuser 17 Dec 11 08:36 S3ToSftpServer.txt
-rw-r--r--. 1 sftpuser sftpuser 18 Dec 11 08:25 sftpServerToS3.txt
$ cat S3ToSftpServer.txt
s3 to sftp server

Amazon S3のファイルがSFTPサーバーに送信されていました!

まとめ

SFTPコネクタを使い、SFTPサーバーとAmazon S3間のファイル送信ができました。 検証する中でいくつかハマるポイントがありましたので、SFTPコネクタを利用したい方の参考になれば幸いです。

参考資料

AWS Transfer Family SFTP コネクタ - AWS Transfer Family

深瀬 義貴 (記事一覧)

エンタープライズクラウド部(ES課研修中)

キャンプがしたいです。