CentOS8でサーバー構築 - 6.FTPサーバーの設定(vsftpd SSL/TLSなど)

以前にCentOS8でサーバー構築 - 1.環境設定でFTPを使えるようにはしましたが、
実際に運用するにはセキュリティーなどを強化してから使用することにします。
今回 Portは 12345、PASV_PORTは60000-60100、クライアントの公開鍵認証は無しで設定します。
ルータやパケットフィルタリング、firewallなどを開けておく事。
vsftpd: version 3.0.3、OpenSSL 1.1.1c です。
この組み合わせだとTLSv1.3で認証する。
(CentOS7では vsftpd: version 3.0.2、OpenSSL 1.0.2k-fips TLSv1.2で認証)
使用したクライアントソフトはFFFTP Ver 4.7、FileZilla 3.48.1
設定一覧
listen_port12345
anonymous_enableNO
匿名での接続を許可
dirmessage_enableNO
ディレクトリに.messageファイルがあれば表示
xferlog_file/var/log/vsftpd.log
xferlog_std_formatNO
NOにした場合は詳細なログを記載
ascii_upload_enableYES
アップロード時ASCIIモードでのデータ転送を許可
ascii_download_enableYES
ダウンロード時ASCIIモードでのデータ転送を許可
chroot_local_userYES
すべてのローカルユーザのログインをchrootで管理
ホームディレクトリの外側にアクセス不可
chroot_list_enableYES
chroot_local_user=YESの場合、chroot_list_fileで指定した
ユーザのみホームディレクトリの外側にアクセス可
chroot_list_file/etc/vsftpd/chroot_list
ここに記載のあるユーザのみホームディレクトリの外側にアクセス可
allow_writeable_chrootYES
YESにしないと、chroot_listに記載のないユーザは接続できなくなる
userlist_enableYES
userlist_fileを有効
userlist_denyNO
userlist_enable=YESの場合
YES: userlist_fileに記載されたユーザのログインを拒否
NO: userlist_fileに記載されたユーザのログインを許可
userlist_file/etc/vsftpd/allowed_user_list
userlist_deny=NOにしてある場合は、
ここに記載のあるユーザのみログインを許可
ssl_enableYES
SSL/TLSの設定を有効
ssl_tlsv1_2YES
TLSv1.2を利用可。TLSv1.3も利用する模様
ssl_ciphersHIGH
これを設定しないと、デフォルトのDES-CBC3-SHAになり、
使用するクライアントソフトによっては接続できないかも。
cipherを直接記載しても良い。
force_local_logins_sslYES
SSL/TLSを使用時のみユーザのログインを許可
force_local_data_sslYES
SSL/TLSを使用時のみデーター転送を許可
rsa_cert_file/etc/pki/tls/certs/vsftpd.pem
証明書のパス
Let's Encrypt などで証明書を取得済みの場合はそちらのパスを
debug_sslYES
SSL関連のログを記載
pasv_min_port60000
pasv_max_port60100
TLS1.0、TLS1.1には既に脆弱性が見つかっているので、TLS1.2以上の利用を推奨。

vsftpd.confの設定

マニュアルも一部追加で記載。
設定
# vi /etc/vsftpd/vsftpd.conf
# Allow anonymous FTP? (Beware - allowed by default if you comment this out).
anonymous_enable=NO
・
・
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
dirmessage_enable=NO
・
・
# You may override where the log file goes if you like. The default is shown
# below.
xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
xferlog_std_format=NO
・
・
# ASCII mangling is a horrible feature of the protocol.
ascii_upload_enable=YES
ascii_download_enable=YES
・
・
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
chroot_local_user=YES
chroot_list_enable=YES
# (default follows)
chroot_list_file=/etc/vsftpd/chroot_list
allow_writeable_chroot=YES
・
・
# When "listen" directive is enabled, vsftpd runs in standalone mode and
# listens on IPv4 sockets. This directive cannot be used in conjunction
# with the listen_ipv6 directive.
listen=YES
#
# This directive enables listening on IPv6 sockets. By default, listening
# on the IPv6 "any" address (::) will accept connections from both IPv6
# and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
# sockets. If you want that (perhaps because you want to listen on specific
# addresses) then you must run two copies of vsftpd with two configuration
# files.
# Make sure, that one of the listen options is commented !!
listen_ipv6=NO

pam_service_name=vsftpd
userlist_enable=YES
・
・ここから追加、デフォルトで有効無効になっているものも、明示的に記載在り
#
# This option is examined if userlist_enable is activated. If you set this
# setting to NO, then users will be denied login unless they are explicitly
# listed in the file specified by userlist_file. When login is denied, the
# denial is issued before the user is asked for a password. Default: YES
userlist_deny=NO
#
# This option is the name of the file loaded when the userlist_enable
# option is active. Default: /etc/vsftpd.user_list
userlist_file=/etc/vsftpd/allowed_user_list
#
# If enabled, vsftpd will display directory listings with the time in your
# local time zone. The default is to display GMT. The times returned by
# the MDTM FTP command are also affected by this option. Default: NO
use_localtime=YES
#
# If activated, files and directories starting with . will be shown in
# directory listings even if the "a" flag was not used by the client.
# This override excludes the "." and ".." entries. Default: NO
force_dot_files=NO
#
# When enabled, allows use of the SITE CHMOD command. NOTE! This
# only applies to local users. Anonymous users never get to use SITE CHMOD.
# Default: YES
chmod_enable=YES
#
# If vsftpd is in standalone mode, this is the port it will listen on
# for incoming FTP connections. Default: 21
listen_port=12345
#
# If enabled, and vsftpd was compiled against OpenSSL, vsftpd will support
# secure connections via SSL. This applies to the control connection (including
# login) and also data connections. You'll need a client with SSL support too.
# NOTE!! Beware enabling this option. Only enable it if you need it. vsftpd can
# make no guarantees about the security of the OpenSSL libraries. By enabling
# this option, you are declaring that you trust the security of your installed
# OpenSSL library. Default: NO
ssl_enable=YES
ssl_sslv2=NO
ssl_sslv3=NO
ssl_tlsv1=NO
ssl_tlsv1_1=NO
ssl_tlsv1_2=YES
#
# This option can be used to select which SSL ciphers vsftpd will allow for
# encrypted SSL connections. See the ciphers man page for further details.
# Note that restricting ciphers can be a useful security precaution as it
# prevents malicious remote parties forcing a cipher which they have found
# problems with. Default: DES-CBC3-SHA
ssl_ciphers=HIGH
#
# If set to yes, all SSL data connections are required to exhibit SSL session
# reuse (which proves that they know the same master secret as the control
# channel). Although this is a secure default, it may break many FTP clients,
# so you may want to disable it. For a discussion of the consequences, see
# http://scarybeastsecurity.blogspot.com/2009/02/vsftpd-210-released.html
# (Added in v2.1.0). Default: YES
require_ssl_reuse=YES
force_local_logins_ssl=YES
force_local_data_ssl=YES
rsa_cert_file=/etc/pki/tls/certs/vsftpd.pem
#
# If enabled, then any log output which would have gone to /var/log/vsftpd.log
# goes to the system log instead. Logging is done under the FTPD facility.
# default: NO
syslog_enable=NO
#
# If true, OpenSSL connection diagnostics are dumped to the vsftpd log file.
# (Added in v2.0.6). Default: NO
debug_ssl=YES
#
# The minimum port to allocate for PASV style data connections. Can be used
# to specify a narrow port range to assist firewalling. Default: 0 (use any port)
pasv_min_port=60000
pasv_max_port=60100
allow_writeable_chroot=YES にしないと環境により下記エラーが起こる。
500 OOPS: vsftpd: refusing to run with writable root inside chroot()
古いクライアントソフトだとデフォルト設定 require_ssl_reuse=YESの環境下では
上記英文のマニュアルで多くのFTPクライアントは壊れると言っているように
522 SSL connection failed: session reuse required
とファイルリストが表示されない事がある。
Let's Encrypt で証明書を取得済みの場合は
rsa_cert_file=/etc/letsencrypt/live/xxxxxxxxx.com/fullchain.pem
rsa_private_key_file=/etc/letsencrypt/live/xxxxxxxxx.com/privkey.pem

ユーザの設定

FTP接続を許可するユーザの追加
# echo "ユーザ名" >> /etc/vsftpd/allowed_user_list
ホームディレクトリ以外の参照を許可するユーザの追加
# echo "ユーザ名" >> /etc/vsftpd/chroot_list

SSL/TLS対応

有効期限は約10年に。
色々聞かれますが、何も記載せず[ENTER]でいけますが、ある程度は入力しておきましょう。
証明書の作製
# cd /etc/pki/tls/certs
# openssl req -x509 -nodes -newkey rsa:2048 -keyout vsftpd.pem -out vsftpd.pem -days 3650
Generating a 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) []:Chiba
Locality Name (eg, city) [Default City]:Funabashi
Organization Name (eg, company) [Default Company Ltd]:KOWLOONET.NET
Organizational Unit Name (eg, section) []:rhizome
Common Name (eg, your name or your server's hostname) []:kowloonet.net
Email Address []:メールアドレス。記載した場合接続したときに表示されます。
パーミッション変更
# chmod 400 vsftpd.pem
証明書の確認
# openssl x509 -text -noout -in /etc/pki/tls/certs/vsftpd.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            1f:81:8f:0e:d6:c1:da:f8:c7:6e:31:39:6d:dc:d4:2a:51:e8:60:f4
        Signature Algorithm: sha256WithRSAEncryption
・
・

再起動して確認

vsftpd再起動
# systemctl restart vsftpd
SSL/TLS接続の確認
# openssl s_client -connect localhost:12345 -starttls ftp
CONNECTED(00000003)
・
・
Peer signing digest: SHA256
Peer signature type: RSA-PSS
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3349 bytes and written 751 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
---
220 (vsFTPd 3.0.3)
---
Post-Handshake New Session Ticket arrived:
SSL-Session:
    Protocol  : TLSv1.3
    Cipher    : TLS_AES_256_GCM_SHA384
・
・
TLSv1.3の様です。ssl_tlsv1_2=YES だとTLSv1.2以上で利用可という事でしょうか。
よくわからず、今後の課題としておきます。
FTPクライアントソフトで確認
   割愛します。

以上でFTPの設定は終了です。

その他

FFFTPで接続時、下記の様なエラーが吐かれる。接続・転送などは特に問題なし。
調べてはみたものの、原因は不明。
FFFTPがTLS1.3に対応していないとかその辺??
Wed Jun 17 05:29:30 2020 [pid 9039] [ユーザ名] DEBUG: Client "xxx.xxx.xxx.xxx", "SSL ret: 18446744073709551615, SSL error: error:00000000:lib(0):func(0):reason(0), errno: 0"
証明書のパス rsa_cert_fileが正しくない時のエラー
500 OOPS: SSL: could not set cipher list
vsftpdがデフォルトで使用する暗号はDES-CBC3-SHAと記載されているが、サーバーには見当たらず。
CentOS8 OpenSSL 1.1.1c
# openssl ciphers -v | grep 'DES-CBC3-SHA'
#
試しにCentOS7では、
CentOS7.6 OpenSSL 1.0.2k-fips
# openssl ciphers -v | grep 'DES-CBC3-SHA'
ECDHE-RSA-DES-CBC3-SHA  SSLv3 Kx=ECDH     Au=RSA  Enc=3DES(168) Mac=SHA1
ECDHE-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH     Au=ECDSA Enc=3DES(168) Mac=SHA1
EDH-RSA-DES-CBC3-SHA    SSLv3 Kx=DH       Au=RSA  Enc=3DES(168) Mac=SHA1
EDH-DSS-DES-CBC3-SHA    SSLv3 Kx=DH       Au=DSS  Enc=3DES(168) Mac=SHA1
DH-RSA-DES-CBC3-SHA     SSLv3 Kx=DH/RSA   Au=DH   Enc=3DES(168) Mac=SHA1
DH-DSS-DES-CBC3-SHA     SSLv3 Kx=DH/DSS   Au=DH   Enc=3DES(168) Mac=SHA1
ECDH-RSA-DES-CBC3-SHA   SSLv3 Kx=ECDH/RSA Au=ECDH Enc=3DES(168) Mac=SHA1
ECDH-ECDSA-DES-CBC3-SHA SSLv3 Kx=ECDH/ECDSA Au=ECDH Enc=3DES(168) Mac=SHA1
DES-CBC3-SHA            SSLv3 Kx=RSA      Au=RSA  Enc=3DES(168) Mac=SHA1
KRB5-DES-CBC3-SHA       SSLv3 Kx=KRB5     Au=KRB5 Enc=3DES(168) Mac=SHA1
CentOS7.6 OpenSSL 1.0.2k-fips環境下で構築したftpに接続してみると、
TLSv1.2となる
# openssl s_client -connect localhost:21 -starttls ftp
CONNECTED(00000003)
depth=0 C = JP, L = Default City, O = Default Company Ltd, CN = kowloonet.local
verify error:num=18:self signed certificate
verify return:1
depth=0 C = JP, L = Default City, O = Default Company Ltd, CN = kowloonet.local
verify return:1
---
Certificate chain
 0 s:/C=JP/L=Default City/O=Default Company Ltd/CN=kowloonet.local
   i:/C=JP/L=Default City/O=Default Company Ltd/CN=kowloonet.local
---
Server certificate
-----BEGIN CERTIFICATE-----
・
・
-----END CERTIFICATE-----
subject=/C=JP/L=Default City/O=Default Company Ltd/CN=kowloonet.local
issuer=/C=JP/L=Default City/O=Default Company Ltd/CN=kowloonet.local
---
No client certificate CA names sent
Client Certificate Types: RSA sign, DSA sign, ECDSA sign
Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Shared Requested Signature Algorithms: RSA+SHA512:DSA+SHA512:ECDSA+SHA512:RSA+SHA384:DSA+SHA384:ECDSA+SHA384:RSA+SHA256:DSA+SHA256:ECDSA+SHA256:RSA+SHA224:DSA+SHA224:ECDSA+SHA224:RSA+SHA1:DSA+SHA1:ECDSA+SHA1
Peer signing digest: SHA512
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 1663 bytes and written 437 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 
・
・
---
ciphers表示
# openssl ciphers -v | sort
表示結果は割愛
ciphers ECDHEのみ表示
# openssl ciphers -v | grep ECDHE | sort
ECDHE-ECDSA-AES128-CCM  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESCCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(128) Mac=AEAD
ECDHE-ECDSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA256
ECDHE-ECDSA-AES128-SHA  TLSv1 Kx=ECDH     Au=ECDSA Enc=AES(128)  Mac=SHA1
ECDHE-ECDSA-AES256-CCM  TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESCCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=AESGCM(256) Mac=AEAD
ECDHE-ECDSA-AES256-SHA  TLSv1 Kx=ECDH     Au=ECDSA Enc=AES(256)  Mac=SHA1
ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH     Au=ECDSA Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-PSK-AES128-CBC-SHA256 TLSv1 Kx=ECDHEPSK Au=PSK  Enc=AES(128)  Mac=SHA256
ECDHE-PSK-AES128-CBC-SHA TLSv1 Kx=ECDHEPSK Au=PSK  Enc=AES(128)  Mac=SHA1
ECDHE-PSK-AES256-CBC-SHA TLSv1 Kx=ECDHEPSK Au=PSK  Enc=AES(256)  Mac=SHA1
ECDHE-PSK-CHACHA20-POLY1305 TLSv1.2 Kx=ECDHEPSK Au=PSK  Enc=CHACHA20/POLY1305(256) Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(128) Mac=AEAD
ECDHE-RSA-AES128-SHA256 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA256
ECDHE-RSA-AES128-SHA    TLSv1 Kx=ECDH     Au=RSA  Enc=AES(128)  Mac=SHA1
ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 Kx=ECDH     Au=RSA  Enc=AESGCM(256) Mac=AEAD
ECDHE-RSA-AES256-SHA    TLSv1 Kx=ECDH     Au=RSA  Enc=AES(256)  Mac=SHA1
ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 Kx=ECDH     Au=RSA  Enc=CHACHA20/POLY1305(256) Mac=AEAD