作为tls新手,我真的不确定在这里应该做什么。
我有一个使用ListenAndServeTLS的客户端应用程序,该应用程序将请求发送到也使用ListenAndServeTLS的go的服务器应用程序。我可以将请求从客户端发送到服务器,并验证本地生成的证书。
当我更新客户端以与代理(C#)进行对话时,我在Azure中打开了一个sslstream到连接到本地计算机上的服务器的azure中继服务。我收到以下错误。 Get https://<ip_address>:8080/hello: x509: cannot validate certificate for <ip_address> because it doesn't contain any IP SANs
我使用的IP地址是动态的,没有主机或DNS。如果IP随我提出的每个请求而更改,我如何通过服务器验证我的证书。
// Server Code
func helloHandler(w http.ResponseWriter, r *http.Request) {
// Write "Hello, world!" to the response body
io.WriteString(w, "Hello, world!\n")
}
func main() {
// Create a CA certificate pool and add cert.pem to it
caCert, err := ioutil.ReadFile("../certs/cert.pem")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
// Create the TLS Config with the CA pool and enable Client certificate validation
tlsConfig := &tls.Config{
ClientCAs: caCertPool,
ClientAuth: tls.RequireAndVerifyClientCert,
}
tlsConfig.BuildNameToCertificate()
server := &http.Server{
Addr: ":8080",
TLSConfig: tlsConfig,
}
// Set up a /hello resource handler
http.HandleFunc("/hello", helloHandler)
// Listen to port 8080 and wait
log.Fatal(server.ListenAndServeTLS("../certs/cert.pem", "../certs/key.pem"))
}
// Client Code
func main() {
cert, err := tls.LoadX509KeyPair("../certs/cert.pem", "../certs/key.pem")
if err != nil {
log.Fatal(err)
}
// Create a CA certificate pool and add cert.pem to it
caCert, err := ioutil.ReadFile("../certs/cert.pem")
if err != nil {
log.Fatal(err)
}
caCertPool := x509.NewCertPool()
caCertPool.AppendCertsFromPEM(caCert)
client := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
// InsecureSkipVerify: true,
RootCAs: caCertPool,
Certificates: []tls.Certificate{cert},
},
},
}
// Request /hello over port 8080 via the GET method
// r, err := http.Get("http://localhost:8080/hello")
// Request /hello over HTTPS port 8443 via the GET method
r, err := client.Get("https://<ip_address>:8080/hello")
if err != nil {
log.Fatal(err)
}
// Read the response body
defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body)
if err != nil {
log.Fatal(err)
}
// Print the response body to stdout
fmt.Printf("%s\n", body)
}
最佳答案
首先,要消除一个误解:服务器不验证证书。证书是身份的加密证明,客户端使用该证书,以便他们可以确保它们已连接到预期的服务器。即他们希望确保网络连接没有意外或恶意地定向到其他服务器。因此,如果证书验证失败,则几乎总是因为客户端不满意,而不是服务器不满意。
当您向https://192.0.2.1:8080/hello
发出HTTP请求时,默认情况下,客户端会期望获得一个在主题备用名称(SAN)中包含192.0.2.1的证书,因为该证书将成为请求的Host字段的值(如上所述),客户端希望确保它确实已连接到该服务器)。
如果您事先不知道IP地址,则无法颁发此类证书,并且唯一的选择是更改客户的期望。那就是ServerName field in tls.Config的目的。只需将其设置为证书的通用名称(应该是域)即可。
关于azure - 多个具有随机ip的云之间的TLS证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60994112/