【AWS】Amazon S3をFTP/SFTPサーバーのように使ってみた

232件のシェア(すこし話題の記事)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

今回の課題

こんにちは植木和樹です。本日のお題は「現在運用しているFTP/SFTPサーバーをAmazon S3でリプレースしたい」です。

外部関係業者とのファイルのやりとりにFTP/SFTPサーバーを使っているケースは数多くあると思います。社内にあまったパソコンにLinuxをインストールしてFTPサーバーを自前で運用していることもあるかもしれません。しかしデータのバックアップやハードウェアの故障などで手を取られている担当者の方がいらっしゃるのではないでしょうか。

そんな時はAmazon S3。99.999999999% の堅牢性と、99.99% の可用性を提供するストレージサービスです。

しかしFTPは長い運用実績の歴史があるサービスです。FTPで求められる様々な運用ニーズにS3はどこまで応えられるでしょうか?今回はその点を検証してみました。

FTPに求められる要望

以下にいくつかの代表的な運用を考えてみました。

  • ユーザー毎にホームフォルダをフルコントロールさせたい(他の人には見せたくない)
  • 同じグループのユーザーには参照のみアクセス可能にしたい
  • ログイン時にホームフォルダ以下のみ表示させたい(chroot)
  • 接続元IPアドレスを制限したい
  • 通信を暗号化したい
  • ファイル名に日本語を使いたい

ユーザー毎にホームフォルダをフルコントロールさせたい

S3でもポリシーを設定することでユーザー毎にフォルダのアクセス権を設定することが可能です。

my-bucket ─ home ┬ ftpuser1
          ├ ftpuser2
          └ ftpuser3

IAMポリシー内で使用できる変数${aws:username}を使うことで、S3にログインしたユーザー名に変数展開され、ホームフォルダだけにフルコントロールアクセスを与えることができます。

IAMグループ:ftpgroup-user-fullcontrol-own-folder

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::*"]
    },
    {
      "Action": ["s3:ListBucket"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::ueki-ftp-bucket"],
      "Condition":{"StringEquals":{"s3:prefix":["","home/"],"s3:delimiter":["/"]}}
     },
    {
      "Action": ["s3:ListBucket"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::ueki-ftp-bucket"],
      "Condition":{"StringLike":{"s3:prefix":["home/${aws:username}/*"]}}
    },
    {
       "Action":["s3:*"],
       "Effect":"Allow",
       "Resource": ["arn:aws:s3:::ueki-ftp-bucket/home/${aws:username}",
		    "arn:aws:s3:::ueki-ftp-bucket/home/${aws:username}/*"]
    }
  ]
}

上記のサンプルはAWSが公開しているIAMポリシーサンプルを参考にしました。AWSより${aws:username}を用いたポリシー設定について詳しく解説している記事がありますので、こちらも参考にしました。

${aws:username}以外にIAMポリシー内で使える変数については以下のドキュメントを参照してください。

同じグループのユーザーには参照のみアクセス可能

FTPを異なる部署やグループで運用している際に、あるメンバーがアップロードしたファイルに、同じグループのメンバーであれば参照・ダウンロードをさせたいという要望があるかと思います。例えばアップロード作業自体は特定の担当者が行い、他のメンバーは参照のみ行うという運用です。

上記ユーザー毎のポリシー設定と同様Conditionで「ある特定グループには参照可能」という設定できれば良いのですが、生憎aws:groupnameという変数はないようです。

現在のところS3のフォルダをグループとユーザーの階層構造にして「グループ以下のフォルダに対しては参照を許可、ホームフォルダにはフルコントロール」とするのが良さそうです。

my-bucket ┬ ftpgroup-A ┬ ftpuser1 
      │      └ ftpuser2
      │
      └ ftpgroup-B ─ ftpuser3

IAMグループ: ftpgroup-A

前述した/homeftpgroup-Aというグループ名に変更し、さらに/ftpgroup-A/*に対して参照権限を与えました。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["s3:ListAllMyBuckets", "s3:GetBucketLocation"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::*"]
    },
    {
      "Action": ["s3:ListBucket"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::ueki-ftp-bucket"],
      "Condition":{"StringEquals":{"s3:prefix":["","ftpgroup-A/"],"s3:delimiter":["/"]}}
     },
    {
      "Action": ["s3:ListBucket"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::ueki-ftp-bucket"],
      "Condition":{"StringLike":{"s3:prefix":["ftpgroup-A/*"]}}
    },
    {
      "Action": ["s3:ListBucket","s3:GetObject"],
      "Effect": "Allow",
      "Resource": ["arn:aws:s3:::ueki-ftp-bucket/ftpgroup-A/*"]
    },
    {
       "Action":["s3:*"],
       "Effect":"Allow",
       "Resource": ["arn:aws:s3:::ueki-ftp-bucket/ftpgroup-A/${aws:username}",
		    "arn:aws:s3:::ueki-ftp-bucket/ftpgroup-A/${aws:username}/*"]
    }
  ]
}

ログイン時にホームフォルダ以下のみ表示させたい

いろいろ調べてみたのですが、S3ログイン後のルートフォルダを特定フォルダ以下に制限する機能(chroot)はないようです。ポリシーの設定次第ではあるフォルダ以上の階層を参照不可にすることはできるのですが、これだとログイン後にルートのバケットから辿れなくなるため使い勝手が悪いです。

FTPを共用で運用し、バケットやフォルダ名に取引先顧客名をつけているようなケースでは、S3だと他の顧客フォルダ名が丸見えになってしまうので好ましくないかもしれません。

接続元IPアドレスを制限したい

IAMグループのポリシーでaws:SourceIp変数をNotIpAddressで判定します。つまり接続元IPアドレスが指定したCIDRに含まれなかった場合には、すべてのS3操作をDenyします。このグループをユーザーに割り当ててください。

IAMグループ:ftpgroup-office-only

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["s3:*"],
      "Condition": {
        "NotIpAddress": { "aws:SourceIp": "203.0.113.0/24" }
      },
      "Resource": ["arn:aws:s3:::*"],
      "Effect": "Deny"
    }
  ]
}

通信を暗号化したい

IAMグループのポリシーでaws:SecureTransportがfalse、つまりHTTPS通信ではないときには、すべてのS3操作をDenyします。このグループをユーザーに割り当ててください。

IAMグループ:ftpgroup-https-only

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": ["s3:*"],
      "Condition": {
        "Bool": { "aws:SecureTransport": "false" }
      },
      "Resource": ["arn:aws:s3:::*"],
      "Effect": "Deny"
    }
  ]
}

ファイル名に日本語を使いたい

入念に検証したわけではありませんが、Windows7のCloudBerry Explorerからアップロードした日本語名ファイルを、OSX(Mountain Lion)のCyberduckで文字化けせず読むことはできています。マネージメントコンソールからだと日本語ファイルはUTF-16UTF-8でエンコードされているようです。

20131110_s3_as_ftp_001

まとめ

本日のネタは、先日とある友人が社内にあったパソコンでFTPサーバーを立てたはいいけれどRAIDがおかしくて数時間サービスを止めてしまい、オロオロと復旧作業をしている姿をみてて思いつきました。

合計1TBの画像や動画を頻繁にやりとりする使い方だと、S3の月額コスト(容量と転送量)はそれなりの額が発生します。しかし、本来の業務の片手間にFTPサーバーの管理を行っていて、トラブルが起きれば障害原因の切り分けもままならずに夜中まで復旧作業をしている姿をみると「その対応時間の人件費でまかなえるんじゃない?」と思ってしまいます。

なによりS3に置いておくことでトラブルなく夜間休日もゆっくり休める安心感というのは何事にも代えがたいはずです。専任システム担当者不在の、中小零細企業にこそS3をオススメしたいです。