Transfer Family のカスタム ID プロバイダー(Lambda)で、ホームディレクトリを任意のディレクトリに設定する方法を教えてください

2022.08.15

困っていた内容

Transfer Family で、Lambda を利用してカスタム ID プロバイダーの設定をしています。
Transfer Family サーバーの作成などには、ドキュメントで紹介されているクラシック (Cognito) スタックテンプレートを利用しました。
SFTP 接続時、S3 のルートディレクトリに移動します。
接続時のディレクトリを任意のディレクトリに設定したいのですが、どのように設定をしたらよいでしょうか。

接続時のディレクトリを変更する方法

Lambda で返却する値を変更してください。

ドキュメントで紹介されているクラシック (Cognito) スタックテンプレートの場合、デフォルトの Lambda では以下の内容が返却されます。

{
  "Role": xxx,
  "Policy": xxx,
  "HomeDirectoryType": "LOGICAL",
  "HomeDirectoryDetails": "[{\"Entry\": \"/${userName}\", \"Target\": \"/${BucketName}/${userName}\"}, (省略)]"
}

※ ${userName}:実際のユーザー名、${BucketName}:S3 バケット名です。

上記の Lambda から返却される内容を変更することで、接続時のディレクトリを変更できます。
以下では、 2 つの方法を記載します。

HomeDirectory を利用する方法

Lambda から返却される内容が以下の場合、接続時のディレクトリが HomeDirectory 記載のディレクトリとなります。

{
  "Role": xxx,
  "Policy": xxx,
  "HomeDirectory": "${BucketName}/something/path"
}

接続時、カレントディレクトリを確認した結果は以下となり、HomeDirectory に指定したディレクトリであることが分かります。

sftp> pwd
Remote working directory: /${BucketName}/something/path

HomeDirectoryType LOGICAL で論理ディレクトリを利用する方法

Lambda から返却される内容が以下の場合、接続時のディレクトリが Target で指定したディレクトリとなります。

{
  "Role": xxx,
  "Policy": xxx,
  "HomeDirectoryType": "LOGICAL",
  "HomeDirectoryDetails": "[{\"Entry\": \"/\", \"Target\": \"/${BucketName}/something/path\"]"
}

※ Entry が / の場合、HomeDirectoryDetails で指定できるマッピングは 1 つのみです。

接続時、カレントディレクトリを確認するとルートディレクトリが表示されますが、実際は Target に指定したディレクトリとなります。
以下のように、ls コマンドなどで Target に指定したディレクトリに存在するデータがあるかご確認ください。

sftp> pwd
Remote working directory: /
sftp> ls -al
-rwxr--r--   1        -        -        0 Aug  9 12:03 hello.txt

上記の設定時にエラーが発生した際のトラブルシューティング

  • Lambda で返却される内容をログ出力し、その内容を確認する
  • Transfer Family サーバーのログを確認する

両方とも CloudWatch Logs から確認できます。

Lambda:/aws/lambda/${LambdaName}
Transfer Family:/aws/transfer/${ServerId}

参考資料

カスタム ID プロバイダーの使用

論理ディレクトリを使用して Transfer Family ディレクトリ構造を簡素化する

Simplify your AWS SFTP Structure with chroot and logical directories

AWS Transfer for SFTP で接続に関するエラーメッセージと対処方法をまとめてみた