Как сделать запрос https с плохим сертификатом?


скажи, что я хочу получить https://golang.org программно. В настоящее время golang.org (ssl) имеет плохой сертификат, который выдается *.appspot.com когда я запускаю это:

package main

import (
    "log"
    "net/http"
)

func main() {
    _, err := http.Get("https://golang.org/")
    if err != nil {
        log.Fatal(err)
    }
}

я получаю (как я и ожидал)

Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org

теперь я хочу сам доверять этому сертификату (представьте себе самоизданный сертификат, где я могу проверить отпечаток пальца и т. д.): как я могу сделать запрос и проверить/доверять сертификату?

мне, вероятно, нужно использовать openssl, чтобы загрузить сертификат, загрузить его в мой файл и заполнить tls.Config структура !?

4 87

4 ответа:

примечание по безопасности: отключение проверки безопасности опасно и следует избегать

вы можете отключить проверки безопасности глобально для всех запросов клиента по умолчанию:

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)
    }
}

Вы можете отключить проверку безопасности для клиента:

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)
    }
}

вот способ сделать это без потери настроек по умолчанию DefaultTransport, и без необходимости поддельного запроса в соответствии с комментарием пользователя.

defaultTransport := http.DefaultTransport.(*http.Transport)

// Create new Transport that ignores self-signed SSL
httpClientWithSelfSignedTLS := &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},
}

Если вы хотите использовать настройки по умолчанию из пакета http, поэтому вам не нужно создавать новый объект транспорта и клиента, вы можете изменить, чтобы игнорировать проверку сертификата следующим образом:

tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig.InsecureSkipVerify = true

все эти ответы неверны! Не используйте InsecureSkipVerify для работы с CN, который не соответствует имени хоста. Разработчики Go неразумно были непреклонны в том, чтобы не отключать проверки имен хостов (которые имеют законное использование-туннели, nats, общие сертификаты кластера и т. д.), а также иметь что-то похожее, но на самом деле полностью игнорирует проверку сертификата. Вы должны знать, что сертификат действителен и подписан сертификатом, которому Вы доверяете. Но в общих случаях знайте, что CN не будет соответствовать имени хоста, с которым вы связались. Для тех, набор ServerName on tls.Config. Если tls.Config.ServerName == remoteServerCN, то проверка сертификата будет выполнена успешно. Это то, что ты хочешь. InsecureSkipVerify означает, что нет аутентификации; и он созрел для человека в середине; победив цель использования TLS.

есть одно законное использование для InsecureSkipVerify: используйте его для подключения к хосту и захватить его сертификат, а затем немедленно отключить. Если вы настроили свой код для использования InsecureSkipVerify, Это правило, потому что вы не установили ServerName правильно (это должно будет исходить от env var или что - то-не болит живот об этом требовании... сделать правильно.)

в частности, если вы используете клиентские сертификаты и полагаетесь на них для аутентификации, у вас в основном есть поддельный логин, который на самом деле больше не входит в систему. Отказаться от кода, который делает InsecureSkipVerify, или вы узнаете, что с ним не так на горьком опыте!