Go 1.27で、crypto/tls・crypto/x509のGODEBUG設定tlsunsafeekm/tlsrsakex/tls10server/tls3des/x509keypairleafの5つが完全に削除された。
crypto/tls
概要
Go 1.26で削除予告されていた5つの互換性用GODEBUG設定 — tlsunsafeekm(Go 1.22で導入)、tlsrsakex(Go 1.22)、tls10server(Go 1.22)、tls3des(Go 1.23)、x509keypairleaf(Go 1.23) — がGo 1.27で完全に削除された。いずれもcrypto/tls・crypto/x509の過去の挙動を復元するための一時的な設定で、導入から2年以上が経過し、GODEBUGのサポート方針(go.dev/doc/godebug)が定める最低保証期間を満たしたため削除された。
削除後にこれらの設定名を旧来の値で指定すると、go build/go vet時のビルドエラー、または実行時起動時のパニックになる(デフォルト値での指定は引き続き許容される)。
導入経緯
Issue golang/go#75316 で、意図的なGODEBUG削除を体系的に行った前例がなかったことを踏まえ、対象の5設定についてGo 1.26で削除予告し、Go 1.27で削除することが提案された。提案時点ではx509negativeserial(Go 1.23で導入)も候補に挙がっていたが、GitHub検索で利用箇所が多数見つかったため、影響が大きいとして今回の削除対象からは除外されている。
議論のハイライト
- 提案者は、過去に意図せず
GODEBUG(tlskyber)を削除してビルド失敗を招いた事例(golang/go#72111)を引き合いに、今回が初めての「意図的な」GODEBUG削除であることを述べた。 - 対象の5設定は「go.modのバージョンに追従させるためのソフトランディング」的な性格が強く実利用は少ないと判断された一方、
x509negativeserialは影響が大きいため除外する判断がなされた。 - Proposal Review Meetingで「likely accept」と判定され、その後変更なく「accepted」となった。会議では、
GODEBUG削除の正式な手順は別issue(golang/go#76163、通称umbrella issue)で定めることとし、本提案自体はそれを待たずに進めることが確認された。 - 会議では、過去の
x509sha1削除(Go 1.24)での事前告知プロセスがコミュニティの反発をうまく吸収し、結果的にうまく機能した実績も参照された。 - 実装はGo 1.27のリリースフリーズの約2週間前に着手され、5つの設定はそれぞれ個別のCLで削除された。
移行時の注意
削除された5つの設定を非デフォルト値(tlsunsafeekm・tlsrsakex・tls10server・tls3desは=1、x509keypairleafは=0)で明示的に指定しているコードがある場合、Go 1.27では次のいずれかの形でエラーになる。
go.modの//go:debugディレクティブに指定している場合:go build/go vet時にビルドエラー- 環境変数
GODEBUGに指定して実行した場合: プログラム起動時にパニック
移行するには、該当の設定に依存している挙動(TLS 1.0サーバーの許可、RSA鍵交換、3DES暗号スイート、危険な鍵材料エクスポート、証明書チェーンでのリーフ証明書選択の旧挙動など)への依存を解消したうえで、指定自体を削除する必要がある。デフォルト値を明示しているだけの指定はエラーにはならないが、意味を持たなくなるため削除して構わない。
実装解説
削除済みGODEBUGの一覧はinternal/godebugs.Removedテーブルで管理されており、今回の5設定はRemoved: 27(Go 1.27)として登録されている(該当エントリ)。
このテーブルは2つの経路から検証に使われる。
- ランタイム起動時:
runtime.parsegodebugがGODEBUG環境変数中の各キーをgodebugs.Removedと突き合わせ、旧来の値が指定されていればinvalidGODEBUGに記録する。実際のパニックは初期化完了後にruntime.mainで発生し、https://go.dev/doc/godebug#go-127へのリンクを含むメッセージが出力される。 go build/go vet時:cmd/go/internal/modload.CheckGodebugがgo.modの//go:debugディレクティブを検証し、削除済み設定に旧来の値が指定されていればビルドエラーを返す。
いずれの経路も、削除済み設定であってもデフォルト値(新しい挙動を意味する値)を明示的に指定した場合はエラーにならない。