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
이제이 인증서를 직접 신뢰하고 싶습니다 (지문 등을 검증 할 수있는 자체 발급 인증서를 상상해보십시오). 인증서를 요청하고 검증 / 신뢰하려면 어떻게해야합니까?
인증서를 다운로드하고 내 파일에로드하고 tls.Config
struct를 채우려면 openssl을 사용해야 할 것입니다 !?
답변
보안 정보 : 보안 검사를 비활성화하는 것은 위험하므로 피해야합니다.
기본 클라이언트의 모든 요청에 대해 전역 적으로 보안 검사를 비활성화 할 수 있습니다.
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
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},
}
최신 정보
짧은 방법 :
customTransport := &(*http.DefaultTransport.(*http.Transport)) // make shallow copy
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
올바른 방법 (Go 1.13 기준) ( 아래 답변 제공 ) :
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
경고 : 테스트 / 개발 목적으로 만 사용됩니다. 다른 모든 것은 자신의 책임하에 진행하십시오 !!!
답변
이 모든 답변이 잘못되었습니다! InsecureSkipVerify
호스트 이름과 일치하지 않는 CN을 처리하는 데 사용하지 마십시오 . Go 개발자는 호스트 이름 검사 (터널, nats, 공유 클러스터 인증서 등의 합법적 인 용도)를 비활성화하지 않는 것에 대해 단호한 태도를 보였으며 유사 해 보이지만 실제로 는 인증서 검사를 완전히 무시했습니다. 인증서가 유효하며 신뢰할 수있는 인증서에 의해 서명되었음을 알아야합니다. 그러나 일반적인 시나리오에서는 CN이 연결 한 호스트 이름과 일치하지 않는다는 것을 알고 있습니다. 사람들을 위해, 설정 ServerName
에 tls.Config
. 경우 tls.Config.ServerName
== remoteServerCN 후 인증서 검사가 성공합니다. 이것이 당신이 원하는 것입니다. InsecureSkipVerify
인증이 없음을 의미합니다. Man-In-The-Middle에게는 무르 익었습니다. TLS 사용 목적을 무너 뜨리는 것.
한 가지 합법적 인 용도가 있습니다 InsecureSkipVerify
.이를 사용하여 호스트에 연결하고 인증서를 가져온 다음 즉시 연결을 끊습니다. 를 사용하도록 코드를 설정 한 경우 InsecureSkipVerify
일반적으로 ServerName
올바르게 설정하지 않았기 때문입니다 (env var 또는 다른 것에서 가져와야합니다.
특히 클라이언트 인증서를 사용하고 인증에 의존하는 경우 기본적으로 실제로 더 이상 로그인하지 않는 가짜 로그인을 갖게됩니다. 하는 코드를 거부하십시오. 그렇지 InsecureSkipVerify
않으면 어려운 방법으로 무엇이 잘못되었는지 알게 될 것입니다!
답변
기본 전송 설정을 유지하려는 경우이를 수행하는 올바른 방법은 다음과 같습니다 (Go 1.13 기준).
customTransport := http.DefaultTransport.(*http.Transport).Clone()
customTransport.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client = &http.Client{Transport: customTransport}
Transport.Clone 은 전송의 전체 복사본을 만듭니다. 이렇게하면 Transport
시간이 지남 에 따라 구조체에 추가되는 새 필드가 누락되는 것에 대해 걱정할 필요가 없습니다 .
답변
http 패키지의 기본 설정을 사용하여 새 전송 및 클라이언트 개체를 만들 필요가없는 경우 다음과 같이 인증서 확인을 무시하도록 변경할 수 있습니다.
tr := http.DefaultTransport.(*http.Transport)
tr.TLSClientConfig.InsecureSkipVerify = true
답변
일반적으로 URL의 DNS 도메인은 인증서의 인증서 주체와 일치해야합니다.
이전에는 도메인을 인증서의 cn으로 설정하거나 도메인을 주체 대체 이름으로 설정하는 것이 가능했습니다.
cn에 대한 지원은 오랫동안 ( RFC 2818의 2000 이후 ) 더 이상 사용되지 않았으며 Chrome 브라우저는 더 이상 cn을 보지 않을 것이므로 오늘날 URL 의 DNS 도메인을 주체 대체 이름으로 사용해야합니다 .
RFC 6125DNS 도메인 용 SAN이있는 경우 cn 검사를 금지하지만 IP 주소 용 SAN이있는 경우는 금지하는 . RFC 6125는 또한 RFC 2818에서 이미 언급 된 cn이 더 이상 사용되지 않는다는 사실을 반복합니다. 그리고 RFC 6125와 함께 기본적으로 cn이 DNS 도메인 이름을 확인하지 않음을 의미하는 인증 기관 브라우저 포럼이 표시됩니다.