前提
・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の役割は何なのでしょうか?
もし想定が間違っている場合は、処理の流れをご教授頂けますと幸いです。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。