ID AWS Lambda 제공자를 통합하는 데 사용 - AWS Transfer Family

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

ID AWS Lambda 제공자를 통합하는 데 사용

사용자 지정 ID 공급자에 연결하는 AWS Lambda 함수를 만드세요. Okta, Secrets Manager와 같은 사용자 지정 ID 공급자를 사용하거나 권한 부여 및 인증 로직이 포함된 사용자 지정 데이터 저장소를 사용할 수 있습니다. OneLogin

참고

Lambda를 ID 공급자로 사용하는 Transfer Family 서버를 생성하기 전에 함수를 생성해야 합니다. Lambda 함수의 예는 예 Lambda 함수를 참조하세요. 또는 다음 중 하나를 사용하는 CloudFormation 스택을 배포할 수 있습니다. Lambda 함수 템플릿 또한 Lambda 함수가 Transfer Family를 신뢰하는 리소스 기반 정책을 사용하는지 확인하세요. 정책 예제는 Lambda 리소스 기반 정책을 참조하세요.

  1. AWS Transfer Family 콘솔을 엽니다.

  2. 서버 생성을 선택하여 서버 생성 페이지를 엽니다. ID 제공자 선택를 위해 다음 스크린샷과 같이 사용자 지정 ID 공급자를 선택합니다.

    맞춤 ID 공급자가 선택된 ID 공급자 선택콘솔 섹션. 또한 사용자가 자신의 암호 또는 키를 사용하여 인증할 수 있는 기본값이 선택되어 있습니다.
    참고

    인증 방법은 SFTP를 Transfer Family 서버의 프로토콜 중 하나로 활성화한 경우에만 사용할 수 있습니다.

  3. 기본값인 ID 제공자를 연결하는 AWS Lambda 데 사용이 선택되어 있는지 확인하십시오.

  4. AWS Lambda 함수에서 Lambda 함수의 이름을 선택합니다.

  5. 나머지 상자를 채운 다음 서버 만들기를 선택합니다. 서버를 만들기 위한 나머지 단계에 대한 자세한 내용은 SFTP, FTPS 또는 FTP 서버 엔드포인트 구성을 참조하세요.

Lambda 리소스 기반 정책

Transfer Family 서버 및 Lambda ARN을 참조하는 정책이 있어야 합니다. 예를 들어 ID 공급자에 연결되는 Lambda 함수와 함께 다음 정책을 사용할 수 있습니다. 정책은 JSON을 문자열로 이스케이프합니다.

"Policy": "{ "Version": "2012-10-17", "Id": "default", "Statement": [ { "Sid": "AllowTransferInvocation", "Effect": "Allow", "Principal": { "Service": "transfer.amazonaws.com" }, "Action": "lambda:InvokeFunction", "Resource": "arn:aws:lambda:region:account-id:function:my-lambda-auth-function", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:transfer:region:account-id:server/server-id" } } } ] }"
참고

상기 예 정책에서 각 사용자 입력 자리 표시자를 자신의 정보로 바꿉니다.

이벤트 메시지 구조

사용자 지정 IDP에 대해 권한 부여자 Lambda 함수로 전송되는 SFTP 서버의 이벤트 메시지 구조는 다음과 같습니다.

{ "username": "value", "password": "value", "protocol": "SFTP", "serverId": "s-abcd123456", "sourceIp": "192.168.0.100" }

서버로 전송되는 로그인 자격 증명의 값인 usernamepassword의 위치는 어디입니까?

예를 들어, 다음 명령을 입력해서 연결합니다.

sftp bobusa@server_hostname

새 암호를 두 번 입력하라는 메시지가 나타납니다.

Enter password: mysecretpassword

Lambda 함수 내에서 전달된 이벤트를 인쇄하여 Lambda 함수에서 이를 확인할 수 있습니다. 그것은 다음 텍스트 블록과 비슷하게 보여야 합니다.

{ "username": "bobusa", "password": "mysecretpassword", "protocol": "SFTP", "serverId": "s-abcd123456", "sourceIp": "192.168.0.100" }

이벤트 구조는 FTP와 FTPS와 비슷한데, 유일한 차이점은 SFTP라기 보다 오히려 아닌 해당 값이 protocol파라미터에 사용된다는 것입니다.

인증을 위한 Lambda 함수

다양한 인증 전략을 구현하려면 Lambda 함수를 편집하세요. 애플리케이션의 요구 사항을 충족하는 데 도움이 되도록 CloudFormation 스택을 배포할 수 있습니다. 자세한 내용은 개발자 안내서AWS Lambda Node.js로 Lambda 함수 구축을 참조하세요.

Lambda 함수 템플릿

인증을 위해 Lambda 함수를 사용하는 AWS CloudFormation 스택을 배포할 수 있습니다. 로그인 자격 증명을 사용하여 사용자를 인증하고 권한을 부여하는 여러 템플릿을 제공합니다. 이러한 템플릿 또는 AWS Lambda 코드를 수정하여 사용자 액세스를 추가로 사용자 지정할 수 있습니다.

참고

템플릿에 FIPS 지원 보안 정책을 AWS CloudFormation 지정하여 FIPS 지원 AWS Transfer Family 서버를 만들 수 있습니다. 사용 가능한 보안 정책은 서버 보안 정책 AWS Transfer Family에 설명되어 있습니다.

인증에 사용할 스택을 만들려면 AWS CloudFormation
  1. https://console.aws.amazon.com/cloudformation 에서 AWS CloudFormation 콘솔을 엽니다.

  2. 사용 AWS CloudFormation 설명서의 AWS CloudFormation 스택 템플릿 선택에 나와 있는 기존 템플릿에서 스택을 배포하는 방법에 대한 지침을 따르십시오.

  3. 다음 템플릿 중 하나를 사용하여 Transfer Family의 인증에 사용할 Lambda 함수를 생성합니다.

    • 클래식 (Amazon Cognito) 스택 템플릿

      에서 사용자 지정 ID 공급자로 사용할 템플릿을 만들기 AWS Lambda 위한 기본 템플릿입니다. AWS Transfer Family암호 기반 인증을 위해 Amazon Cognito에 대해 인증하며, 퍼블릭 키 기반 인증을 사용하는 경우 Amazon S3 버킷에서 퍼블릭 키가 반환됩니다. 배포 후에는 Lambda 함수 코드를 수정하여 다른 작업을 수행할 수 있습니다.

    • AWS Secrets Manager 스택 템플릿

      Secrets Manager를 ID 공급자로 통합하기 위해 AWS Transfer Family 서버와 AWS Lambda 함께 사용하는 기본 템플릿입니다. AWS Secrets Manager 형식의 aws/transfer/server-id/username 항목에 대해 인증합니다. 또한 암호에는 Transfer Family에 반환된 모든 사용자 속성에 대한 키-값 쌍이 들어 있어야 합니다. 배포 후에는 Lambda 함수 코드를 수정하여 다른 작업을 수행할 수 있습니다.

    • Okta 스택 템플릿: AWS Lambda AWS Transfer Family 서버와 함께 사용하여 Okta를 사용자 지정 ID 공급자로 통합하는 기본 템플릿입니다.

    • Okta-MFA 스택 템플릿: AWS Lambda AWS Transfer Family 서버와 함께 사용하여 Okta를 MultiFactor 인증과 사용자 지정 ID 공급자로 통합하는 데 사용하는 기본 템플릿입니다.

    • Azure Active Directory 템플릿: 이 스택에 대한 세부 정보는 Azure Active Directory를 사용한 인증 및 블로그 게시물에 설명되어 있습니다. AWS Transfer Family AWS Lambda

    스택을 배포한 후에는 콘솔의 출력 탭에서 스택에 대한 세부 정보를 볼 수 있습니다. CloudFormation

    사용자 지정 ID 공급자를 Transfer Family 워크플로에 통합하는 가장 쉬운 방법은 이러한 스택 중 하나를 배포하는 것입니다.

유효 Lambda 값

다음 표에는 사용자 지정 ID 공급자에 사용되는 Lambda 함수에 대해 Transfer Family가 허용하는 값에 대한 세부 정보가 설명되어 있습니다.

설명 필수

Role

Amazon S3 버킷 또는 Amazon EFS 파일 시스템에 대한 사용자 액세스를 제어하는 IAM 역할의 Amazon 리소스 이름(ARN)을 지정합니다. 이 역할에 연결된 정책은 Amazon S3 버킷 또는 Amazon EFS 파일 시스템에 대한 파일 송수신 시 사용자에게 제공할 액세스의 수준을 결정합니다. 또한 IAM 역할에는 사용자의 전송 요청을 처리할 때 서버가 해당 리소스에 액세스할 수 있도록 허용하는 신뢰 관계가 포함되어야 합니다.

신뢰 관계 설정에 대한 자세한 내용은 신뢰 관계를 구축하기 위해을 참조하세요.

필수

PosixProfile

Amazon EFS 파일 시스템에 대한 사용자의 액세스를 제어하는 사용자 ID(Uid), 그룹 ID(Gid) 및 보조 그룹 ID(SecondaryGids)를 포함한 전체 POSIX 자격 증명입니다. 파일 시스템의 파일 및 디렉터리에 설정된 POSIX 권한에 따라 Amazon EFS 파일 시스템에서 파일을 송수신할 때 사용자에게 제공되는 액세스 수준이 결정됩니다.

Amazon EFS 백업 스토리지에 필요

PublicKeys

이 사용자에게 유효한 SSH 퍼블릭 키 값 목록. 목록이 비어 있으면 유효한 로그인이 아님을 의미합니다. 암호 인증 중에는 반환할 수 없습니다.

선택 사항

Policy

여러 사용자에 대해 동일한 IAM 역할을 사용할 수 있도록 한 사용자에 대한 세션 정책입니다. 이 정책은 Amazon S3 버킷의 부분에 대한 사용자 액세스의 범위를 축소합니다.

선택 사항

HomeDirectoryType

사용자가 서버에 로그인하는 경우 홈 디렉터리가 될 랜딩 디렉터리(폴더) 타입입니다.

  • PATH로 설정하면, 사용자는 파일 전송 프로토콜 클라이언트에서와 같이 절대 Amazon S3 버킷 또는 Amazon EFS 경로를 볼 수 있습니다.

  • LOGICAL로 설정하면 HomeDirectoryDetails 파라미터에서 Amazon S3 또는 Amazon EFS 경로를 사용자에게 시각적으로 표시할 방법에 대한 매핑을 제공해야 합니다.

선택 사항

HomeDirectoryDetails

사용자에게 표시할 Amazon S3 또는 Amazon EFS 경로 및 키와 이러한 경로 및 키를 사용자에게 시각적으로 표시할 방법을 지정하는 논리적 디렉터리 매핑입니다. EntryTarget 쌍을 지정해야 합니다. 여기서 Entry는 경로가 표시되는 방식을 보여주고 Target는 실제 Amazon S3 경로입니다.

HomeDirectoryTypeLOGICAL의 값을 가진 경우 필요

HomeDirectory

클라이언트를 사용하여 서버에 로그인하는 경우 랜딩 디렉터리(폴더)입니다.

선택 사항

참고

HomeDirectoryDetails는 JSON 맵의 문자열 표현입니다. 이는 실제 JSON 맵 객체인 PosixProfile과 문자열로 구성된 JSON 배열인 PublicKeys과 대조적입니다. 언어별 세부 정보는 코드 예를 참조하세요.

예 Lambda 함수

이 섹션에서는 NodeJS와 Python 모두에서 사용할 수 있는 Lambda 함수 몇 가지를 소개합니다.

참고

이 예에서는 사용자, 역할, POSIX 프로필, 암호 및 홈 디렉토리 세부 정보가 모두 예시이므로 실제 값으로 바꿔야 합니다.

Logical home directory, NodeJS

다음 NodeJS 예 함수는 논리적 홈 디렉터리가 있는 사용자에 대한 세부 정보를 제공합니다.

// GetUserConfig Lambda exports.handler = (event, context, callback) => { console.log("Username:", event.username, "ServerId: ", event.serverId); var response; // Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. if (event.serverId !== "" && event.username == 'example-user') { var homeDirectoryDetails = [ { Entry: "/", Target: "/fs-faa1a123" } ]; response = { Role: 'arn:aws:iam::123456789012:role/transfer-access-role', // The user is authenticated if and only if the Role field is not blank PosixProfile: {"Gid": 65534, "Uid": 65534}, // Required for EFS access, but not needed for S3 HomeDirectoryDetails: JSON.stringify(homeDirectoryDetails), HomeDirectoryType: "LOGICAL", }; // Check if password is provided if (!event.password) { // If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ]; // Check if password is correct } else if (event.password !== 'Password1234') { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } } else { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } callback(null, response); };
Path-based home directory, NodeJS

다음 NodeJS 예 함수는 경로 기반의 홈 디렉터리가 있는 사용자에 대한 세부 정보를 제공합니다.

// GetUserConfig Lambda exports.handler = (event, context, callback) => { console.log("Username:", event.username, "ServerId: ", event.serverId); var response; // Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. // There is also event.protocol (one of "FTP", "FTPS", "SFTP") and event.sourceIp (e.g., "127.0.0.1") to further restrict logins. if (event.serverId !== "" && event.username == 'example-user') { response = { Role: 'arn:aws:iam::123456789012:role/transfer-access-role', // The user is authenticated if and only if the Role field is not blank Policy: '', // Optional, JSON stringified blob to further restrict this user's permissions HomeDirectory: '/fs-faa1a123' // Not required, defaults to '/' }; // Check if password is provided if (!event.password) { // If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ]; // Check if password is correct } else if (event.password !== 'Password1234') { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } } else { // Return HTTP status 200 but with no role in the response to indicate authentication failure response = {}; } callback(null, response); };
Logical home directory, Python

다음 Python 예 함수는 논리적 홈 디렉터리가 있는 사용자에 대한 세부 정보를 제공합니다.

# GetUserConfig Python Lambda with LOGICAL HomeDirectoryDetails import json def lambda_handler(event, context): print("Username: {}, ServerId: {}".format(event['username'], event['serverId'])) response = {} # Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. if event['serverId'] != '' and event['username'] == 'example-user': homeDirectoryDetails = [ { 'Entry': '/', 'Target': '/fs-faa1a123' } ] response = { 'Role': 'arn:aws:iam::123456789012:role/transfer-access-role', # The user will be authenticated if and only if the Role field is not blank 'PosixProfile': {"Gid": 65534, "Uid": 65534}, # Required for EFS access, but not needed for S3 'HomeDirectoryDetails': json.dumps(homeDirectoryDetails), 'HomeDirectoryType': "LOGICAL" } # Check if password is provided if event.get('password', '') == '': # If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ] # Check if password is correct elif event['password'] != 'Password1234': # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} else: # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} return response
Path-based home directory, Python

다음 Python 예 함수는 경로 기반 홈 디렉터리가 있는 사용자에 대한 세부 정보를 제공합니다.

# GetUserConfig Python Lambda with PATH HomeDirectory def lambda_handler(event, context): print("Username: {}, ServerId: {}".format(event['username'], event['serverId'])) response = {} # Check if the username presented for authentication is correct. This doesn't check the value of the server ID, only that it is provided. # There is also event.protocol (one of "FTP", "FTPS", "SFTP") and event.sourceIp (e.g., "127.0.0.1") to further restrict logins. if event['serverId'] != '' and event['username'] == 'example-user': response = { 'Role': 'arn:aws:iam::123456789012:role/transfer-access-role', # The user will be authenticated if and only if the Role field is not blank 'Policy': '', # Optional, JSON stringified blob to further restrict this user's permissions 'HomeDirectory': '/fs-fs-faa1a123', 'HomeDirectoryType': "PATH" # Not strictly required, defaults to PATH } # Check if password is provided if event.get('password', '') == '': # If no password provided, return the user's SSH public key response['PublicKeys'] = [ "ssh-rsa abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789" ] # Check if password is correct elif event['password'] != 'Password1234': # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} else: # Return HTTP status 200 but with no role in the response to indicate authentication failure response = {} return response

구성 테스트

사용자 지정 ID 공급자를 만든 후에는 구성을 테스트해야 합니다.

Console
AWS Transfer Family 콘솔을 사용하여 구성을 테스트하려면
  1. AWS Transfer Family 콘솔을 엽니다.

  2. 서버 페이지에서 새 서버를 선택하고 작업을 선택한 다음 테스트를 선택합니다.

  3. AWS CloudFormation 스택을 배포할 때 설정한 사용자 이름암호 텍스트를 입력합니다. 기본 옵션을 유지한 경우 사용자 이름은 myuser 이고 암호는 MySuperSecretPassword입니다.

  4. 서버 프로토콜을 선택하고 소스 IP의 IP 주소 ( AWS CloudFormation 스택을 배포할 때 설정한 경우) 를 입력합니다.

CLI
AWS CLI를 사용하여 구성을 테스트하려면
  1. test-identity-provider 명령을 실행합니다. 다음 단계에서 설명하는 대로 user input placeholder 각각을 사용자 고유의 정보로 바꾸세요.

    aws transfer test-identity-provider --server-id s-1234abcd5678efgh --user-name myuser --user-password MySuperSecretPassword --server-protocol FTP --source-ip 127.0.0.1
  2. 서버 ID를 입력합니다.

  3. AWS CloudFormation 스택을 배포할 때 설정한 사용자 이름과 비밀번호를 입력합니다. 기본 옵션을 유지한 경우 사용자 이름은 myuser 이고 암호는 MySuperSecretPassword입니다.

  4. 서버 프로토콜과 소스 IP 주소 ( AWS CloudFormation 스택을 배포할 때 설정한 경우) 를 입력합니다.

사용자 인증에 성공하면 테스트 결과 StatusCode: 200 HTTP 응답, 빈 문자열 Message: "" (그렇지 않으면 실패 이유가 포함됨) 및 Response 필드가 반환됩니다.

참고

아래 응답 예에서 Response 필드는 '문자열화' (프로그램 내에서 사용할 수 있는 플랫 JSON 문자열로 변환) 된 JSON 객체이며, 사용자의 역할 및 권한에 대한 세부 정보를 포함합니다.

{ "Response":"{\"Policy\":\"{\\\"Version\\\":\\\"2012-10-17\\\",\\\"Statement\\\":[{\\\"Sid\\\":\\\"ReadAndListAllBuckets\\\",\\\"Effect\\\":\\\"Allow\\\",\\\"Action\\\":[\\\"s3:ListAllMybuckets\\\",\\\"s3:GetBucketLocation\\\",\\\"s3:ListBucket\\\",\\\"s3:GetObjectVersion\\\",\\\"s3:GetObjectVersion\\\"],\\\"Resource\\\":\\\"*\\\"}]}\",\"Role\":\"arn:aws:iam::000000000000:role/MyUserS3AccessRole\",\"HomeDirectory\":\"/\"}", "StatusCode": 200, "Message": "" }