2012-08-25 44 views
79

私はhttps://golang.orgをプログラマチックに取得したいと言います。現在golang.org(SSL)は、私が実行するので、とき*.appspot.comに発行された不正な証明書を持っているこの:golang:不正な証明書でhttpsリクエストを行うにはどうすればよいですか?

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構造体を入力するには、おそらくopensslを使用する必要があります。

+0

これは「不良証明書」ではなく、別のCNを持つ証明書です。 InsecureSkipVerifyは正当な使用法ではありません。 tlsにServerNameを設定する必要があります。あなたが接続しようとしているものと一致するように設定します。このStackOverflowポストは、Goコードのこの大きなセキュリティホールをあらゆる場所に広げています。 InsecureSkipVerifyは、すべての証明書をチェックしません。必要なのは、CNがホスト名と一致しない場合でも、証明書が信頼できるエンティティによって正当に署名されたことを確認することです。トンネルとNATSは合法的にこの不一致を引き起こす可能性があります。 – Rob

答えて

167

セキュリティに関する注意:セキュリティチェックを無効にすることは危険であり、避けるべきである

あなたは、デフォルトのクライアントのすべての要求のためのグローバルセキュリティチェックを無効にすることができ

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

'InsecureSkipVerify:true'を使わずに接続を使用できるように、信頼できる証明書をどこに置くのだろうか。それは可能ですか? – topskip

+7

'NameToCertificate'が役に立つかもしれません、' tls.Config'のドキュメントを参照してください:http://golang.org/pkg/crypto/tls/#Config – cyberdelia

+0

この方法でチェックを無効にすると、証明書が自己署名証明書の場合は有効ではありません。 InsecureSkipVerifyは本当にセキュリティチェックをスキップしますか? – Alexander

7

httpパッケージのデフォルト設定を使用する場合は、あなたはこのように証明書の検証を無視するように変更することができ、新しいトランスポートおよびクライアントオブジェクトを作成する必要はありません。

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

これを行うと、 'panic:runtime error:無効なメモリアドレスまたはnilポインタの逆参照 'が発生します。 – OscarRyz

+4

この前にデフォルトのhttpリクエスタを使用しない場合は、偽のリクエストを強制して初期化されます。 –

+0

ホスト名のチェックを無効にします。すべての証明書チェックを無効にします。 Goは接続先の証明書にCNと同じServerNameを設定します。 InsecureSkipVerifyは、実際のサービスに転送するふりをする不正なMITMサーバに接続します。 InsecureSkipVerifyの正当な使用は、リモートエンドの証明書を取得し、ただちに切断することです。 – Rob

2

ここ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}, 
} 
+0

上記のコメントを参照してください。これらのすべてが間違っています! – Rob

+0

素晴らしいです、ありがとうございます。これは受け入れられた答えでなければなりません! –

1

これらの回答はすべて間違っています。ホスト名と一致しないCNを処理する場合は、InsecureSkipVerifyを使用しないでください。 Goの開発者は、トンネル、ナット、共有クラスター証明書などの正当な用途を持っているホスト名のチェックを無効にしないことを馬鹿にしていましたが、実際には似ているものの、実際にはは証明書のチェックを無視します。証明書が有効であり、信頼する証明書によって署名されていることを知る必要があります。しかし、一般的なシナリオでは、CNはあなたが接続したホスト名と一致しないことを知っています。その場合はServerNametls.Configに設定してください。 tls.Config.ServerName == remoteServerCNの場合、証明書のチェックは成功します。これはあなたが望むものです。 InsecureSkipVerifyは、認証がないことを意味します。それはマン・イン・ザ・ミドルズにとって熟している。 TLSを使用する目的を破っています。

InsecureSkipVerifyには1つの正当な用途があります。ホストに接続して証明書を取得し、すぐに切断するために使用します。 InsecureSkipVerifyを使用するようにコードを設定した場合は、通常、ServerNameを正しく設定していないためです(env varなどから来る必要があります)。

特に、クライアント証明書を使用して認証に頼っているのであれば、実際にはログインしていない偽のログインが基本的にあります。 InsecureSkipVerifyのコードを拒否するか、難しいことが間違っているかを学びます。

+0

私はこれをテストできるサイトを知っていますか? golang orgはもうエラーをスローしません。 – topskip

+0

はopensslツールを使用して証明書を作成します。これを徹底的にテストするための単体テストを書くことができます。 – Rob

+0

この回答はとても間違っています。ホスト名に関係なく有効に署名された証明書を受け入れるなら、まだ本当のセキュリティは得られません。私が管理しているどのドメインでも有効な証明書を簡単に入手できます。あなたがTLSチェックのために私のホスト名を指定するつもりなら、私が本当に私が言っている妥当性検証を失います。その時点で、証明書が「合法」であるということは問題ではありません。それは間違っていて、あなたは真ん中の人間に脆弱です。 –

関連する問題