用 Golang 写一个 TLS 隧道,不想验证域名(SNI),双向验证两端证书是否为同个 CA 证书签发,该如何实现。。
试过 VerifyPeerCertificate 但是在本地网络下可以运行,到了远程就报错,不知为何
路过大佬求点拨,以下是两端配置,谢谢。。。
======== Server ========
tlsConfig := tls.Config{} tlsConfig.InsecureSkipVerify = true tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert tlsConfig.Certificates = []tls.Certificate{func() tls.Certificate { CertKey, err := tls.X509KeyPair(ServerCert, ServerKey) if err != nil { panic(err) } return CertKey }()} tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { Roots := x509.NewCertPool() Roots.AppendCertsFromPEM(CA) cert, _ := x509.ParseCertificate(rawCerts[0]) opts := x509.VerifyOptions{ DNSName: "", Roots: Roots, } _, err := cert.Verify(opts) if err != nil { return err } return nil }
===== Client =====
tlsConfig := tls.Config{} tlsConfig.InsecureSkipVerify = true tlsConfig.Certificates = []tls.Certificate{func() tls.Certificate { CertKey, err := tls.X509KeyPair(ClientCert, ClientKey) if err != nil { panic(err) } return CertKey }()} tlsConfig.ClientAuth = tls.RequireAndVerifyClientCert tlsConfig.VerifyPeerCertificate = func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { Roots := x509.NewCertPool() Roots.AppendCertsFromPEM(CA) cert, _ := x509.ParseCertificate(rawCerts[0]) opts := x509.VerifyOptions{ DNSName: "", Roots: Roots, } _, err := cert.Verify(opts) if err != nil { return err } return nil }
1
yaott2020 OP |
2
jinliming2 2022-02-16 09:25:55 +08:00
没做错误处理、自己处理一下
server 端: cert, err := tls.LoadX509KeyPair(*cert, *key) CA := x509.NewCertPool() file, err := ioutil.ReadFile(*ca) CA.AppendCertsFromPEM(file) tlsConfig := tls.Config{ GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { return &cert, nil }, ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: CA, // ... } 客户端: cert, err := tls.LoadX509KeyPair(*cert, *key) CA := x509.NewCertPool() file, err := ioutil.ReadFile(*ca) CA.AppendCertsFromPEM(file) tlsConfig := tls.Config{ Certificates: []tls.Certificate{cert}, RootCAs: certPool, ClientAuth: tls.RequireAndVerifyClientCert, ClientCAs: certPool, // ... } |
3
yaott2020 OP 多谢,已解决
|
5
yaott2020 OP 服务器设置:
``` InsecureSkipVerify = false Certificates //放服务器证书 ClientCAs //放 CA 证书 ClientAuth = tls.RequireAndVerifyClientCert ``` 客户端设置: ``` InsecureSkipVerify = false Certificates //放客户端证书 RootCAs //放 CA 证书 ServerName //设置 SNI ,必须与服务器证书的 servername 一致 ``` |
6
yaott2020 OP 客户端连接地址可以是域名可以是 ip ,反正会使用 ServerName 验证 SNI
|
7
yaott2020 OP 服务器和客户端证书建议用同一个 CA 证书签发,(其他情况没试过)该配置可以实现双向验证
|