当初はAWS Transfer Family for FTPで構築していましたが、あまりにもコストが高いのでEC2上に別途FTPサーバを構築した際のメモです
AWS Transfer Familyとは
AWS Transfer Familyを使用するとS3・EFSにSFTPやFTPなどでファイル転送を行うことができるサービスです
が、データ転送量の他にエンドポイントが有効になっている期間で課金されるという料金体系になっています
東京リージョンで1か月だとエンドポイント料金は
USD 0.30/1時間 × 24 × 30日 = 216 USD
と結構な額です
(平日の日中だけしか使用されないので未使用時には停止したいが、停止してもエンドポイント料金は変わらない)
EC2上でSFTPサーバを構築している方もいるのでFTPサーバでも同じように自前で構築することにしました
S3 Filesで構築するという手段もありましたが、s3の前段のキャッシュ層が若干割高である・s3への同期にラグがありそのラグがシステム上許容できないため、mount-s3での構築することとしました
https://dev.classmethod.jp/articles/amazon-s3-files-pricing-visual-guide/
準備
以下のポリシーをEC2のIAMロールに追加します
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:ListBucket",
"s3:GetObjectVersion",
"s3:GetObjectACL",
"s3:GetObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
},
{
"Action": [
"s3:PutObjectACL",
"s3:PutObject"
],
"Effect": "Allow",
"Resource": [
"arn:aws:s3:::my-bucket/*"
]
}
]
}
マウントポイントのディレクトリを作成します
sudo mkdir /mnt/s3
vsftpd
vsftpd をインストールします
sudo dnf install vsftpd
vsftpd を設定する
manpages vsftpd.conf
設定の詳細は省略しますが、仮想ユーザでのFTPログインを行うためファイルなどのオーナーは ftp ユーザとなるようにします
local_root=/mnt/s3
guest_enable=YES
guest_username=ftp
virtual_use_local_privs=YES
ちなみに、anonymounsユーザの場合は以下を追加します
chown_uploads_anon=YES
chown_username=ftp
Mountpoint for Amazon S3
mount-s3のインストール
wget https://s3.amazonaws.com/mountpoint-s3-release/latest/x86_64/mount-s3.rpm
sudo dnf install mount-s3.rpm
vsftpd経由でアップロードされたファイルとオーナーを合わせるため、mount-s3 は vsftpd.conf で指定した ftp ユーザでmountするようにします
mount-s3 はFUSEを使用してmountしているため、root以外でもmountできるように以下を追加します
user_allow_other
起動時にmountされるように mount-s3 をサービス登録します
[Unit]
ConditionPathExists=/usr/bin/mount-s3
Wants=network-online.target
After=network-online.target
[Service]
User=ftp # mountするユーザ
Group=ftp # mountするユーザグループ
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/mount-s3 my-bucket /mnt/s3 --allow-delete --allow-overwrite --allow-other --dir-mode 0775 --file-mode 0664
ExecStop=/usr/bin/umount /mnt/s3
[Install]
WantedBy=multi-user.target
サービス起動します
sudo systemctl enable mount-s3
sudo systemctl start mount-s3
vsftpdの設定
mount-s3 の実行後に vsftpd が起動するようにします
[Unit]
Description=Vsftpd ftp daemon
Wants=network-online.target
After=mount-s3.service # この行を追加
[Service]
Type=forking
ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf
[Install]
WantedBy=multi-user.target
vsftpdを起動します
sudo systemctl daemon-reload
sudo systemctl start vsftpd
AWS Transfer Familyとの違い
- AWS Transfer Family ではPUT時にディレクトリがなくてもPUTができるが、mount-s3 + vsftpdでは明示的に
mkdirを実行しないといけない
lftp user1@ftp-server:/> put a -o path1/path2/a
put: Access failed: 553 Could not create file. (path1/path2/a)
-
mkdirを実行しただけではs3上にはフォルダが作成されず(見えていないだけかも?)、ファイルを転送した時点で見えるようになる
mkdirは成功し、ディレクトリも見える
lftp user1@ftp-server:/> mkdir path1
mkdir ok, `path1' created
lftp user1@ftp-sertver:/> ls
drwxrwxr-x 2 ftp ftp 0 Oct 06 09:30 path1
が、s3では見えない
$ aws s3 ls s3://my-bucket/
2026-05-18 14:10:29 0