[ssl] 잘못된 인증서로 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

이제이 인증서를 직접 신뢰하고 싶습니다 (지문 등을 검증 할 수있는 자체 발급 인증서를 상상해보십시오). 인증서를 요청하고 검증 / 신뢰하려면 어떻게해야합니까?

인증서를 다운로드하고 내 파일에로드하고 tls.Configstruct를 채우려면 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이 연결 한 호스트 이름과 일치하지 않는다는 것을 알고 있습니다. 사람들을 위해, 설정 ServerNametls.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을 보지 않을 것이므로 오늘날 URLDNS 도메인을 주체 대체 이름으로 사용해야합니다 .

RFC 6125DNS 도메인 용 SAN이있는 경우 cn 검사를 금지하지만 IP 주소 용 SAN이있는 경우는 금지하는 . RFC 6125는 또한 RFC 2818에서 이미 언급 된 cn이 더 이상 사용되지 않는다는 사실을 반복합니다. 그리고 RFC 6125와 함께 기본적으로 cn이 DNS 도메인 이름을 확인하지 않음을 의미하는 인증 기관 브라우저 포럼이 표시됩니다.


답변