質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.46%
AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

Q&A

解決済

1回答

2795閲覧

Transfer family for FTPのlambdaの認証について

suzunashi

総合スコア16

AWS Lambda

AWS Lambdaは、クラウド上でアプリを実行できるコンピューティングサービス。サーバーのプロビジョニングや管理を要せず複数のイベントに対してコードを実行します。カスタムロジック用いた他AWSサービスの拡張やAWSの規模やパフォーマンスを用いたバックエンドサービスを作成できます。

AWS(Amazon Web Services)

Amazon Web Services (AWS)は、仮想空間を機軸とした、クラスター状のコンピュータ・ネットワーク・データベース・ストーレッジ・サポートツールをAWSというインフラから提供する商用サービスです。

0グッド

0クリップ

投稿2021/11/06 18:53

前提

・Transfer family for FTPを作成しS3にアクセスする事を想定。

・IDプロバイダーはカスタムを設定。

・IDプロバイダはcloudformationで作成し、下記テンプレートを使用。
https://s3.amazonaws.com/aws-transfer-resources/custom-idp-templates/aws-transfer-custom-idp-secrets-manager-apig.template.yml

lambdaコード

Cloudformationで作成されるlambdaのコードは下記です。
ユーザー名などはSecret managerで保存されています。

python

1import os 2import json 3import boto3 4import base64 5from botocore.exceptions import ClientError 6 7def lambda_handler(event, context): 8 resp_data = {} 9 10 if 'username' not in event or 'serverId' not in event: 11 print("Incoming username or serverId missing - Unexpected") 12 return response_data 13 14 # It is recommended to verify server ID against some value, this template does not verify server ID 15 input_username = event['username'] 16 print("Username: {}, ServerId: {}".format(input_username, event['serverId'])); 17 18 if 'password' in event: 19 input_password = event['password'] 20 if input_password == '' and (event['protocol'] == 'FTP' or event['protocol'] == 'FTPS'): 21 print("Empty password not allowed") 22 return response_data 23 else: 24 print("No password, checking for SSH public key") 25 input_password = '' 26 27 # Lookup user's secret which can contain the password or SSH public keys 28 resp = get_secret("SFTP/" + input_username) 29 30 if resp != None: 31 resp_dict = json.loads(resp) 32 else: 33 print("Secrets Manager exception thrown") 34 return {} 35 36 if input_password != '': 37 if 'Password' in resp_dict: 38 resp_password = resp_dict['Password'] 39 else: 40 print("Unable to authenticate user - No field match in Secret for password") 41 return {} 42 43 if resp_password != input_password: 44 print("Unable to authenticate user - Incoming password does not match stored") 45 return {} 46 else: 47 # SSH Public Key Auth Flow - The incoming password was empty so we are trying ssh auth and need to return the public key data if we have it 48 # この部分は不要 49 # if 'PublicKey' in resp_dict: 50 # resp_data['PublicKeys'] = [resp_dict['PublicKey']] 51 # else: 52 # print("Unable to authenticate user - No public keys found") 53 # return {} 54 55 # If we've got this far then we've either authenticated the user by password or we're using SSH public key auth and 56 # we've begun constructing the data response. Check for each key value pair. 57 # These are required so set to empty string if missing 58 if 'Role' in resp_dict: 59 resp_data['Role'] = resp_dict['Role'] 60 else: 61 print("No field match for role - Set empty string in response") 62 resp_data['Role'] = '' 63 64 # These are optional so ignore if not present 65 if 'Policy' in resp_dict: 66 resp_data['Policy'] = resp_dict['Policy'] 67 68 if 'HomeDirectoryDetails' in resp_dict: 69 print("HomeDirectoryDetails found - Applying setting for virtual folders") 70 resp_data['HomeDirectoryDetails'] = resp_dict['HomeDirectoryDetails'] 71 resp_data['HomeDirectoryType'] = "LOGICAL" 72 elif 'HomeDirectory' in resp_dict: 73 print("HomeDirectory found - Cannot be used with HomeDirectoryDetails") 74 resp_data['HomeDirectory'] = resp_dict['HomeDirectory'] 75 else: 76 print("HomeDirectory not found - Defaulting to /") 77 78 print("Completed Response Data: "+json.dumps(resp_data)) 79 return resp_data 80 81def get_secret(id): 82 region = os.environ['SecretsManagerRegion'] 83 print("Secrets Manager Region: "+region) 84 85 client = boto3.session.Session().client(service_name='secretsmanager', region_name=region) 86 87 try: 88 resp = client.get_secret_value(SecretId=id) 89 # Decrypts secret using the associated KMS CMK. 90 # Depending on whether the secret is a string or binary, one of these fields will be populated. 91 if 'SecretString' in resp: 92 print("Found Secret String") 93 return resp['SecretString'] 94 else: 95 print("Found Binary Secret") 96 return base64.b64decode(resp['SecretBinary']) 97 except ClientError as err: 98 print('Error Talking to SecretsManager: ' + err.response['Error']['Code'] + ', Message: ' + str(err)) 99 return None 100

SFTPでIDプロバイダにサービスマネージドを選択した場合

上記の前提ではなく、SFTPで作成する場合はSFTPユーザーを作成し、SFTPユーザーにS3にアクセスを許可してIAMロールを付与しているので下記の様な流れかと思っています。

1.PCからSFTPサーバにアクセス。
ユーザ名やSSHキーを送信。
2.SFTPサーバで認証し、追加したSFTPユーザーからS3にアクセス。
SFTPユーザーにはS3へのアクセスを許可したロールを付与している。

このようにアクセスするユーザー自体にロールを付与しているので、ユーザがS3にアクセスできているのは理解できます。

FTPでIDプロバイダにカスタムを選択した場合

#####想定している処理①
1.PCからFTPサーバにアクセス。
ユーザ名とパスワードを送信

2.API Gatewayからlambdaで認証し、問題なければFTPサーバにS3へのアクセスを許可したロールを付与。

3.FTPサーバがS3へアクセス。

ただ、この場合上記のlambdaのコード内にはSecret Managerに保存されている情報との比較のみのコードしかないと思うのですが、どこでロールを付与しているのかが分かりません。

#####想定している処理②
1.PCからFTPサーバにアクセス。
ユーザ名とパスワードを送信

2.予めFTPサーバにS3へのアクセスを許可したロールを付与しており、
その情報と送信されたユーザ名パスワードでlambdaが認証。

3.問題なければS3へアクセス

この場合は、FTPサーバは初めからS3へアクセスするロールを持っておりlambdaから送られる情報が無いので、
lambdaの役割が理解できません。

質問

私の想定している様な処理であっていますでしょうか。
①場合はどこでS3アクセスを許可したロールを付与しているのでしょうか?
②場合はlambdaの役割は何なのでしょうか?

もし想定が間違っている場合は、処理の流れをご教授頂けますと幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

自己解決しました。

想定している処理①の方法で処理が行われており、resp_dataにroleの情報などを格納し、レスポンスとして返す事でs3アクセスのロールを付与しているのだと理解できました。

投稿2021/11/08 05:10

suzunashi

総合スコア16

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.46%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問