Amazon S3をFTP経由で利用するテンプレート | アドカレ2013 : CFn #22

2013.12.22

こんにちは。たけかわです。『アドベントカレンダー2013:AWS CloudFormationビッグバンテンプレート』22日目です。
昨日は、望月さんのGitlab編でした。

S3とFTPサーバー

S3をお客様に説明するとき「FTPアクセスできないの?」とよく言われます。今回は FTPサーバーを作成し、S3をマウント、ユーザーがFTP経由でS3にアクセスできるCloudFormationテンプレートを作成しました。 前回、「s3fsでAmazon S3をファイルシステムとして扱う」で作ったテンプレートを進化させて、FTPサーバーのインストールとユーザーの作成をおこないます。

FTPサーバーはvsftpdを利用しました。こちらは、Amazon Linuxではyumコマンド一つでインストールできます。s3fsの設定は前回のテンプレートでおこないましたので、行なうことはFTP用の設定のみとなります。

テンプレートの説明

このCFnテンプレート以下の作業をおこないます。

  • S3にアクセスできるIAMロールを作成します
  • FTPが利用できるようにセキュリティグループを設定します
  • 標準のAmazon AMIでインスタンスをたちあげます
  • s3fsに必要なパッケージをインストールします
  • vsftpdをインストールします
  • s3fsをコンパイルしてインストールします。
  • s3fsコマンドを実行し、指定されたバケットを/mnt/3にマウントします
  • vsftpdの設定ファイルを作成します
  • FTPログインできるようにec2-userにパスワードを設定します。

S3用FTPインスタンスを起動

以下に起動時のパラメータを示します。

InstanceType 起動するEC2インスタンスのタイプです。デフォルトはt1.microです。
KeyName EC2にSSHログインするためのKeyPair名を指定します。
VpcId インスタンスの所属するVPCのIDを指定します。例 :vpc-XXXXXXXX
SubnetId VPCのSubnetIDを指定します。例 :例 :subnet-XXXXXXXX
BucketName マウントしたいS3のバケット名を指定します。
UserPasswrod FTPをするためにec2-userのパスワードを設定します。

CloudFormationのスタックがCompleteになったあと10分程待ってから起動したEC2にec2-userでftpを行なってください。ログイン後、s3にバケットの内容がみえていたら成功です。

$ ftp ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com
Connected to ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com.
220 Classmethod Advent Calendar No.22 FTP service.

Name (ec2-XXX-XXX-XXX-XXX.ap-northeast-1.compute.amazonaws.com:takekawa): ec2-user
331 Please specify the password.
Password: 
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> ls
229 Entering Extended Passive Mode (|||58823|).
150 Here comes the directory listing.
lrwxrwxrwx    1 0        0               7 Dec 22 02:33 s3 -> /mnt/s3
226 Directory send OK.
ftp> cd s3
250 Directory successfully changed.
ftp> ls
229 Entering Extended Passive Mode (|||56156|).
150 Here comes the directory listing.
----------    1 222      500         12042 Dec 22 02:26 vsftpd.template
226 Directory send OK.

コマンドラインからの実行

awscliを用いるとコマンドラインからスタックの作成ができます。デバッグ時等GUIでパラメータを何度も入れるのは面倒です。今回のテンプレートですとこんな感じで実行できます。

$ CFN_BUCKETNAME=MYBUCKETNAME
$ CFN_SUBNETID=subnet-XXXXXXX
$ CFN_VPCID=vpc-XXXXXXX
$ CFN_KEYNAME=MYKEYNAME
$ CFN_STACKNAME=vsftpd-test3
$ CFN_PASSWORD=XXXXXXX
$ 
$ aws cloudformation create-stack --disable-rollback \
--region ap-northeast-1 --stack-name $CFN_STACKNAME --parameters \
 ParameterKey=BucketName,ParameterValue=$CFN_BUCKETNAME \
 ParameterKey=SubnetId,ParameterValue=$CFN_SUBNETID \ 
 ParameterKey=VpcId,ParameterValue=$CFN_VPCID \
 ParameterKey=KeyName,ParameterValue=$CFN_KEYNAME \
 --template-url https://cm-public-cfn-templates.s3-ap-northeast-1.amazonaws.com/cfn_s3fs/cfn_s3fs-1.0-SNAPSHOT.template
{
    "StackId": "arn:aws:cloudformation:ap-northeast-1:314132709601:stack/s3fsTEST/86c768e0-5ed4-11e3-8524-50fa01768096"
}

10分程度おいて実行結果を確認します。CREATE_COMPLETEと出ていたら成功です。

aws cloudformation describe-stacks --stack-name $CFN_STACKNAME |  jq '.Stacks[].StackStatus'
"CREATE_COMPLETE"

改善すべき点

以下の改善すべき点があります。

  • IAMロールがS3の全てにアクセスできるという権限になっています。実際の利用ではこの部分絞るようにすべきです。
  • FTPユーザーにec2-userをつかっています。実際の利用では専用のユーザーを作るべきです。
  • /mnt/s3にマウントしたものをシンボリックリンクしてユーザーにみせています。実際の医療では、この部分は各ユーザー毎にマウントするなどして、ログインディレクトリより上のディレクトリに移動できないようにすべきです。
  • サブネットIDを指定すればVPC IDも一意に定まる気がするのですが、VPC IDの取得方法がわかりませんでした。

ということで GitHubよりフォークして進化させて頂ければと思います。プルリクエストされたらとても喜びます。

FTPについて

FTPは通信路が暗号化されておらず、認証はパスワード認証のみということでセキュリティに不安のあるプロトコルです。過去から使われていているため、現在でも要望はあるのですが、SCP、SFTP,FTPSのような代替手法を利用すべきです。Amazon S3がFTPをサポートしないのは正しい判断だと思います。

ユーザー/パスワードのバッチ処理

今回パスワードの設定にはpassword --stdinオプションを利用しました。これ以外にもchpasswdnewusersといったコマンドが利用できるとのことでした。教えてくれた大瀧さん、慎介さんありがとうございました。

まとめ

FTPサーバーを作成し、s3fs経由でs3にアクセスするテンプレートを作成しました。 明日は横田慎介さんです。おたのしみに。