CentOSサーバーにFTPをインストール・設定する方法

vsftpdftplftpなどがインストールされているか確認

yum list installed | grep ftp
実行結果
ftp.x86_64                            0.17-67.el7                      @base
lftp.x86_64                           4.4.8-14.el7_9                   @updates
vsftpd.x86_64                         3.0.2-29.el7_9                   @updates

vsftpdは、FTPのサーバー
ftpは、FTPのクライアント
lftpは、FTPSのクライアント

上記のコマンドで何も表示されない場合は、ftpがインストールされていない

yum install vsftpd -y

vsftpdをインストール

systemctl status vsftpd
systemctl enable vsftpd
systemctl start vsftpd

vsftpdを自動起動に設定
vsftpdを起動

yum install ftp -y 

FTPクライアントをインストール

vsftpdの動作確認のときに使うだけなので、この作業は必須ではない

yum install lftp -y

FTPSクライアントをインストール

vsftpdの動作確認のときに使うだけなので、この作業は必須ではない

FTPサーバーのポートを変更する

FTPサーバーには、

  • リッスン用のポート
  • データ転送用のポート

の2種類のポートがある

リッスン用のポートは、FTPでログインするときに使うポート
デフォルトでは21

データ転送用のポートは、コネクション確立後(ログイン後)、実際のファイル転送に使われるポート
アクティブモードのときは20番ポート、
パッシブモードのときは、ポートはランダムに選択される
(デフォルトではパッシブモード)

vi /etc/vsftpd/vsftpd.conf

vsftpd.confに設定を書くと、ポートの変更などができる

echo "listen_port=10021" >> /etc/vsftpd/vsftpd.conf

vsftpd.confファイルの末尾に、
listen_port=10021を追加

リッスンポートが10021になる

echo "pasv_min_port=11000" >> /etc/vsftpd/vsftpd.conf
echo "pasv_max_port=11009" >> /etc/vsftpd/vsftpd.conf

データ転送用のポートを、1100011009の間に設定
通信時にこの中からランダムにポートが選ばれる

systemctl restart vsftpd

vsftpdのポート変更に伴い、ファイアウォールでもポートの変更が必須

ftp.xmlファイルをコピー

cp /usr/lib/firewalld/services/ftp.xml /etc/firewalld/services/

/usr/lib/firewalld/servicesディレクトリのftp.xmlファイルを
/etc/firewalld/servicesディレクトリにコピー

ftpポートを変更

リッスン用のポートを21から10021に変更

vi /etc/firewalld/services/ftp.xml
ftp.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>FTP</short>
  <description>FTP is a protocol used for remote file transfer. If you plan to make your FTP server publicly available, enable this option. You need the vsftpd package installed for this option to be useful.</description>
  <port protocol="tcp" port="21"/>
  <module name="nf_conntrack_ftp"/>
</service>

ftp.xml
というファイルで
21
の部分を
10021
に書き換え

ftpサービスを許可

firewall-cmd --add-service=ftp --permanent

ファイアウォールで、ftpサービスの通信を許可

firewall-cmd --add-port=11000-11009/tcp --permanent

1100011009の範囲でポートを開放

firewall-cmd --reload

リロードをしないと設定変更が反映しない

firewall-cmd --list-all
実行結果
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: ftp http https ssh
  ports: 11000-11009/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

servicesftpが、
ports11000-11009/tcpが表示されていればOK

wp-config.php抜粋(変更前)
define('FTP_HOST', 'localhost');
wp-config.php抜粋(変更前)
define('FTP_HOST', 'localhost:10021');

WordPressのwp-config.phpというファイルの中に
FTP_HOSTという項目がある場合は
ここにも変更したポートで通信するように設定を加える必要がある

ここの設定が適切でないと
WordPressの管理画面からWordPress本体の更新や
プラグインの追加・削除・更新などができない

hosts.denyというファイルを開く

vi /etc/hosts.deny

デフォルトではvsftpd : allの記述はないはずだが
既にvsftpd : allと書かれている場合は、一時的にコメントアウト
(動作確認が終わったら、コメントアウトを解除する)

hosts.denyでは
サービス名 : IPアドレスのペアで1行となっていて
指定されたIPアドレスから該当のサービスへの接続を禁止できる

vsftpd : allと書かれていれば、すべてのIPアドレスからのvsftpdへの接続が禁止になっている

ftp localhost 10021
実行結果
Trying ::1...
Connected to localhost (::1).
220 (vsFTPd 3.0.2)
Name (localhost:root): user1
331 Please specify the password.
Password:
230 Login successful.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp>

プロンプトが出てくるので
Nameにユーザー名
Passwordにパスワードを入力してログインする

230 Login successful.のような表示があれば、ログインに成功している

ログイン後の操作

ftp> pwd
257 "/home/user1"
ftp>

ログインに成功していれば、
ftp>プロンプトでpwdlsなどのコマンドが実行できる

権限が不足しているとpwdはできるけどlsはエラーになったりもする

FTPを終了

quit

quitまたはexitコマンドで、FTP接続を終了する

rootユーザーでのログインを禁止する

デフォルトではrootユーザーでのログインは禁止になっている

ftp localhost 10021
実行結果
Trying ::1...
Connected to localhost (::1).
220 (vsFTPd 3.0.2)
Name (localhost:root): root
530 Permission denied.
Login failed.
ftp>

rootでログインしようとすると
530 Permission denied.
Login failed.
と表示される

これは、/etc/vsftpd/user_listというファイルでrootユーザーのftp使用が禁止されているから

user_list
# vsftpd userlist
# If userlist_deny=NO, only allow users in this file
# If userlist_deny=YES (default), never allow users in this file, and
# do not even prompt for a password.
# Note that the default vsftpd pam config also checks /etc/vsftpd/ftpusers
# for users that are denied.
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
news
uucp
operator
games
nobody
user_listを禁止リストに設定する方法

/etc/vsftpd/vsftpd.confというファイルで
userlist_deny=YESと設定した場合、もしくはuserlist_denyの項目がない場合は
user_listは禁止リストとして働く

user_listを許可リストに設定する方法

userlist_deny=NOと設定した場合は
user_listは許可リストとして働く

デフォルトではuser_listは禁止リスト

デフォルトではuserlist_denyの項目がない

user_listは禁止リストとして働くので
user_listにリストされているrootユーザーはftpを使用できない

ftp
ftp> open 192.168.100.2 10021

サーバーのコンソールからではなく
ローカルのPC上でコマンドプロンプトを起動し
ftpと打つと
ftp>というプロンプトが出現する

open IPアドレス ポートのように打つと、
ローカルでftpコマンドを実行したときのように
ユーザー名やパスワードの入力をしてログインできる

ログインできないようであれば、ファイアウォールの設定などに問題がある可能性が高い

vi /etc/vsftpd/vsftpd.conf

vsftpd.confというファイルに設定を書くことで、vsftpd(FTPサーバー)の設定を変更できる

vsftpd.conf抜粋(変更前)
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=YES
vsftpd.conf抜粋(変更後)
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO

vsftpd.conf
というファイルの
anonymous_enable=YES
という部分を
anonymous_enable=NO
に変更

上記の設定により、匿名ユーザーでのログインができなくなる

/etc/vsftpd/user_listファイルは
デフォルトでは禁止リストとなっているので
これを許可リストへと変更する

echo "userlist_deny=NO" >> /etc/vsftpd/vsftpd.conf

vsftpd.confというファイルの末尾に
userlist_deny=NOという設定を追加する

vsftpd.conf
userlist_deny=NOが設定してある場合
/etc/vsftpd/user_listは許可リストとして機能する

userlist_deny=YESが設定してある場合、またはuserlist_denyの項目がない場合
/etc/vsftpd/user_listは禁止リストとして機能する

ちなみにuserlist_enable=YESという記述がないとuser_listがそもそも発動しないので禁止にも許可にもならないが
userlist_enable=YESは、もともとvsftpd.confに記載がある

vi /etc/vsftpd/user_list

下記のようなユーザーが列挙されているので全削除

user_list
root
bin
daemon
adm
lp
sync
shutdown
halt
mail
news
uucp
operator
games
nobody

FTPで利用するユーザーだけをuser_listに記載する

user_list
kusanagi
user1

上記の例だと、kusanagiuser1というユーザーにFTPの利用を許可している
それ以外のユーザーはFTPが利用できなくなる

各自の環境に合わせてuser_listにユーザー名を列挙する

ただし、rootユーザーにFTP接続を許可することはおすすめしない

万が一、rootのパスワードが流出した場合
rootでFTP接続してデータを盗まれたり、サーバー内の全データを削除されるなど、取り返しのつかないことになるリスクがある

systemctl restart vsftpd

vsftpd.confの設定を変更した場合、vsftpdサービス再起動のタイミングで設定が反映する

user_listの編集だけのときは、再起動不要

CentOS8ではhosts.denyとhosts.allowがなくなっているので注意
その話はファイアウォールでIPアドレスを制限(CentOS8)を参照

ここではCentOS7の話をする

hosts.denyの設定

vi /etc/hosts.deny

hosts.denyを開く


hosts.denyというファイルに、
vsftpd : all
という1行を追加する

hosts.deny
vsftpd : all

vsftpdに対してall(すべてのIPアドレス)からの接続を拒否する

別途hosts.allowで許可するIPアドレスだけを指定する

hosts.allowの設定

vi /etc/hosts.allow

hosts.allowを開く


hosts.allowに下記の設定を追加

hosts.allow
vsftpd : localhost
vsftpd : 127.0.0.1
vsftpd : xx.xx.xx.xx

実際にはxx.xx.xx.xxの部分には具体的な数値を記入する
自宅からサーバーにftpで接続したい場合は、自宅PCのグローバルIPアドレスがxx.xx.xx.xxの部分に入る

サーバーからサーバー(自分自身)へのアクセスを許可するためにlocalhost127.0.0.1も許可する

hosts.denyとhosts.allowの優先順位

hosts.denyhosts.allowでは、hosts.allowの方が優先される
よって、hosts.denyで全禁止となっていても、hosts.allowで許可したIPアドレスからはvsftpdへ接続可能

opensslがインストールされていることを確認

openssl version
実行結果
OpenSSL 1.0.2k-fips  26 Jan 2017

opensslのバージョンを確認

バージョン情報が出てこない場合は、opensslがインストールされていない

opensslをインストール

opensslがインストールされていない場合は、自分でインストールする
インストール済みならこのステップは不要

yum install openssl -y

上記のコマンドでopensslがインストールされる

opensslの証明書を作成

cd /etc/pki/tls/certs
openssl req -x509 -nodes -newkey rsa:2048 -days 36500 -keyout vsftpd.pem -out vsftpd.pem

/etc/pki/tls/certsディレクトリに移動して
openssl reqコマンドを実行している

実行結果
Generating a 2048 bit RSA private key
....................................................................................+++
...................+++
writing new private key to 'vsftpd.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:JP
State or Province Name (full name) []:Tokyo
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (eg, your name or your server's hostname) []:
Email Address []:

openssl reqコマンドを実行すると対話モードが始まる

  • Country Name (2 letter code) [XX]: JP
  • State or Province Name (full name) []: Tokyo
  • Locality Name (eg, city) [Default City]:
  • Organization Name (eg, company) [Default Company Ltd]:
  • Organizational Unit Name (eg, section) []:
  • Common Name (eg, your name or your server's hostname) []:
  • Email Address []:

Country NameJP
State or Province NameTokyo
その他の項目は空欄でOK


vsftpd.pemの中身

openssl reqコマンドの実行により、vsftpd.pemというファイルが生成される

vsftpd.pemの中身は、
PRIVATE KEY(秘密鍵)と
CERTIFICATE(証明書)が連結されたもの

vsftpd.pem
-----BEGIN PRIVATE KEY-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-----END CERTIFICATE-----

opensslのコマンドオプション

コマンドオプションは下記のとおり
req: 証明書の署名要求(CSR)の作成
-x509: X.509形式の署名要求ファイルを作成する
-nodes: 鍵ファイルは暗号化しない
-newkey rsa:2048: RSA2048の秘密鍵を作成
-days 36500: X.509形式の証明書の有効期限を36500日(100年)とする
-keyout filename: 秘密鍵の出力先ファイル名
-out filename: サーバ証明書(CRT)出力先ファイル名

echo "ssl_enable=YES" >> /etc/vsftpd/vsftpd.conf
echo "rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem" >> /etc/vsftpd/vsftpd.conf
echo "force_local_logins_ssl=NO" >> /etc/vsftpd/vsftpd.conf
echo "force_local_data_ssl=NO" >> /etc/vsftpd/vsftpd.conf

vsftpd.confというファイルに、下記の4行を追加

vsftpd.conf
ssl_enable=YES
rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem
force_local_logins_ssl=NO
force_local_data_ssl=NO

FTP over SSL/TLSを有効化

証明書のパスを指定
(さきほどopensslで作成したもの)

ssl_enable=YESを設定すると、FTPSで接続できるようになる代わりに、FTPでは接続できなくなる

force_local_logins_ssl=NOforce_local_data_ssl=NOにより
ローカル接続のときだけは、FTPSではなくFTP接続を許可する

FTPSはFTPよりも遅い
そのため、WordPressでプラグインの削除をするときに、FTPSだとタイムアウトでエラーになることがある
(WordPressはプラグインのアンインストールのときに、FTPでファイルを削除している)
ローカルでは、FTPS必須ではなくFTP接続できるように許可することで、この問題は解決する

systemctl restart vsftpd

vsftpd.confを書き換えた後は、vsftpdサービスの再起動が必要

lftp(FTPSクライアント)の設定を変更する

ユーザーを切替

su user1

rootなどで作業中だった場合は、FTPSを利用するユーザーに切り替え


.lftprcを作成

vi ~/.lftprc

.lftprcというファイルを新規作成
.lftprcに以下を記載

.lftprc
set ftp:ssl-auth TLS
set ftp:ssl-force true
set ftp:ssl-allow yes
set ftp:ssl-protect-list yes
set ftp:ssl-protect-data yes
set ftp:ssl-protect-fxp yes
set ssl:verify-certificate no
set ssl:check-hostname no

.lftprcファイルは、lftpでFTPS接続するときのクライアントのパラメーターを指定するもの

lftp -d -u user1 localhost:10021

-dはデバッグモードのオプション
-uはユーザー名を指定するオプション

実行結果
パスワード:
lftp user1@localhost:~> ls
---- localhost (::1) ポート 10021 に接続中
<--- 220 (vsFTPd 3.0.2)
---> FEAT
<--- 211-Features:
<---  AUTH TLS
<---  EPRT
<---  EPSV
<---  MDTM
<---  PASV
<---  PBSZ
<---  PROT
<---  REST STREAM
<---  SIZE
<---  TVFS
<---  UTF8
<--- 211 End
---> AUTH TLS
<--- 234 Proceed with negotiation.
---> OPTS UTF8 ON
Certificate: C=JP,ST=Tokyo,L=Default City,O=Default Company Ltd,CN=example.com
 Issued by: C=JP,ST=Tokyo,L=Default City,O=Default Company Ltd,CN=example.com
WARNING: Certificate verification: Not trusted
WARNING: Certificate verification: hostname checking disabled
<--- 200 Always in UTF8 mode.
---> USER user1
<--- 331 Please specify the password.
---> PASS XXXX
<--- 230 Login successful.
---> PWD
<--- 257 "/home/user1"
---> PBSZ 0
<--- 200 PBSZ set to 0.
---> PROT P
<--- 200 PROT now Private.
---> PROT P
<--- 200 PROT now Private.
---> EPSV
<--- 229 Entering Extended Passive Mode (|||11001|).
---- データソケットを (::1) のポート 11001 に接続中
---- Data connection established
---> LIST
<--- 150 Here comes the directory listing.
Certificate: C=JP,ST=Tokyo,L=Default City,O=Default Company Ltd,CN=example.com
 Issued by: C=JP,ST=Tokyo,L=Default City,O=Default Company Ltd,CN=example.com
WARNING: Certificate verification: Not trusted
WARNING: Certificate verification: hostname checking disabled
-rw-rw-r--    1 1000     1000           15 Jul 11 08:55 test.txt
---- Got EOF on data connection
---- データソケットを閉じています
<--- 226 Directory send OK.
lftp user1@localhost:~>

パスワードの入力を求められる
パスワード入力すると、
lftp user1@localhost:~>
のようなプロンプトが現れる

lsなどのコマンドを実行して、ファイルの一覧が表示されればFTPSは機能している

lftpでログインし、lsなどのコマンドを実行したタイミングで、下記のようなエラーが出ることがある

実行結果
ERROR: Certificate verification: Not trusted
ERROR: Certificate verification: certificate common name doesn't match requested host name ‘localhost’

これは、opensslコマンドで証明書を作成するときに
COMMON NAMEexample.comを指定したのに
lftp -d -u user1 localhost:10021コマンドではlocalhostに接続しているため

example.comlocalhostで名前が一致しないためにエラーとなる

.lftprcファイルに
set ssl:check-hostname noを記載するとエラーは出なくなる

たとえば、2021年1月1日 12時00分にFTPでファイルをアップロードしたとする

ファイルの最終更新時刻が、
FileZillaのようなFTPクライアントで見ると、2021年1月1日 12時00分になっているが、
サーバー上でls -laのようなコマンドでファイルの情報を見ると、2021年1月1日 3時00分のようにGMTで表示されてしまうことがある
(FTPクライアントの表示は正常、サーバー上で時刻ずれ)

また、FileZillaのようなFTPクライアントで見ると、2021年1月1日 21時00分になり、
サーバー上では、2021年1月1日 12時00分のようになる場合もある
(FTPクライアントで時刻ずれ、サーバー上の表示は正常)

そのような場合は、vsftpd.confuse_localtime=YESを設定すると状態が改善されるかもしれない

echo "use_localtime=YES" >> /etc/vsftpd/vsftpd.conf

systemctl restart vsftpd

vsftpd.confというファイルの末尾に、
use_localtime=YES
という1行を追加している

もともと時刻のずれが発生していない場合は、
この設定をすると時刻がずれる

サーバー側、クライアント側のタイムゾーンが共に日本時間になっていれば、おそらくこの設定は必要ない
サーバー側とクライアント側のタイムゾーンの設定が一致していない場合に必要な設定

  • 最終更新: 2023/05/25 14:09