¿Cómo hacer una solicitud https con un certificado incorrecto?
Digamos que quiero hacerlo https://golang.org
programáticamente. Actualmente golang.org (ssl) tiene un certificado incorrecto que se emite para *.appspot.com
Entonces, cuando ejecuto esto:
package main
import (
"log"
"net/http"
)
func main() {
_, err := http.Get("https://golang.org/")
if err != nil {
log.Fatal(err)
}
}
Entiendo (como esperaba)
Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org
Ahora, quiero confiar en este certificado yo mismo (imagínese un certificado autoemitido donde puedo validar la huella digital, etc.): ¿cómo puedo realizar una solicitud y validar/confiar en el certificado?
Probablemente necesite usar openssl para descargar el certificado, cargarlo en mi archivo y completar tls.Config
la estructura.
Nota de seguridad: deshabilitar los controles de seguridad es peligroso y debe evitarse
Puede desactivar las comprobaciones de seguridad globalmente para todas las solicitudes del cliente predeterminado:
package main
import (
"fmt"
"net/http"
"crypto/tls"
)
func main() {
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
_, err := http.Get("https://golang.org/")
if err != nil {
fmt.Println(err)
}
}
Puede desactivar la verificación de seguridad para un cliente:
package main
import (
"fmt"
"net/http"
"crypto/tls"
)
func main() {
tr := &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: tr}
_, err := client.Get("https://golang.org/")
if err != nil {
fmt.Println(err)
}
}
Forma correcta (a partir de Go 1.13) (proporcionada por la respuesta a continuación ):
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: customTransport}
Respuesta original:
Aquí hay una manera de hacerlo sin perder la configuración predeterminada de DefaultTransport
y sin necesitar la solicitud falsa según el comentario del usuario.
defaultTransport := http.DefaultTransport.(*http.Transport)
// Create new Transport that ignores self-signed SSL
customTransport := &http.Transport{
Proxy: defaultTransport.Proxy,
DialContext: defaultTransport.DialContext,
MaxIdleConns: defaultTransport.MaxIdleConns,
IdleConnTimeout: defaultTransport.IdleConnTimeout,
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
client := &http.Client{Transport: customTransport}
Manera más corta:
customTransport := &(*http.DefaultTransport.(*http.Transport)) // make shallow copy
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{Transport: customTransport}
Advertencia : solo para fines de prueba/desarrollo. ¡¡¡Cualquier otra cosa, procede bajo tu propia responsabilidad!!!
¡Todas estas respuestas están equivocadas! No lo utilice InsecureSkipVerify
para tratar con un CN que no coincida con el nombre de host. Los desarrolladores de Go, imprudentemente, se mostraron firmes en no deshabilitar las comprobaciones de nombres de host (que tienen usos legítimos: túneles, nats, certificados de clúster compartido, etc.), y al mismo tiempo tenían algo que parece similar pero que en realidad ignora por completo la verificación de certificados. Debe saber que el certificado es válido y está firmado por un certificado de confianza. Pero en escenarios comunes, usted sabe que el CN no coincidirá con el nombre de host con el que se conectó. Para aquellos, opte ServerName
por tls.Config
. Si tls.Config.ServerName
== remoteServerCN, la verificación del certificado se realizará correctamente. Esto es lo que quieres. InsecureSkipVerify
significa que NO hay autenticación; y está listo para un hombre en el medio; frustrando el propósito de usar TLS.
Hay un uso legítimo para InsecureSkipVerify
: usarlo para conectarse a un host y obtener su certificado, luego desconectarse inmediatamente. Si configura su código para usar InsecureSkipVerify
, generalmente es porque no lo configuró ServerName
correctamente (deberá provenir de una var env o algo así; no se preocupe por este requisito... hágalo correctamente).
En particular, si utiliza certificados de cliente y confía en ellos para la autenticación, básicamente tiene un inicio de sesión falso que en realidad ya no inicia sesión. ¡Rechaza el código que sí lo hace InsecureSkipVerify
, o aprenderás qué tiene de malo de la manera más difícil!
Si desea utilizar la configuración predeterminada del paquete http, por lo que no necesita crear un nuevo objeto de Transporte y Cliente, puede cambiar para ignorar la verificación del certificado de esta manera:
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig.InsecureSkipVerify = true