Powiedz, że chcę uzyskać https://golang.org
programowo. Obecnie golang.org (ssl) ma zły certyfikat, który jest wystawiany dla *.appspot.com
Więc kiedy uruchamiam to:
package main
import (
"log"
"net/http"
)
func main() {
_, err := http.Get("https://golang.org/")
if err != nil {
log.Fatal(err)
}
}
Dostaję (tak jak się spodziewałem)
Get https://golang.org/: certificate is valid for *.appspot.com, *.*.appspot.com, appspot.com, not golang.org
Teraz chcę sam zaufać temu certyfikatowi (wyobraź sobie certyfikat wydany przez siebie, w którym mogę zweryfikować odcisk palca itp.): Jak mogę złożyć wniosek i zweryfikować / zaufać certyfikatowi?
Prawdopodobnie muszę użyć openssl, aby pobrać certyfikat, załadować go do mojego pliku i wypełnić tls.Config
strukturę!?
Odpowiedzi:
Uwaga dotycząca bezpieczeństwa: wyłączenie kontroli bezpieczeństwa jest niebezpieczne i należy go unikać
Możesz wyłączyć globalne kontrole bezpieczeństwa dla wszystkich żądań klienta domyślnego:
Możesz wyłączyć kontrolę bezpieczeństwa dla klienta:
źródło
InsecureSkipVerify: true
. Czy to jest możliwe?NameToCertificate
może pomóc, zajrzyj dotls.Config
dokumentacji: golang.org/pkg/crypto/tls/#ConfigDialer.Timeout
.Oto sposób na zrobienie tego bez utraty domyślnych ustawień
DefaultTransport
i bez potrzeby fałszywego żądania zgodnie z komentarzem użytkownika.AKTUALIZACJA
Krótszy sposób:
Właściwy sposób (od Go 1.13) (podany w odpowiedzi poniżej ):
Ostrzeżenie : tylko do celów testowych / programistycznych. Cokolwiek innego, kontynuuj na własne ryzyko !!!
źródło
mytransportsettings := &(*http.DefaultTransport.(*http.Transport))
a następnie zmodyfikować konfigurację klienta TLSmytransportsettings.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
?Wszystkie te odpowiedzi są błędne! Nie używaj
InsecureSkipVerify
do obsługi CN, która nie pasuje do nazwy hosta. Deweloperzy Go nierozsądnie byli nieugięci, aby nie wyłączać sprawdzania nazw hostów (co ma uzasadnione zastosowania - tunele, Nats, współdzielone certyfikaty klastrów itp.), A jednocześnie mając coś, co wygląda podobnie, ale w rzeczywistości całkowicie ignoruje sprawdzanie certyfikatu. Musisz wiedzieć, że certyfikat jest ważny i podpisany certyfikatem, któremu ufasz. Ale w typowych scenariuszach wiesz, że CN nie będzie pasować do nazwy hosta, z którym się łączyłeś. Dla nich ustawServerName
natls.Config
. Jeślitls.Config.ServerName
== remoteServerCN, sprawdzenie certyfikatu powiedzie się. To jest to, czego chcesz.InsecureSkipVerify
oznacza, że NIE ma uwierzytelnienia; i jest już gotowy na Man-In-The-Middle; pokonanie celu korzystania z TLS.Jest jedno uzasadnione zastosowanie
InsecureSkipVerify
: użyj go, aby połączyć się z hostem i pobrać jego certyfikat, a następnie natychmiast się rozłączyć. Jeśli skonfigurowałeś swój kod do użyciaInsecureSkipVerify
, zazwyczaj dzieje się tak, ponieważ nie ustawiłeśServerName
poprawnie (będzie musiał pochodzić z zmiennej env lub czegoś podobnego - nie bój się brzucha z powodu tego wymagania ... zrób to poprawnie).W szczególności, jeśli używasz certyfikatów klienta i polegasz na nich przy uwierzytelnianiu, w zasadzie masz fałszywy login, który w rzeczywistości już się nie loguje. Odrzuć kod, który to robi
InsecureSkipVerify
, albo dowiesz się, co jest z nim nie tak na własnej skórze!źródło
Prawidłowy sposób, aby to zrobić, jeśli chcesz zachować domyślne ustawienia transportu, to teraz (od Go 1.13):
Transport.Clone tworzy głęboką kopię transportu. W ten sposób nie musisz się martwić brakiem nowych pól, które
Transport
z czasem zostaną dodane do struktury.źródło
Jeśli chcesz użyć domyślnych ustawień z pakietu http, więc nie musisz tworzyć nowego obiektu Transport i Client, możesz zmienić, aby zignorować weryfikację certyfikatu w następujący sposób:
źródło
panic: runtime error: invalid memory address or nil pointer dereference
Ogólnie rzecz biorąc, domena DNS adresu URL MUSI być zgodna z tematem certyfikatu certyfikatu.
W przeszłości mogło to być spowodowane ustawieniem domeny jako cn certyfikatu lub ustawieniem domeny jako alternatywnej nazwy podmiotu.
Obsługa cn została wycofana przez długi czas (od 2000 r. W RFC 2818 ), a przeglądarka Chrome nie będzie już nawet patrzeć na cn, więc dziś musisz mieć domenę DNS adresu URL jako alternatywną nazwę podmiotu.
RFC 6125 zabrania sprawdzania cn, jeśli jest obecna SAN dla domeny DNS, ale nie, jeśli jest obecna SAN dla adresu IP. RFC 6125 również powtarza, że cn jest przestarzałe, co zostało już powiedziane w RFC 2818. Obecne jest także forum przeglądarki urzędów certyfikacji, co w połączeniu z RFC 6125 zasadniczo oznacza, że cn nigdy nie będzie sprawdzane pod kątem nazwy domeny DNS.
źródło