錯誤:Go TLS 連線中的憑證欄位差異
嘗試使用Go 與MongoDB 伺服器建立TLS 連線時,您可能會遇到以下錯誤:
failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
原因:
當伺服器的TLS 憑證依賴舊版通用名稱(CN) 欄位進行識別時,會發生此錯誤,但Go的運行時預設使用主題備用名稱(SAN) 進行TLS 連線。
解決方案:
解決此問題的主要方法有兩種:
1.利用伺服器憑證中的SAN:
2.暫時停用CN 匹配:
如果無法立即重新產生伺服器證書,可以透過設定環境變數來暫時停用CN 匹配:
GODEBUG=x509ignoreCN=0
但這不是長期解決方案,只能用於臨時建立連線。
程式碼實作:
如果您選擇在 Go 程式碼中修正問題,請確保您載入的憑證包含與連線期間使用的主機名稱相符的 SAN。以下是您提供的程式碼片段的更新版本:
<code class="go">const CONFIG_DB_CA = "/etc/ca-files/new-mongo.ca.crt" func main() { cer, err := tls.LoadX509KeyPair("/mongo-server.crt", "/mongo-server.key") if err != nil { log.Println(err) return } roots := x509.NewCertPool() ca, err := ioutil.ReadFile(CONFIG_DB_CA) if err != nil { fmt.Printf("Failed to read or open CA File: %s.\n", CONFIG_DB_CA) return } roots.AppendCertsFromPEM(ca) tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cer}, RootCAs: roots, VerifyPeerCertificate: func(rawCerts [][]*x509.Certificate) error { for _, certs := range rawCerts { for _, cert := range certs { if len(cert.Subject.CommonName) > 0 { continue } for _, dns := range cert.DNSNames { if dns == "customhost" || dns == "customhost:port" { return nil } } return errors.New("certificate does not contain a SAN for the host") } } return errors.New("no valid certificate found") }, } conn, err := tls.Dial("tcp", "customhost:port", tlsConfig) if err != nil { fmt.Printf("failed to connect: %v.\n", err) return } err = conn.VerifyHostname("customhost") if err != nil { panic("Hostname doesn't match with certificate: " + err.Error()) } for i, cert := range conn.ConnectionState().PeerCertificates { prefix := fmt.Sprintf("CERT%d::", i+1) fmt.Printf("%sIssuer: %s\n", prefix, cert.Issuer) fmt.Printf("%sExpiry: %v\n", prefix, cert.NotAfter.Format(time.RFC850)) fmt.Printf("%sDNSNames: %v\n\n", prefix, cert.DNSNames) } fmt.Printf("Success!") }</code>
此更新的程式碼使用自訂的VerifyPeerCertificate函數來驗證憑證是否包含與主機名稱相符的CN或與主機名稱相符的SAN。如果找到合適的證書,連線就會成功。
以上是為什麼我會遇到「連線失敗:x509:憑證依賴舊版公用名字段,使用 SAN 或暫時啟用與 GODEBUG=x509ignoreCN=0 相符的公用名稱」錯誤的詳細內容。更多資訊請關注PHP中文網其他相關文章!