エラーメッセージ
tls: client offered only unsupported versions: [301]
net/http は「http: TLS handshake error from <client address>: tls: client offered only unsupported versions: [301]」と出力します。リストには、クライアントが提示したすべてのバージョンが示されます(300 = SSL 3.0、301 = TLS 1.0、302 = TLS 1.1)。
Go crypto/tls server (net/http ErrorLog) — the client offered only TLS versions below the server's minimum
このエラーの意味
Go の TLS サーバーが、最小バージョンより低いプロトコルバージョンしか提示しない ClientHello を受信しました。この例では TLS 1.0(バージョンコード 301)です。Go のサーバーはデフォルトで TLS 1.2 と 1.3 を受け入れるため、ハンドシェイクは protocol_version アラートで拒否され、net/http がこの行をログに記録します。相手側のクライアントは古いか、意図的に探りを入れています。
発生する理由
古いクライアント
よくあるレガシーデバイス、古い Java 6/7 や .NET Framework のアプリケーション、組み込みの HTTP クライアントなど、TLS 1.2 を使えないクライアントが該当します。
インターネットスキャナーとセキュリティツール
よくあるスキャナーは、サーバーを分類するために意図的に古いバージョンを提示します。公開されているエンドポイントでは、さまざまなアドレスからこうしたログ行が記録されるのは想定どおりです。
古いバージョンを使うよう設定されたクライアント
ときどきとうの昔になくなったレガシーシステムとの連携のために、プロトコル設定が TLS 1.0 に固定されたままのアプリケーションです。
修正方法
- 1.
送信元を特定する
ログ行をクライアントのアドレスごとにまとめてください。少数の既知のアドレスであれば、アップグレードすべき古いクライアントです。多数の未知のアドレスであれば、スキャナーです。
bash # Which addresses send these handshakes, and how often? journalctl -u myservice --since today | grep 'client offered only unsupported versions' \ | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c | sort -rn | head - 2.
サーバーの最小バージョンを TLS 1.2 のままにする
スキャナーに合わせて MinVersion を下げないでください。代わりに、正当な少数の古いクライアントをアップグレードしてください。
go // Keep TLS 1.2 as the minimum (Go's server default); set it explicitly to document intent srv := &http.Server{Addr: ":443", TLSConfig: &tls.Config{MinVersion: tls.VersionTLS12}} - 3.
ハンドシェイクのノイズを分離する
ハンドシェイクのエラーは http.Server.ErrorLog に送られます。これを専用のロガーに向ければ、アプリケーションのログを読みやすく保てます。
go // Route handshake noise from scanners to a separate logger instead of the main log srv.ErrorLog = log.New(handshakeLogWriter, "tls: ", 0)