AWS Lambda 를 사용하여 자격 증명 공급자 통합 - AWS Transfer Family

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

AWS Lambda 를 사용하여 자격 증명 공급자 통합

사용자 지정 자격 증명 공급자에 연결하는 AWS Lambda 함수를 생성합니다. Okta, Secrets Manager, OneLogin또는 권한 부여 및 인증 로직이 포함된 사용자 지정 데이터 스토어와 같은 사용자 지정 자격 증명 공급자를 사용할 수 있습니다.

참고

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

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

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

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

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

  3. 기본값인 자격 증명 공급자 연결 AWS Lambda 에 사용 가 선택되어 있는지 확인합니다.

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

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

Lambda 리소스 기반 정책

Transfer Family 서버 및 Lambda를 참조하는 정책이 있어야 합니다ARNs. 예를 들어 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:transfer:region:account-id:function:my-lambda-auth-function", "Condition": { "ArnLike": { "AWS:SourceArn": "arn:aws:transfer:region:account-id:server/server-id" } } } ] }"
참고

위의 예제 정책에서 각각을 바꿉니다.user input placeholder 자신의 정보를 사용합니다.

이벤트 메시지 구조

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

{ '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. 유일한 차이점은 값이 보다는 protocol 파라미터에 사용된다는 것입니다SFTP.

인증을 위한 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) 스택 템플릿

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

    • AWS Secrets Manager 스택 템플릿

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

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

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

    • 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) 및 보조 그룹IDs(SecondaryGids)을 포함한 전체 POSIX 자격 증명입니다. 파일 시스템의 파일 및 디렉터리에 설정된 POSIX 권한에 따라 Amazon EFS 파일 시스템으로 파일을 전송하거나 전송할 때 사용자가 받는 액세스 수준이 결정됩니다.

Amazon EFS 백업 스토리지에 필요

PublicKeys

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

선택 사항

Policy

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

선택 사항

HomeDirectoryType

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

  • 로 설정하면 PATH파일 전송 프로토콜 클라이언트에서와 같이 절대 Amazon S3 버킷 또는 Amazon EFS 경로가 표시됩니다.

  • 로 설정한 경우 사용자가 Amazon S3 또는 Amazon EFS 경로를 볼 수 있도록 HomeDirectoryDetails 파라미터에 매핑을 제공해야 LOGICAL합니다.

선택 사항

HomeDirectoryDetails

사용자에게 표시해야 하는 Amazon S3 또는 Amazon EFS 경로와 키를 지정하는 논리적 디렉터리 매핑과 이를 표시할 방법을 지정합니다. EntryTarget 페어를 지정해야 합니다. 여기서 는 경로가 어떻게 표시되는Entry지, 는 실제 Amazon S3 또는 Amazon EFS 경로Target입니다.

HomeDirectoryTypeLOGICAL의 값을 가진 경우 필요

HomeDirectory

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

선택 사항

참고

HomeDirectoryDetails 는 JSON 맵의 문자열 표현입니다. 이는 실제 JSON 맵 객체이고 문자열 JSON 배열PosixProfilePublicKeys 와는 대조적입니다. 언어별 세부 정보는 코드 예를 참조하세요.

예 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. 서버 프로토콜을 선택하고 AWS CloudFormation 스택을 배포할 때 설정한 경우 원본 IP 의 IP 주소를 입력합니다.

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. AWS CloudFormation 스택을 배포할 때 설정한 경우 서버 프로토콜과 소스 IP 주소를 입력합니다.

사용자 인증에 성공하면 테스트는 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": "" }