AWS Transfer Family(관리형 FTP 서버)
S3 오브젝트 스토리지의 경우 웹에서 제공하는 GUI 콘솔 혹은 AWS CLI 혹은 SDK를 통한 프로그래밍 방식으로 파일을 업로드/다운로드 가능한데요. 하지만 기존 온프레미스의 시스템이 오래되거나, 수정이 불가능하여 FTP를 통해서만 업로드가 가능한 경우에 사용이 가능한 방법이 있을까하여 관련 서비스를 찾아보다 AWS에서 제공하는 관리형 SFTP/FTPS/FTP 서비스인 AWS Transfer Family 에 대해 알게 되어 소개해드리려고 합니다.
AWS Transfer Family 서비스란
AWS Transfer Family 서비스는 위에 기재한 것과 같이 굉장히 심플하게 관리형 SFTP/FTPS/FTP 서비스이며, 파일을 업로드하는 대상은 S3 버킷입니다. 초기에는 SFTP 프로토콜만 지원하여 이름이 AWS Transfer for SFTP 였으나, 세 가지 프로토콜을 모두 지원하게 되면서 이름이 AWS Transfer Family 으로 변경되었습니다.
지원하는 프로토콜
AWS Transfer Family 서비스는 위에 기재한 것과 같이 SFTP/FTPS/FTP 프로토콜을 지원합니다.
SFTP - FTP over SSH, SSH를 기반으로 동작하는 FTP 입니다. 기본 포트는 SSH와 같은 22번입니다.
FTPS - FTP over TLS, 기존 평문(plain) FTP에 TLS/SSL 인증서를 적용하여 암호화 통신을 하는 FTP 입니다. 여기서 TLS/SSL 인증서는 ACM(Amazon Certificate Manager)에 등록된 인증서를 말합니다.
FTP - 평문 FTP로 암호화되지 않은 통신입니다. 보안에 취약하며, AWS Transfer Family 에서는 VPC 내부 간 파일 전송을 위한 internal 방식으로만 생성이 가능하며, 퍼블릭 액세스는 불가능합니다.
인증 방식
AWS Transfer Family 의 인증 방식은 크게 Service managed 방식과 Custom 방식으로 나뉩니다.
Service managed - AWS Transfer Family 서비스 내에서 유저를 생성하여 유저별로 특정 버킷에 대한 권한을 설정 가능합니다. 로그인 방식으로는 아이디/키페어 방식을 지원합니다. SFTP 프로토콜만 선택이 가능한 인증 방식입니다.
Custom - 말그대로 사용자 정의 인증 방식인데 API Gateway + Lambda 를 이용하여 인증을 하는 방식입니다. 로그인 방식은 Lambda 코드를 어떻게 구성하느냐에 따라 아이디/키페어/패스워드 모두 사용가능하며, SFTP/FTPS/FTP 모든 프로토콜 사용이 가능합니다. 아래 페이지에 상세히 안내되어 있지만 기본 클라우드포메이션 스택 템플릿 파일을 제공하여 손쉽게 커스텀 인증 제공자를 세팅할 수 있게 해줍니다. 그 외에도 AWS Secrets Manager를 통해 인증을 관리할 수도 있습니다.
커스텀 인증 제공자 설정 작업 안내 문서
https://docs.aws.amazon.com/ko_kr/transfer/latest/userguide/authenticating-users.html
비용
AWS Transfer Family 는 서버의 가동 시간에 대한 비용 및 데이터 업/다운로드에 대한 비용 모두 발생합니다.
처음에는 감이 잘 안왔는데 EC2 인스턴스 비용과 비교하니 엄청나게 비싸다는 생각이 들었습니다. 과연 FTP를 액세스하기 위한 용도로 저정도 비용을 줄 가치가 있는지 생각해볼 필요가 있을것 같습니다.
t3a.large -> 시간당 $0.187
t3a.xlarge -> 시간당 $0.374
구성 가능한 예
프로토콜과 인증 방식 엔드포인트의 퍼블릭 액세스 가능 여부에 따라 구성 가능한 케이스는 크게 4가지 정도가 됩니다.
1) 퍼블릭 액세스 가능한 Service managed 방식의 sftp 서버 구성
2) 퍼블릭 액세스 가능한 custom 인증 제공자로 sftp 서버 구성
3) Internet Facing(퍼블릭 액세스 가능), custom 인증 제공자로 ftps 서버 구성
4) internal, custom 인증 제공자로 ftp 서버 구성
여기서 2번 구성 예는 1번과 3번 구성 예를 응용하면 방식이 동일하고, 4번 구성 예 또한 3번과 동일하기 때문에 1번과 3번 구성 예를 구성하여 테스트해보겠습니다.
구성 테스트
1) 퍼블릭 액세스 가능한 Service managed 방식의 sftp 서버 구성
구성이 가장 간단하며 쉬운 방법이지만 위에 기재한 것과 같이 Service managed 방식의 인증은 SFTP만 지원하기 때문에 FTPS/FTP 프로토콜 액세스가 필요한 경우 사용할 수 없는 방법입니다. 구성 순서는 심플하게 1) 서버 생성 -> 2) iam S3 정책 및 역할 생성 -> 3) sftp 유저 생성 순서로 진행합니다. AWS Transfer Family 콘솔로 이동하여 Create Server 버튼을 클릭하여 서버 생성 과정을 시작합니다.
먼저 프로토콜을 선택하는 단계입니다. Custom 인증 방식의 경우 모든 프로토콜을 지원하기 때문에 중복으로 모두 선택도 가능하지만 Service managed 인증 방식의 경우 SFTP만 사용 가능하기 때문에 SFTP만 선택합니다.
다음은 인증 방식을 선택하는 부분입니다. 이번 구성은 Service managed 방식이기 때문에 Service managed 를 선택합니다.
만약 프로토콜을 선택하는 단계에서 FTPS/FTP 방식을 체크하고 다음 단계에서 Service managed 방식의 인증 방식을 선택하면 아래와 같은 에러 문구가 노출되며 다음으로 진행이 불가합니다.
다음은 접속에 사용할 엔드포인트에 대한 설정 단계입니다. 여기서 퍼블릭 액세스를 가능하게 할지 여부를 선택 가능합니다.
Publicly accessiable 옵션의 경우 SFTP 만 선택 가능한 퍼블릭 액세스 방식이며, VPC 내에 SFTP 접속을 위한 리소스가 생성되지 않습니다.
VPC hosted 방식의 경우, 나의 VPC 내에 FTP 접속을 위한 리소스가 생성되는 방식이며, FTPS/FTP 프로토콜의 경우 VPC hosted 방식만 사용 가능합니다.
현재 구성에서는 Publicly accessible 방식으로 구성할 것이기 때문에 Publicly accessible 을 선택합니다.(VPC hosted 방식은 다음 구성에서 다룹니다)
다음은 기타 세부사항 세팅입니다. FTP 로그가 남을 클라우드와치에 대한 로깅 iam 역할과 암호화 알고리즘, 서버 개인키 등의 설정이 가능한데 기본 값으로 진행합니다.
마지막 검토 단계입니다. 검토 후 create server 버튼을 눌러 서버를 생성합니다.
서버 생성은 완료되었습니다. 현재는 생성된 유저가 하나도 없기 때문에 유저를 생성해야하는데 유저가 S3 버킷에 대한 제한된 권한만 가질 수 있도록 iam 정책 및 역할 생성 후 SFTP 유저를 생성할 예정입니다.
iam 콘솔 -> 정책으로 이동하여 새로운 정책을 아래와 같이 생성합니다. 정책 이름은 임의로 지어도 관계 없습니다.(테스트에서는 s3-readwrite-policy-for-ftp으로 설정했습니다.)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListingOfUserFolder",
"Action": [
"s3:ListBucket",
"s3:GetBucketLocation"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::<bucket_name>" -> 액세스를 허용할 버킷 이름으로 <bucket_name>을 치환합니다.
]
},
{
"Sid": "HomeDirObjectAccess",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:DeleteObjectVersion",
"s3:DeleteObject",
"s3:GetObjectVersion"
],
"Resource": "arn:aws:s3:::<bucket_name>/*" -> 액세스를 허용할 버킷 이름으로 <bucket_name>을 치환합니다.
}
]
}
정책 생성이 완료되었으면 iam 역할을 생성합니다. 역할 이름도 임의로 지정합니다.(테스트에서는 s3-readwrite-role-for-ftp으로 설정했습니다)
역할 생성 후 해당 역할의 신뢰 관계 탭으로 이동하여 신뢰 관계를 아래와 같이 수정합니다.
신뢰 관계 편집 버튼을 누른 뒤 아래 내용을 붙여 넣습니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "transfer.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
iam 정책 및 역할 생성이 완료되었습니다. 다시 AWS Transfer Family 콘솔로 돌아와 Add user 버튼을 눌러 유저 생성을 진행합니다.
생성할 유저 이름을 지정하고 전 단계에서 생성한 iam 역할을 부여합니다.
Home directory는 해당 유저가 업로드/다운로드에 사용할 S3 버킷입니다.(테스트에서는 godo_cdntest 버킷으로 지정했습니다)
Restrict 옵션의 경우 FTP에서 사용하는 chroot와 같은 설정으로 홈디렉토리를 / 로 설정하여 홈디렉토리 밖으로 벗어나지 못하도록 하는 옵션입니다.
접속에 사용할 공개키를 입력하는 부분입니다. 테스트에서는 기존에 사용하던 키페어의 공개키를 입력했습니다. 기존에 사용하던 키가 없다면 puttygen(putty 키 생성기) 등을 이용하여 키를 생성합니다.
이제 유저 생성까지 완료되었습니다. 접속 테스트를 진행합니다. FTP 접속 테스트는 파일질라 클라이언트를 기준으로 진행합니다. 파일질라 클라이언트에 유저 생성에 사용할 공개키와 매칭되는 개인키를 설정한뒤,
AWS Transfer Family 콘솔상에서 엔드포인트 접속 주소를 확인하여 접속합니다. 성공적으로 접속된 것을 확인할 수 있습니다.
디렉토리 생성/제거를 하여 읽기/쓰기 권한이 모두 정상적인지 확인합니다.
FTP 접속 및 작업 로그는 cloudwatch logs를 통해 확인 가능합니다.
2) Internet Facing(퍼블릭 액세스 가능), custom 인증 제공자로 ftps 서버 구성
앞선 테스트에서는 Service managed 방식의 인증을 이용하여 SFTP 서버를 구성했습니다. Service managed 방식은 사용이 간단하지만 SFTP 프로토콜만 사용이 가능하기 때문에 FTPS/FTP의 경우 Custom 인증 제공자를 사용해야합니다.
이번에는 AWS 문서에서 제공하는 custom 인증 제공자 클라우드포메이션 스택 템플릿을 이용하여 API Gateway + Lambda 함수를 구성 후 FTPS 서버를 구성하는 방법으로 진행해보겠습니다. 먼저 아래 링크를 통해 클라우드포메이션 템플릿을 다운로드합니다.
위의 템플릿의 경우 FTP에 인증을 제공하기 위한 Lambda 코드 및 Lambda 함수에 엔드포인트를 제공하기 위한 API Gateway 및 기타 역할을 생성하는 내용으로 구성되어 있습니다. (AWS Transfer Family server의 경우 스택으로 함께 생성도 가능하지만 VPC hosted 방식의 엔드포인트를 생성하기 위해서는 스택을 통해 server는 생성하지 않고 이후 수동으로 server 생성 진행합니다)
클라우드포메이션 콘솔로 이동하여 다운로드한 템플릿을 업로드합니다.
파라미터 설정 값이 중요합니다.
CreateServer - 기본값 true -> AWS Transfer Family 서버를 생성할지 결정합니다. 엔드포인트가 자동으로 Publicly accessible 옵션으로 설정되기 때문에, VPC hosted 옵션으로 생성하고 싶은 경우 false 로 변경 후 수동으로 서버를 생성해야합니다.
UserHomeDirectory - 기본값 / -> 액세스를 허용할 S3 버킷 이름을 입력합니다.
UserName - 기본값 myuser -> 접속에 사용할 계정입니다. 원하는 아이디로 수정합니다.
UserPassword - 기본값 MySuperSecretPassword -> 접속에 사용할 비밀번호입니다. 원하는 비밀번호로 수정합니다.
UserPublicKey1 - 기본값 ssh-rsa myrsapubkey -> 접속에 사용할 개인키와 매칭하는 공개키를 입력합니다.(아이디/패스워드 방식으로 로그인하려면 기본 값으로 두어도 됩니다)
UserRoleArn - 기본값 arn:aws:iam::000000000000:role/MyUserS3AccessRole -> 이전 단계에서 설정한 S3 iam 사용자 역할(s3-readwrite-role-for-ftp) arn 으로 수정합니다.
클라우드포메이션 스택 생성이 완료되면 AWS Transfer Family 서버 생성을 진행합니다. 프로토콜은 FTPS를 선택하고 ACM에 등록된 인증서를 선택합니다.(인증서가 없는 경우 ACM을 통해 새로 생성 후 여기서부터 다시 진행합니다)
다음은 인증 제공자를 선택하는 단계입니다.
custom provider의 경우 아래 스크린샷과 같이 API Gateway에 생성된 api 를 선택 후 스테이지 메뉴의 url 호출 주소를 복사하여 붙여 넣습니다.
invocation role은 premisan-test-ftp-stack-TransferIdentityProviderRo-6Y7IH2OG0CUC 와 같이 역할 이름에 TransferIdentityProvider 라는 단어가 포함되어 있는 클라우드 포메이션 스택에 의해 생성된 역할을 선택합니다.
아래 스크린샷은 API Gateway 의 엔드포인트 주소를 확인하기 위한 화면입니다. 위의 인증 제공자 설정 시 참고합니다.
엔드포인트를 설정하는 단계입니다. VPC hosted를 선택한 뒤, 퍼블릭 액세스를 가능하도록 internet facing 옵션을 선택합니다. 만약 VPC 내부에서만 사용하고 싶다면 internal 을 선택하면 됩니다. internet facing 옵션을 선택했다면 VPC 및 서브넷, EIP를 선택해야합니다. 여분의 EIP 가 없다면 생성하고 진행합니다.
VPC 내에 리소스를 생성하는 것이기 때문에 보안그룹의 영향을 받습니다. AWS Transfer Family 를 통해 생성된 FTPS/FTP 서버의 경우 패시브 모드만 지원하기 때문에 데이터 포트로 어떤 포트가 사용될지 알 수 없습니다. 때문에 21번 포트 외에 전체 포트 오픈이 필요하기 때문에 보안그룹은 별도로 생성해주는 것이 좋습니다.
추가 세부사항을 설정합니다. 기본 값으로 진행하겠습니다.
검토화면이 표시되면 검토 후 create server 버튼을 눌러 서버 생성을 완료합니다. 서버가 생성되어 리스트에 offline 상태로 보여진다면 actions -> start 클릭하여 서버를 시작합니다.
이제 생성된 서버의 엔드포인트를 이용하여 접속을 시도합니다. 클라우드포메이션 스택 생성 시 지정한 아이디와 비밀번호/개인키를 이용하여 접속해봅니다. FTP 계정 인증에 비밀번호와 개인키 모두 사용이 가능합니다. TLS/SSL은 도메인 기반이기 때문에 FTP 접속에 사용한 도메인과 인증서의 도메인이 일치하지 않으면 아래와 같이 경고 창이 발생합니다.
엔드포인트에 대한 CNAME 도메인 레코드 생성(ftp.premisan01.shop)하여 연결 시 경고창 없이 정상적으로 접속 됩니다. 접속 후 읽기/쓰기가 모두 정상적으로 작동하는지 확인합니다.
SFTP와 마찬가지로 FTPS/FTP 또한 cloudwatch logs 를 통해 접속 및 FTP 작업 로그 확인이 가능합니다.
결론
이렇게 AWS Transfer Family 서비스를 이용하여 SFTP 및 FTPS 프로토콜을 통해 S3 버킷에 접속하여 파일 업로드/다운로드하는 방법을 알아보았습니다. 클라우드/온프레미스에 구성된 시스템, 솔루션 상에서 SFTP, FTPS, FTP 등 특정 프로토콜만을 지원하고 이미 구성된 시스템을 수정하는게 어려운 상황이라면 기존 시스템에 대한 수정이 필요없고 자동으로 용량이 확장하며 비용 효율적인 S3에 대한 연동이 가능하다는 점에서 어쩔 수 없는 경우 사용해볼만한 서비스라는 생각이 들었으나, FTP 용도로만 사용하기에는 AWS Transfer Family + S3 비용까지 생각한다면 너무 비싸다는 생각이 들었습니다.
최근에는 winscp 등 FTP 클라이언트 프로그램 상에서 Amazon S3로 api를 통한 액세스를 지원하여 아래와 같이 사용도 가능하니, 사용자 인터페이스를 위한 부분이라면 FTP 클라이언트 프로그램을 통해 api 방식으로 액세스하는게 낫겠습니다.