Hanatare's PaPa

Make life a little richer.

Virtual Space of Hanatare's PaPa

人生をほんの少しだけ充実させる

【AWS】閉域網のEC2にFTPサーバーを構築

f:id:nothing-title:20210319214105p:plain

業務でFTPサーバーを利用している方もまだまだ多いのではないでしょうか?今回はプライベートサブネットのEC2にFTPサーバーを構築して、パブリックサブネットのEC2からアクセスできるようする方法を紹介したいと思います。

記事のポイント
  • AWS プライベートサブネット上へのFTPサーバーの構築手順
  • FTPサーバーのセキュリティ設定
  • FTPの通信モード

FTPサーバーの構築

FTPは随分古くから使われている転送方式の1つで、暗号化されていないなど、セキュリティ的に問題はあるものの、業務では未だに多く利用されれているのではないでしょうか?私の現場でもこのFTPを使っているファイル転送を行っているため、今回はこのFTPサーバーを構築したいと思います。まずは、セキュリティなどを気にせずFTPサーバーを構築したいと思います

事前に準備

NATゲートウェイの設置

今回はプライベートサブネット上のEC2にFTPサーバーを構築するため、事前にNATゲートウェイを設定してプライベートサブネット上のEC2にソフトをインストールできるようにしておきます。NATゲートウェイのインストールは以下の記事を参考にしてください。

www.hanatare-papa.jp

パブリックサブネットのEC2にFTPクライアントのインストール

デフォルトではEC2にFTPクライアントは入っていません。そのためパブリックサブネットのEC2に以下のコマンドでFTPクライアントをインストールしてください。

$ sudo yum install -y ftp

vsftpdをインストール

プライベートサブネット上のEC2にSSHでログインします。rootユーザーにスイッチするか、一般ユーザーの場合は以下のコマンドでvsftpdをインストールします。

$ sudo yum install -y vsftpd

vsftpdサービスの有効化と起動

インストールしたvsftpdのサービスを起動します

$ sudo systemctl enable vsftpd
$ sudo systemctl start vsftpd
$ sudo systemctl status vsftpd

● vsftpd.service - Vsftpd ftp daemon
   Loaded: loaded (/usr/lib/systemd/system/vsftpd.service; disabled; vendor preset: disabled)
   Active: active (running) since 木 2020-07-09 04:31:30 UTC; 1h 24min ago
  Process: 25447 ExecStart=/usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf (code=exited, status=0/SUCCESS)
 Main PID: 25448 (vsftpd)
   CGroup: /system.slice/vsftpd.service
           └─25448 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf

 709 04:31:30 ip-XX-X-X-X.ap-northeast-1.compute.internal systemd[1]: St...
 709 04:31:30 ip-XX-X-XX-X.ap-northeast-1.compute.internal systemd[1]: St...
Hint: Some lines were ellipsized, use -l to show in full.

FTP接続ユーザーを作成

FTP接続用のユーザーを作成します。

#ユーザー作成:ftp-user
$ sudo useradd ftp-user
#パスワード設定:ftp-user
$ sudo passwd ftp-user

セキュリティグループの設定

ここまで設定は何も変更していませんので、デフォルトではパッシブモードでの接続になります。その前提でポートの開放を行います。

セキュリティグループ

セキュリティグループの画面からプライベートサブネットに設定しているセキュリティグループを選択し、『インバウンドルール』のタブを選択し、『インバウンドルールを編集』をクリックします。

インバウンドルールの編集

インバウンドルールを編集画面で『ルールを追加』をクリックし、インバウンドルールを設定し、『ルールを保存』をクリックします。

FTPのインバウンドルールはデフォルト設定の場合は以下の2つのポートを開けます。

接続確認

今の状態で接続はできるはずですので、確認をしておきます。FTPクライアントを事前にインストールしたパブリックサブネット配下のEC2にSSHでログインし、以下のコマンドを実行します。

$ ftp
#FTPモードに切り替わるため、FTPサーバーに接続する
ftp> open FTPサーバーのIP
Connected to XX.XX.XX.XX (XX.XX.XX.XX).
220 (vsFTPd 3.0.2)
#FTP接続時のユーザーを問われるのでユーザーIDを入力(今回はftp-user)
Name (XX.XX.XX.XX:ユーザー名):ftp-user
331 Please specify the password.
#接続ユーザーのパスワードを求められるので入力(今回はftp-userのパスワード)
Password:ftp-userのパスワードを入力
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.

接続ができれば、最後にデータ転送が可能かを確認します。

ftp >
227 Entering Passive Mode (XX,XX,XX,XX,XXX,XXX).
150 Here comes the directory listing.
226 Directory send OK

FTPサーバーのセキュリティ設定

FTPはセキュリティ的に見ると脆弱な転送方式です。個人的にはFTPではなく、暗号化された通信を使用するSCPやSFTPなどを用いるほうが良いと考えますが、それでもFTPでやり取りをしたいという要件もあるかと思うので、FTPサーバー上で最低限のセキュリティ対策を行いたいと思います。

この対策はもちろん正解ではないので、今回の要件は以下を想定します。

     
  • 匿名ユーザー(anonymous)のログインは拒否する
  •  
  • パッシブモードでの転送を許可する
  •  
  • rootユーザーのログインを拒否する
  •  
  • 接続したユーザー自身のホームディレクトリより上の階層に対してアクセスを禁止する

FTPのセキュリティは危険であることを理解する

FTPは古くから使われている転送の仕組みなのですが、セキュリティ的にとても脆弱です。なぜなら、通信する内容の暗号化を行わないため、通信内容傍受されると、その中身が筒抜けになるからです。通信内容には、もちろんデータの中身も含まれますし、FTP接続する際のユーザーID・PASSも含まれます。データの中身に個人情報が含まれており、それが傍受されれば、個人情報の流出につながりますし、FTPのユーザーID・パスワードが盗まれれば、サーバーに不正にアクセスされます。こうしたリスクがFTP通信にはあるということを理解した上で使うようにしてください。

vsftpd.confの設定を変更する

あらためて要件を確認しておきます。

     
  • 匿名ユーザー(anonymous)のログインは拒否する
  •  
  • パッシブモードでの転送を許可する
  •  
  • rootユーザーのログインを拒否する
  •  
  • 接続したユーザー自身のホームディレクトリより上の階層に対してアクセスを禁止する

vsftpdは起動時にvsftpd.confを参照し、設定に応じて動作を決定します。csftpd.confはデフォルトでは/etc/vsftpd/配下に配置されています。

# デフォルトのファイルをコピーしバックアップを取る
$ sudo cp /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.20200709
# 設定ファイルを編集する
$ sudo vi /etc/vsftpd/vsftpd.conf
# /etc/vsftpd/vsftpd.confの中身です。
# 20200709 edit config file /etc/vsftpd/vsftpd.conf
#
# 匿名ユーザーによるFTPログインの許可/拒否(YES/NO)
anonymous_enable=NO
#
# ローカル ユーザ アカウントによる ログインを許可/拒否(YES/NO)
local_enable=YES
#
# ファイルに変更を加えるFTPコマンドの使用を許可/拒否(YES/NO)
write_enable=YES
#
# 新規ファイルに適用するパーミッションの設定
local_umask=022
#
# 匿名ユーザーからのサーバーへのファイル書き込み許可/拒否(YES/NO)
anon_upload_enable=NO
#
# 匿名ユーザーのディレクトリの生成を許可/拒否(YES/NO)
anon_mkdir_write_enable=NO
#
# 新たなディレクトリに初めて入ったときにメッセージを表示/非表示(YES/NO)
dirmessage_enable=YES
#
# ログ取得の有無(YES/NO)
xferlog_enable=YES
#
# アクティブモード時のサーバー側が使用するデータ転送用ポート番号の指定方法を定義
# (YES:ftp_data_portで指定するポート、NO:1024以降のポート)
connect_from_port_20=YES
#
# 匿名ユーザーでアップロードされたファイルの所有者を変更許可拒否(YES/NO)
chown_uploads=YES
#
# 匿名ユーザーでアップロードされたファイルの所有者を変更す場合のユーザーを指定
#chown_username=whoever
#
# ログファイルのファイル名を設定する
xferlog_file=/var/log/xferlog
#
# ログをxferlogのフォーマットにするかの設定する
xferlog_std_format=YES
#
# コントロールコネクション上でアイドル状態のタイムアウト値を秒数で指定する
idle_session_timeout=600
#
# データ転送の進捗が進まない場合のタイムアウト値を秒数で指定する
data_connection_timeout=120
#
# 特権がいらない場合の権限を指定する
#nopriv_user=ftpsecure
#
# 非同期ABORを許可/拒否(YES/NO)
#async_abor_enable=YES
#
# アップロード時のASCIIモードでのデータ転送を許可/拒否(YES/NO)
ascii_upload_enable=NO
#
# ダウンロード時のASCIIモードでのデータ転送を許可/拒否(YES/NO)
ascii_download_enable=NO
#
# 接続が最初に来たときにvsftpdが表示する挨拶メッセージを指定する
ftpd_banner=Welcome to FTP service.
#
# 匿名ユーザーのパスワード(e-mail アドレス)のうちログインを拒否したいもののリストを適用/非適用(YES/NO)
#deny_email_enable=YES
#
# 匿名ユーザーのパスワード(e-mail アドレス)のうち、拒否リストのファイル名
#banned_email_file=/etc/vsftpd/banned_emails
#
# ログイン後にホームディレクトリへとchrootするかどうかを指定
chroot_local_user=YES
#
# ログイン後にホームディレクトリへとchrootされるローカルユーザーのリストを指定
chroot_list_enable=YES
#
# ホームディレクトリ内のchootに入れられるローカルユーザーのリストを示すファイル名を指定
chroot_list_file=/etc/vsftpd/chroot_list
#
#chroot先へに書き込み権限を許可/拒否(YES/NO)
allow_writeable_chroot=YES
#
# “ls -R”コマンドの使用を許可/拒否(YES/NO)
#ls_recurse_enable=YES
#
# スタンドアロンモード(デーモン)で起動するかどうか(YES/NO)
listen=YES
#
# スタンドアロンモード(デーモン)で起動するかどうか(IPv6で待ち受ける)
listen_ipv6=NO
#
# vsftpdが使用するPAMサービス名を指定する
pam_service_name=vsftpd
#
# userlist_fileで指定したファイルをユーザ名のリストとして読み込む。
# このファイルに名前のあるユーザーでログインしようとするとパスワードを尋ねられる前に拒否される
userlist_enable=YES
#
# userlist_denyをNOにした場合、userlist_fileで指定したファイルに
# 明示的にリストされたユーザー以外はログインが拒否される
userlist_deny=YES
#
# userlist_enableオプションがYESの場合に読み込まれるファイルを指定する
userlist_file=/etc/vsftpd/user_list
#
# YESにした場合、vsftpdをtcp_wrappersをサポートしてコンパイルしてあれば
# 外から来る接続はtcp_wrappersのアクセス制御が適用される
tcp_wrappers=YES
#
# ディレクトリリストの表示にローカルのタイムゾーンを使用する
use_localtime=YES
#
# パッシブモード接続の許可/不許可(YES/NO)
pasv_enable=YES
#
# パッシブモードでの接続に割り当てるポートの最小値
#pasv_min_port=0
#
# パッシブモードでの接続に割り当てるポートの最大値
#pasv_max_port=0
#
# End

ここでのポイントは以下13個の設定です。それぞれ目的に応じての設定について解説をしておきます。

匿名ユーザー(anonymous)のログインは拒否する

     
  • anonymous_enable=NO
  •  
  • anon_upload_enable=NO
  •  
  • anon_mkdir_write_enable=NO

上記の3つをNOにして匿名ユーザーでの操作を禁止します。特にanonymous_enable=NOは匿名ユーザーを使ってのログインを禁止するため、設定することをおすすめします。

パッシブモードでの転送を許可する

     
  • pasv_enable=YES
  •  
  • pasv_min_port=0
  •  
  • pasv_max_port=0

デフォルトではパッシブモードはYESの状態ですが、ここでは明示的にYESと記載して許可しています。パッシブモード時のデータ転送ポートはminとmaxを0にしているとエフェメラルポートを使用するので、1024〜65535のいずれかが毎回ランダムで割り当てられます。他とポートが重複するなどある場合は、minとmaxを指定して使用するポートの範囲を決定しておきます。

rootユーザーのログインを拒否する

     
  • userlist_enable=YES
  •  
  • userlist_deny=NO
  •  
  • userlist_file=/etc/vsftpd/user_list

userlist_enableをYESにしてユーザーリスト(userlist_file)を使ってFTPアクセスできるユーザーを制限することを可能にします。そしてuserlist_denyを使って、ユーザーリストの内容を拒否する(YES)か、許可するか(NO)を決めます。個人的には全て拒否にして、必要なユーザーだけを通すほうが良いので、NOを指定して、ユーザーリストに許可するユーザー(今回はftp-user)を記載します(後述します)。

接続したユーザー自身のホームディレクトリより上の階層に対してアクセスを禁止する

     
  • chroot_local_user=YES
  •  
  • chroot_list_enable=YES
  •  
  • chroot_list_file=/etc/vsftpd/chroot_list
  •  
  • allow_writeable_chroot=YES

chroot_local_userを使ってログイン後にユーザーのホームディレクトリ(/home/ユーザー名)にchrootするかどうか決定します。chrootを設定するとホームディレクトリより上の階層が見えなくなり、アクセスできなくなります。chroot_list_enableではchrootをしても例外的に上の階層にアクセスできるユーザーをリスト管理するかどうかを指定します。そのリストはchroot_list_fileになります。このファイルはデフォルトでは作られないので、必要であれば作りましょう。最後にchrootを設定してもchroot先に書き込み権限があると、ログインが許可されません。(次のエラーになります)

500 OOPS: vsftpd: refusing to run with writable root inside chroot()

chroot先のディレクトリの書き込み権限を外してもよいのでは、それではファイルをputできないので、今回はchroot先での書き込みを許可するallow_writeable_chrootをYESにしておきます。

FTPログインを許可するユーザーを指定

ここではvsftpd.confのuserlist_denyがNOになっていることを前提にして進めます。

# 設定ファイルを編集する
$ sudo vi /etc/vsftpd/user_list

#/etc/vsftpd/user_list
ftp-user

設定を反映します

最後にvsftpdのサービスを再起動して、設定を反映させます。

$ sudo systemctl restart vsftpd

FTPのアクティブモード・パッシブモード

最後にFTP通信時の2つのモードについて違いを整理しておきたいと思います。FTP転送を設定しているところではパッシブモード利用が多いとは思いますが、稀にアクティブモードにしているところもあるため、違いについて理解を深めておきたいと思います。

アクティブモード・パッシブモード

アクティブモード

アクティブモードはサーバー側からクライアント側に接続する要求するモードになります。このモードは一般的に接続コネクションを21ポートを利用しデータ転送コネクションに20ポートを利用します。このモードはサーバー側からクライアント側に接続をするため、クライアント側の受信ポートの開放が必要になります。しかし、一般的な企業であれば、自社のFireWallが設けられており、外からのアクセスに対して厳しく制限を設けているところが多いことでしょう。そのため、このアクティブモードを利用して接続する際はクライアント側のFireWallに対しても穴をあける必要が出てきます。

パッシブモード

パッシブモードはクライアント側からサーバー側に接続を要求するモードになります。このモードは一般的に接続コネクションを21番ポートを利用し、データ転送コネクションはエフェメラルポートの中で毎回ランダムに振られたポートを使います。パッシブモードはサーバー側のポートを開放をておけば良いので、アクティブモードのようにクライアント側に影響を与えることはありません。

まとめ

今回はFTPについてまとめてみました。FTPサーバーを作るにあたっての手順は設定内容など比較的細かく記載したつもりではいますが、今回整理して思ったのは、やっぱりFTPは好んでは使いたいと思わないということでした。この理由は本文中にも何度か述べましたがセキュリティのリスクがあるからです。FTPが必須でないならば、SCPやSFTPなどのセキュアな転送方式を使って転送の仕組みを作られることをおすすめしたいです