エラーメッセージ
SSL routines:tls_validate_record_header:wrong version number
別の表記
- error:0A00010B:SSL routines:ssl3_get_record:wrong version number
- error:0A00010B:SSL routines::wrong version number
- error:1408F10B:SSL routines:ssl3_get_record:wrong version number
関数名は、OpenSSL 3.5 では tls_validate_record_header、OpenSSL 3.0 では ssl3_get_record(「error:0A00010B:SSL routines:ssl3_get_record:wrong version number」)です。OpenSSL 1.1.1 は古いコード 1408F10B を使います。関数名を含めずにエラーを整形するアプリケーション(curl や Node.js のメッセージ)は、「error:0A00010B:SSL routines::wrong version number」と出力します。「error:」の前の接頭辞はスレッド ID、末尾の接尾辞はソースコード上の位置で、どちらも一定ではありません。
OpenSSL 3 (openssl s_client and any OpenSSL-based client) — SSL_R_WRONG_VERSION_NUMBER
このエラーの意味
OpenSSL は TLS レコードを想定してヘッダーのプロトコルバージョンフィールドをチェックしましたが、受信したバイト列はそもそも TLS ではありませんでした。多くの場合、HTTP レスポンスの先頭やメールサーバーが送るテキストのグリーティングが、バージョン番号であるかのように読み取られています。この名前は誤解を招きます。原因はサポートされていない TLS バージョンではなく、相手側がそのポートで別のプロトコル(または平文)で通信していることです。
発生する理由
ポートが平文の HTTP や、ほかの平文のプロトコルで応答している
よくある80/8080 番ポートの HTTP、TLS を終端するプロキシの背後にあるバックエンド、TLS のリスナーが別のポートにあるサービスなどが該当します。
STARTTLS のポートに暗黙的 TLS で接続した
よくあるSMTP(25 番、587 番)、IMAP(143 番)、POP3(110 番)、LDAP(389 番)、PostgreSQL、MySQL、XMPP は平文で通信を開始し、要求に応じて TLS に切り替えます。最初から TLS ハンドシェイクを行うと、これらのグリーティングは意味のないデータとして読み取られます。
プロキシやキャプティブポータルが平文で応答している
ときどき平文の HTTP プロキシに対して https:// のプロキシ URL を設定したクライアントや、接続を横取りするネットワークでは、TLS を想定していたところに HTTP が返ってきます。
修正方法
- 1.
同じ接続内でアップグレードするプロトコルには -starttls を使う
openssl s_client は smtp、imap、pop3、ftp、xmpp、ldap、postgres、mysql などに対応しています。このオプションを使うと、プロトコルのアップグレードコマンドの後に TLS ハンドシェイクが始まります。
bash # Protocols that upgrade in-band need -starttls openssl s_client -connect mail.example.com:587 -starttls smtp -servername mail.example.com </dev/null openssl s_client -connect db.example.com:5432 -starttls postgres </dev/null openssl s_client -connect ldap.example.com:389 -starttls ldap </dev/null - 2.
ポートが実際に何を送信しているかを確認する
netcat でテキストのバナーや HTTP のステータス行が表示されれば、そのポートは暗黙的 TLS ではありません。
bash # What does the port answer with? A readable banner means it is not TLS printf 'HEAD / HTTP/1.0\r\n\r\n' | timeout 3 nc api.example.com 8080 | head -3 timeout 3 nc mail.example.com 587 </dev/null | head -1 # "220 ... ESMTP" = SMTP, STARTTLS port - 3.
暗黙的 TLS のポートに接続する
クライアントが STARTTLS に対応していない場合は、そのプロトコルの TLS 用ポートを使ってください。
bash # Implicit TLS ports: 443 (HTTPS), 465 (SMTPS), 993 (IMAPS), 995 (POP3S), 636 (LDAPS) openssl s_client -connect mail.example.com:465 -servername mail.example.com -brief </dev/null
関連するエラー
curl: (35) TLS connect error: error:0A00010B:SSL routines::wrong version numbercurl (OpenSSL backend)[SSL: WRONG_VERSION_NUMBER] wrong version numberPython ssl module (OpenSSL)code: 'ERR_SSL_WRONG_VERSION_NUMBER'Node.js tls.connect / fetch (undici)tls: first record does not look like a TLS handshakeGo crypto/tls