AWS Transfer Family のカスタムIDプロバイダーで AWS Secrets Manager を使用して パスワード認証を有効にしてみる

パスワード認証でS3にSFTPする
2021.06.03

はじめに

おはようございます、もきゅりんです。

皆さん、SFTP してますか?

お手軽にS3にいろんなプロトコルでファイルアップロードできちゃう AWS Transfer Family って素敵ですよねえ。

そんな AWS Transfer Family のユーザー管理には3つのタイプがあります。

  1. AWS Transfer Familyのサービス管理
  2. AWS Directory Service for Microsoft Active Directory (AD管理)
  3. カスタム ID プロバイダー

さらにカスタムIDプロバイダーでは、APIGatewayを使って SecretsManager と連携したパスワード/SSHキー認証、 Oktaと連携したパスワード認証が可能です。

詳細は、カスタム ID プロバイダーの使用 - AWS Transfer Family を参照下さい。

本稿では、Enable password authentication for AWS Transfer Family using AWS Secrets Manager (updated) | AWS Storage Blog を元に APIGatewayを使ってSecretsManagerと連携したパスワード/SSHキー認証を設定してみます。

上記は、2019年5月のAWS ブログ AWS Secrets Manager を使用して AWS Transfer for SFTP のパスワード認証を有効にする が更新されたものです。

なお、このブログを元に、弊社ブログに AWS Transfer for SFTP でパスワード認証と論理ディレクトリをやってみた | DevelopersIO もあります。

更新されたブログでは以下が追加されています。

  • 論理ディレクトリマッピング (このブログとは別に2019年9月に更新されていますが)
  • 個々のユーザーのオプションのクライアントソース IP アドレスチェック
  • FTP/FTPS ユーザー向けの独立したパスワードとロールのサポート

本稿では、上2つを使ってみて接続を行います。

やること

  1. カスタムIDプロバイダーおよびSFTPサーバの構築
  2. SecretsManagerでユーザー作成
  3. 確認

前提条件

構成図

下図は各エンドポイントの構成イメージになります。

PUBLIC

PUBLIC_architecture

VPC

VPC_architecture

今回は PUBLIC を選択します。

構築

ここからDLしてSAMテンプレートで構築します。

なお、Lambda関数なのですが、このままブログに書かれている通りに設定しても想定通りに動かないので要注意です。

input_protocol + key, かつ AcceptedIpNetwork という変数でIPアドレスチェックしているため、 SecretsManager に AcceptedIpNetwork で登録してコード修正するなり、 SecretsManager に ${PROTOCOL}AcceptedIPNetwork にしてコード修正するなりの対応が必要です。

SecretsMangerに SFTPAcceptedIPNetworkで登録することにして、AcceptedIpNetwork を AcceptedIPNetwork に修正してデプロイします。

def check_ipaddress(secret_dict, input_sourceIp, input_protocol):
#    accepted_ip_network = lookup(secret_dict, "AcceptedIpNetwork", input_protocol)
	  accepted_ip_network = lookup(secret_dict, "AcceptedIPNetwork", input_protocol)

ブログに記載されている通りですが、sam deploy –guided すると、以下の情報を求めるプロンプトが表示されます。

サブネットID, VPC IDは、VPC デプロイを使用する場合にのみ必要です。

VPCで作成すると、default のセキュリティグループが VPC エンドポイントに割り当てられます。

 Setting default arguments for 'sam deploy'
 =========================================
 Stack Name [sam-app]: 
 AWS Region [ap-northeast-1]: 
 Parameter CreateServer [true]: 
 Parameter SecretsManagerRegion []: ap-northeast-1
 Parameter TransferEndpointType [PUBLIC]: 
 Parameter TransferSubnetIDs []: subnet-xxxxxx,subnet-xxxxxxxx
 Parameter TransferVPCID []: vpc-0xxxxxxxxxxxxx

SecretsManagerで Secret を作成

Roleは、今回使い捨てのため AWS管理ポリシーの AmazonS3FullAccess で作成します。サービスはもちろん Transfer です。(実利用時は、適切に制限を設けた Role を作成しましょう。)

各種、キー/バリュー を追加します。

SecretsMangerParameters

シークレット名は serverId/username です。

Secret

確認

IDプロバイダーのテストをコンソールおよびCLIでできます。

IdP_test

aws transfer test-identity-provider --server-id "s-xxxxxxxxxxxx" --user-name ${USERNAME} --user-password ${PASSWORD} --source-ip "192.168.1.1" --server-protocol "SFTP"

わざと異なるIPレンジからアクセスしてみると、以下のような Transfer Familyのログが CloudWatchLogs に出力されます。

sftp username@s-xxxxxxxxx.server.transfer.ap-northeast-1.amazonaws.com

(VPCからアクセスする場合は、VPCエンドポイントのDNS名を@以降に使います)

ERRORS AUTH_FAILURE Method=password User=USERNAME Message= SourceIP=xx.xx.xx.xx

SSHキー認証でもパブリックキーを追加していれば接続可能です。

sftp -i .ssh/hogehoge.pem USERNAME@s-xxxxxxxx.server.transfer.ap-northeast-1.amazonaws.com

現状、S3フルアクセスポリシーかつホーム指定する設定を何もしていないため、S3のリソースを見放題なのですが、実際はそのような状況を望まないはずです。

ふたたび 下記形式で SecretsManagerで論理ディレクトリ HomeDirectoryDetails を設定することでルートを変更することが出来ます。

HomeDirectoryDetails: [{"Entry": "/", "Target": "/bucketname/myhomedirectory"}]

logical_directory

なお、論理ディレクトリを利用する場合は HomeDirectory は使えません。(逆も然りですので注意です。)

これで、無事ルート変更されて不要なバケットやファイルは見えないかと思います。

さいごに

カスタムIDプロバイダーでは、各人の公開鍵管理に比べて管理が統一されており、各ユーザごとのパスワード認証やIAMロール、IP制限など(FTP/FTPS ユーザー向けに独立したパスワードとロールのサポートもする)、柔軟に設定ができるかと思います。

ただ、SecretsManager, APIGateway, Lambdaのコードなど管理するリソースが増えてくるため、想定される利用環境で設定が必要かどうかご検討すると良いでしょう。

参考