Skip to content

GoのGODEBUG=tlsrsakexはmainで設定しても効果がある

GODEBUG 環境変数で設定する値は runtime に作用するものがあり、それらは main で設定しても効果がない場合がある。tlsrsakex について、mainos.Setenv しても問題ないのかを確認するためにコードを読んだ。

crypto/tlstlsrsakex を参照しているのは Config.cipherSuites のあたり

var tlsrsakex = godebug.New("tlsrsakex")
if tlsrsakex.Value() == "1" {
return defaultCipherSuitesWithRSAKex
}

Config.cipherSuites は以下のあたりから呼ばれているが、どれも main に到達した以降で使われる関数だろう(おそらく)

  • ClientHelloInfo.SupportsCertificate
  • Conn.makeClientHello
  • serverHandshakeState.pickCipherSuite

godebug.New はこれ

godebug.Setting.Value

どちらも、特に変わったことはしていない、キャッシュから取り出している + empty をキャッシュにセットしているだけで、環境変数は全く触ってない。どこで環境変数をみているのかでいうと、 initsetUpdate(update) があって、そこでみている。

setUpdate//go:linkname ディレクティブによって他のパッケージにある実装をリンクしている。実態は runtimegodebug_setUpdate

実装はこれ

やっていることは単純で、godebugNotify(bool) が呼ばれたときに実行される関数を登録している。godebugNotify はsetenv, unsetenvのときに動く。

  • main の途中で os.Setenv("GODEBUG", v) するとキャッシュに反映される
  • 少なくとも tlsrsakex は、TLSハンドシェイクで都度GODEBUGキャッシュを読む
  • なので mainos.Setenv("GODEBUG", v) してもいい