0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

lftpで"Fatal error: gnutls_record_recv: An unexpected TLS packet was received." の対処法

Last updated at Posted at 2025-05-11

状況の説明

下記の投稿を確認してください。

環境

ローカルOS: WSLのUbuntu-24.04
リモートOS: Amazon Linux 2023
vsftpd: version 3.0.5
openssl 3.0.8

仮説 1

サーバー側のOpenSSLで設定している暗号化スイートとは異なる暗号化スイートを使用し、lftpがGnuTLSでFTPS接続しようとしているため、再ネゴシエーションが拒否される

確認すること (その 1)

暗号化スイート(vsftpd、httpd)と TLSプロトコルバージョン (gnutls)の設定を確認

Step1. opensslコマンドで確認

サーバー側でopenssl s_server コマンドを使用し、サーバー証明書と秘密鍵を指定し、特定の暗号化スイートをテストします。

.bash
sudo openssl s_server -cert /etc/pki/tls/certs/localhost.pem -key /etc/pki/tls/private/localhost.key -port 443 -ciphersuites ECDHE-ECDSA-AES128-GCM-SHA256
-www
Call to SSL_CONF_cmd(-ciphersuites, ECDHE-ECDSA-AES128-GCM-SHA256) failed
805BBA0CB77F0000:error:0A0000B9:SSL routines:set_ciphersuites:no cipher match:ssl/ssl_ciph.c:1345:

右記、man openssl s_server によるこのコマンドの説明です。「このコマンドは、SSL/TLS を使用して指定されたポートで接続をListenする汎用 SSL/TLS サーバーを実装します。」

This command implements a generic SSL/TLS server which listens for connections on a given port using SSL/TLS.

今回暗号化スイートは ECDHE-ECDSA-AES128-GCM-SHA256 を指定しました。上記のopenssl s_serverの実行結果を見ると、failedとなっています。その下の行には、no cipher match (一致する暗号化スイートがありません)というエラーメッセージが表示されているのが分かります。

Step2. サーバーの設定を確認

暗号化スイートを確認します。openssl s_server はhttpdのポート番号443を指定して確認しましたので、まずはhttpdの設定ファイルで暗号化スイートを確認してみます。

/etc/httpd/conf.d/ssl.conf
# みやすいように改行していますが、実際にはコロンで連結し、一行で設定しています。
SSLCipherSuite          
          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256
          :ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
          :DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384
          :DHE-RSA-CHACHA20-POLY1305

httpdの設定では ECDHE-ECDSA-AES128-GCM-SHA256が設定されています。これはさきほどopensslコマンドでテストしてfailedとなった暗号化スイートです。なのでこの暗号化スイートでのTLS接続が失敗している、ということになります。コロン (:) で後ろに連結して設定しているほかの暗号化スイートも総当たりで openssl s_serverコマンドで確認してみましたが、すべてfailedとなりました。

httpsではじまるURLにブラウザからアクセスはできているのに、openssl s_serverで確認したら failedになっているのは、何かがおかしいということです。暗号化スイートあたりの設定が原因かもしれません。
no cipher match (一致する暗号化スイートがありません)ということですので、上記の/etc/httpd/conf.d/ssl.confとは別に、設定が必要なファイルがある(設定ファイルじたいが違うとか)か、設定ファイルのパスが違うとかなのかもしれません。

Step3. vsftpdの設定を確認

ついでに、vsftpdも同じように設定されているのか、確認してみます。

/etc/vsftpd/vsftpd.conf
ssl_ciphers=kEECDH+AESGCM+AES128:kEECDH+AESGCM:kEECDH+AES128:kEECDH+AES:!aNULL:!eNULL:!LOW:!EXP

こちらはECDHAES128GCMなどの文字列は見えますが、ECDSASHA256の文字列は見えません。そのあたりの設定が必要なのかもしれません。この場合、次の節でvsftpdの設定を修正する必要があります。

openssl s_servervsftpd.confkEECDH+AESGCMに対応させて暗号化スイートをECDHE-AES-GCMと指定してみましたが、やはりこちらもfailedとなってしまいます。また、Step1-port 443 に対してテストしたのと同様、no cipher match (一致する暗号化スイートがありません)というエラーメッセージが表示されています。

.bash
sudo openssl s_server -cert /etc/pki/tls/certs/localhost.pem -key /etc/pki/tls/private/localhost.key -port 21 -ciphersuites ECDHE-AES-GCM -www
Call to SSL_CONF_cmd(-ciphersuites, ECDHE-AES-GCM) failed
809BEA0DFB7F0000:error:0A0000B9:SSL routines:set_ciphersuites:no cipher match:ssl/ssl_ciph.c:1345:

Step 4. 【任意】gnutlsの設定を確認 (クライアントがgnutlsを使用している場合)

gnutlsの設定ファイルのdisabled-versionでtls1.2以外を無効化します(TLS v1.2の暗号化スイートを使用する場合)。また、default-priority-stringで優先するプロトコルバージョンを指定します。※ただし、すでにvsftpdやopensslなどで同様の設定をしていると仮定します

/etc/gnutls/config.ini
[overrides]
disabled-version = tls1.0
disabled-version = tls1.1
disabled-version = tls1.3
disabled-version = dtls0.9
disabled-version = dtls1.0
default-priority-string = NORMAL:-VERS-TLS-ALL:+VERS-TLS1.

上記設定で、openssl s_serverでTLS v1.2以外がはじかれるかどうか見てみました。error:80000062:system library:BIO_bind:Address already in use:crypto/bio/bio_sock2.cerror:10000075:BIO routines:BIO_bind:unable to bind socket:crypto/bio/bio_sock2.cというメッセージが表示されています。

ちなみに下記の対処法 (その 1)を行った結果も、同じエラーが出てきます。その対処法で、解決できましたのでそちらを確認してください。

タイトルとは別のエラーになりますので、このエラーメッセージについて詳しいことは割愛します。

.bash
sudo openssl s_server -cert /etc/pki/tls/certs/localhost.pem -key /etc/pki/tls/private/localhost.key -port 21 -no_tls1_2 -www
Using default temp DH parameters
805BC68C8D7F0000:error:80000062:system library:BIO_bind:Address already in use:crypto/bio/bio_sock2.c:176:calling bind()
805BC68C8D7F0000:error:10000075:BIO routines:BIO_bind:unable to bind socket:crypto/bio/bio_sock2.c:178:
   0 items in the session cache
   0 client connects (SSL_connect())
   0 client renegotiates (SSL_connect())
   0 client connects that finished
   0 server accepts (SSL_accept())
   0 server renegotiates (SSL_accept())
   0 server accepts that finished
   0 session cache hits
   0 session cache misses
   0 session cache timeouts
   0 callback cache hits
   0 cache full overflows (128 allowed)   

対処法 (その 1)

httpdとvsftpdの暗号化スイートの設定を見直す

Step 1. httpdの暗号化スイートの設定

HTTPSの設定でまず思ったのが、Apacheのmod_sslの設定が十分なのかということ。そもそも httpdのSSLの設定(/etc/httpd/conf.d/ssl.conf)と、mod_sslの設定がリンクしているのかが分かっていませんでした。
Copilot (MicrosoftのChatgpt)にきくと、その認識でいいということでした。(詳しくは調べていません)なのでこれはスルーします。

Step 2. vsftpdの暗号化スイートの設定を確認

FTPSの方は、以下のようにvsftpd.confに OpenSSL方式で指定していますが、その文法や一つ一つの要素がちゃんと理解できていませんでした。

vsftpd.conf
# 元々設定ファイルに記載していた内容
# ※ 不十分のため本投稿で修正します (後述)
ssl_ciphers=kEECDH+AESGCM+AES128:kEECDH+AESGCM:kEECDH+AES128:kEECDH+AES:!aNULL:!eNULL:!LOW:!EXP

また、前の節での仮定に対する確認事項で、Step 4. に書いてあるように、ECDSASHA256の設定が必要なのかもしれません。この節ではそこを確認し直します。

追記 (2025/5/12)
ECDSAで署名していたと勘違いして思っていましたが、あとでRSAで署名し直したことを思い出したため、ECDHを含む暗号化スイートを使用しないように投稿の内容を修正しました。

Step 3. 暗号化スイートをリストアップ

設定したい暗号化スイートを openssl ciphers -v でリストアップします。パラメータの書き方は、+で、複数の暗号化スイート (AESやECDHE)の要素を連結します。:でいろんな組み合わせ (ECDHEやRSA)を指定できます。:+で、リストの末尾 (優先順位を最下位にする)にとばします。たとえば、:+AES256で、AES256を含むものはリストの末尾にいどうします。

.bash
# **こちらを実行(追記:2025/5/12)**
sudo openssl ciphers -v 'AESGCM+ECDHE+aRSA:CHACHA20+ECDHE+aRSA:+AES256'
TLS_AES_256_GCM_SHA384         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(256)            Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256   TLSv1.3 Kx=any      Au=any   Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESGCM(128)            Mac=AEAD
TLS_AES_128_CCM_SHA256         TLSv1.3 Kx=any      Au=any   Enc=AESCCM(128)            Mac=AEAD
ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(256)            Mac=AEAD
ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2 Kx=ECDH     Au=RSA   Enc=AESGCM(128)            Mac=AEAD
ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2 Kx=ECDH     Au=RSA   Enc=CHACHA20/POLY1305(256) Mac=AEAD

# 【参考情報】本投稿の修正前のパラメータにつき、読み飛ばし推奨(追記:2025/5/12)
sudo openssl ciphers -v 'AESGCM+ECDHE:AESGCM+DHE+aRSA:CHACHA20+ECDHE:CHACHA20+DHE:+AES256
'

Step 4. 暗号化スイートの設定 (httpdとvsftpd)

httpd

/etc/httpd/conf.d/ssl.conf
# **こちらを入力**(追記:2025/5/12)
SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384

# 【参考情報】本投稿の修正前のパラメータにつき、読み飛ばし推奨(追記:2025/5/12)
SSLCipherSuite          ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384

vsftpd

/etc/vsftpd/vsftpd.conf
# **こちらを入力**(追記:2025/5/12)
ssl_ciphers=AESGCM+ECDHE+aRSA:CHACHA20+ECDHE+aRSA:+AES256

# 【参考情報】本投稿の修正前のパラメータにつき、読み飛ばし推奨(追記:2025/5/12)
ssl_ciphers=AESGCM+ECDHE:AESGCM+ECDHE+aRSA:AESGCM+DHE+aRSA:CHACHA20+ECDHE:CHACHA20+DHE:+AES256
/etc/vsftpd/vsftpd.conf
# または、明示的に安全でないものを除外
ssl_ciphers=AESGCM+ECDHE+aRSA:CHACHA20+ECDHE+aRSA:!aNULL:!eNULL:!LOW:!EXP:+AES256

vsftpdを再起動

.bash
sudo systemctl restart vsftpd.service

opensslコマンドで確認

.bash
# TLSv1.2の暗号化スイートを使用する場合、-cipherをつける
# -ciphersuitesをつけると、TLSv1.3で利用可能な暗号化スイートを使用する
sudo openssl s_server -cert /etc/pki/tls/certs/localhost.pem -key /etc/pki/tls/private/localhost.key -port 21 -cipher ECDHE-ECDSA-AES128-GCM-SHA256
Using default temp DH parameters
800BCA6C877F0000:error:80000062:system library:BIO_bind:Address already in use:crypto/bio/bio_sock2.c:176:calling bind()
800BCA6C877F0000:error:10000075:BIO routines:BIO_bind:unable to bind socket:crypto/bio/bio_sock2.c:178:
   0 items in the session cache
   0 client connects (SSL_connect())
   0 client renegotiates (SSL_connect())
   0 client connects that finished
   0 server accepts (SSL_accept())
   0 server renegotiates (SSL_accept())
   0 server accepts that finished
   0 session cache hits
   0 session cache misses
   0 session cache timeouts
   0 callback cache hits
   0 cache full overflows (128 allowed)

"Address already in use" というエラーが出る
openssl s_serverコマンドで確認すると、
error:80000062:system library:BIO_bind:Address already in use:crypto/bio/bio_sock2.cerror:10000075:BIO routines:BIO_bind:unable to bind socket:crypto/bio/bio_sock2.cというメッセージが表示されています。

そこで、21番ポートをnetstatとlsofで確認してみると、以下のようになりました。

.bash
# 21番ポートでLISTENしている
sudo netstat -nao | grep ":21"
tcp6       0      0 :::21                   :::*                    LISTEN      off (0.00/0/0)

# vsftpがLISTENしている
sudo lsof -i :21
COMMAND     PID USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
vsftpd  2751136 root    4u  IPv6 16715547      0t0  TCP *:ftp (LISTEN)

ファイアウォールは以下。

.bash
sudo firewall-cmd --permanent --list-all
public
  target: default
  icmp-block-inversion: no
  interfaces:
  sources:
  services: dhcpv6-client https mdns ssh
  ports: 80/tcp 443/tcp xxxxx-xxxxx/tcp 21/tcp # 21番ポートを許可 (xxxはパッシブモードのポート範囲)
  protocols:
  forward: yes
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

21番を使用している vsftpdのプロセスIDを指定して、ポートを解放します。

.bash
#  vsftpdのプロセスを強制終了
sudo kill -9 2751136
# 再び確認
sudo lsof -i :21
sudo netstat -nao | grep ":21" # 21番ポートが解放され、LISTENもしていない
# 再び TLS v1.2の暗号化スイートでのSSL接続を確認
sudo openssl s_server -cert /etc/pki/tls/certs/localhost.pem -key /etc/pki/tls/private/localhost.key -port 21 -cipher ECDHE-ECDSA-AES128-GCM-SHA256
Using default temp DH parameters
ACCEPT # 無事、接続が受け付けられた
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?