1.概要
運用中のシステムでリプレース等の理由で、過去のOSを使わなければいけない。。。
なんてことはよくある話かと思います。
今回はFTPS通信を行った時に、Windows8.1のみで何故かエラーになってしまう
という謎の現象を解決した話になります。
2.動作環境
サーバー
OS:CentOS8
vsftpd:バージョン3.0.3
証明書:あり(正規に認証されたもの)
クライアント
OS:Windows8.1
アプリケーション:自作(.net Framework4.5ターゲット)
FTPモジュール:FluentFTP
暗号化プロトコルはTLS1.2です。
3.エラーの内容
アプリケーションが出力したログは下記のとおり
System.Security.Authentication.AuthenticationException: SSPI への呼び出しに失敗しました。内部例外を参照してください。 ---> System.ComponentModel.Win32Exception: 予期されない、または形式が間違ったメッセージを受信しました。 --- 内部例外スタック トレースの終わり --- 場所 System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception) 場所 System.Net.Security.SslState.StartSendBlob(Byte incoming, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.ProcessReceivedBlob(Byte buffer, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.StartReceiveBlob(Byte buffer, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.StartSendBlob(Byte incoming, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.ProcessReceivedBlob(Byte buffer, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.StartReceiveBlob(Byte buffer, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.StartSendBlob(Byte incoming, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.ProcessReceivedBlob(Byte buffer, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.StartReceiveBlob(Byte buffer, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.StartSendBlob(Byte incoming, Int32 count, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest) 場所 System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult) 場所 FluentFTP.FtpSocketStream.ActivateEncryption(String targethost, X509CertificateCollection clientCerts, SslProtocols sslProtocols) 場所 FluentFTP.FtpClient.Connect()
FluentFTPが出力したログは下記のとおり
# Connect() Status: Connecting to ***.***.***.***:*** Response: 220 (vsFTPd 3.0.3) Status: Detected FTP server: VsFTPd Command: AUTH TLS Response: 234 Proceed with negotiation. Status: Disposing FtpSocketStream... Error: FTPS Authentication Failed
ログをみる限り、クライアントがサーバーに接続する段階で
暗号化によるエラーが発生しているようです。
過去にも別の原因で同様のエラーが発生していました。
解決記事は下記を参照
www.chuken-engineer.com
4.解決方法
原因はわかれば単純ですが、結構な時間を費やしてしまいました。。。
【vsftpd.conf】に下記を追加しました。
ssl_ciphers=HIGH
5.原因
ssl_ciphers=HIGH
は何の設定なのかと言うと
みたいなニュアンスかと思います。
これを設定しないとデフォルトで
単純に考えると今回不具合が起きたWindows8.1環境では
これにより接続が出来なくなったと思われますが
Windows8.1のせいではなく、環境依存の可能性が高いのかな?と思ったりもします。
6.おまけ
自作アプリケーションのコードが悪いのかと思い
一般的なFTPクライアントソフトでも試してみました。
使ったソフトは
・FFFTP
・FileZilla
の二つです。
結果は
・FFFTPは接続失敗・・・
・FileZillaは接続成功!
という結果になりました。
一体何が違うのかというと
【SChannel】か【openSSL】
かの違いのようです。
FluentFTPも【SChannel】のようですので
またひとつ勉強になりました。