2012-08-25 24 views
79

कहें कि मैं https://golang.org प्रोग्रामेटिक रूप से प्राप्त करना चाहता हूं। वर्तमान में golang.org (एसएसएल) एक बुरा प्रमाण पत्र तो जब मैं चलाने के जो *.appspot.com को जारी किया जाता है यह:गोलांग: खराब प्रमाणपत्र के साथ 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 

अब, मैं इस पर विश्वास करना चाहते प्रमाण पत्र स्वयं (एक स्व-जारी प्रमाण पत्र की कल्पना करें जहां मैं फिंगरप्रिंट इत्यादि को मान्य कर सकता हूं): मैं कैसे अनुरोध कर सकता हूं और प्रमाण पत्र को प्रमाणित/भरोसा कर सकता हूं?

मुझे शायद प्रमाणपत्र डाउनलोड करने के लिए openssl का उपयोग करने की आवश्यकता है, इसे अपनी फ़ाइल में लोड करें और tls.Config संरचना भरें!

+0

यह एक "खराब प्रमाण पत्र" नहीं है, यह एक अलग सीएन के साथ एक प्रमाण पत्र है। InsecureSkipVerify यहां एक वैध उपयोग नहीं है। आपको सर्वर नाम को टीएलएस में सेट करना होगा।आप जो कनेक्ट करने का प्रयास कर रहे हैं उससे मेल खाने के लिए कॉन्फ़िगर करें। यह स्टैक ओवरफ्लो पोस्ट हर जगह फैलाने के लिए गो कोड में इस बड़े सुरक्षा छेद का कारण बन रहा है। InsecureSkipVerify प्रमाण पत्र की जांच नहीं करता है। आप जो चाहते हैं उसे सत्यापित करना है कि प्रमाण पत्र वैध रूप से किसी विश्वसनीय इकाई द्वारा हस्ताक्षरित किया गया था, भले ही सीएन होस्टनाम से मेल नहीं खाता हो। सुरंगों और एनएटीएस वैध रूप से इसे मेल नहीं कर सकते हैं। – 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

मुझे आश्चर्य है कि एक विश्वसनीय प्रमाणपत्र कहां रखा जाए ताकि कनेक्शन का उपयोग 'असुरक्षित स्किप सत्यापित करें: सत्य' के बिना किया जा सके। क्या यह संभव है? – 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

ऐसा करने के परिणामस्वरूप 'पैनिक: रनटाइम त्रुटि: अमान्य मेमोरी पता या शून्य पॉइंटर डेरफ़्रेंस' – OscarRyz

+4

यदि आप इससे पहले डिफ़ॉल्ट http अनुरोधकर्ता का उपयोग नहीं करते हैं, तो आपको एक नकली अनुरोध को मजबूर करना होगा ताकि डिफ़ॉल्ट ट्रांसपोर्ट को प्रारंभ किया जा सके –

+0

यह नहीं है होस्टनाम चेक अक्षम करना। यह सभी प्रमाणपत्र जांच अक्षम करता है। आप जो कनेक्ट करते हैं उसके प्रमाण में सीएन के बराबर सर्वर नाम को सेट करने के लिए आपको मजबूर करें। InsecureSkipVerify एक दुष्ट एमआईटीएम सर्वर से कनेक्ट होगा जो वास्तविक सेवाओं को आगे बढ़ाने का नाटक करता है। एक 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

ये सभी उत्तर गलत हैं! एक सीएन से निपटने के लिए InsecureSkipVerify का उपयोग न करें जो होस्टनाम से मेल नहीं खाता है। गो डेवलपर्स अनजाने में मेजबाननाम चेक (जिसमें वैध उपयोग हैं - सुरंगों, नट्स, साझा क्लस्टर कर्ट इत्यादि) को अक्षम करने के बारे में अशिष्ट थे, जबकि कुछ ऐसा दिखता है, लेकिन वास्तव में पूरी तरह से प्रमाणपत्र जांच को अनदेखा करता है। आपको यह जानना होगा कि प्रमाण पत्र मान्य है और उस प्रमाणपत्र द्वारा हस्ताक्षरित है जिस पर आप भरोसा करते हैं। लेकिन सामान्य परिदृश्यों में, आप जानते हैं कि सीएन आपके द्वारा जुड़े होस्टनाम से मेल नहीं खाएगा। उन लोगों के लिए, tls.Config पर ServerName सेट करें। यदि tls.Config.ServerName == रिमोटसेवर सीएन, तो प्रमाणपत्र जांच सफल होगी। आप यही चाहते हैं। InsecureSkipVerify का मतलब है कि कोई प्रमाणीकरण नहीं है; और यह मैन-इन-द-मध्य के लिए परिपक्व है; टीएलएस का उपयोग करने के उद्देश्य को हराया।

InsecureSkipVerify के लिए एक वैध उपयोग है: इसे होस्ट से कनेक्ट करने और उसके प्रमाणपत्र को पकड़ने के लिए इसका उपयोग करें, फिर तुरंत डिस्कनेक्ट करें। यदि आप InsecureSkipVerify का उपयोग करने के लिए अपना कोड सेट करते हैं, तो आमतौर पर यह ServerName ठीक से सेट नहीं किया गया था (इसे एक env var या कुछ से आना होगा - इस आवश्यकता के बारे में पेट-दर्द न करें ... इसे सही तरीके से करें)।

विशेष रूप से, यदि आप ग्राहक के संपर्कों का उपयोग करते हैं और प्रमाणीकरण के लिए उन पर भरोसा करते हैं, तो मूल रूप से एक नकली लॉगिन होता है जो वास्तव में और लॉगिन नहीं करता है। कोड को अस्वीकार करें जो InsecureSkipVerify करता है, या आप सीखेंगे कि इसमें क्या गलत है!

+0

क्या आपको ऐसी साइट जाननी है जहां मैं इसका परीक्षण कर सकता हूं? गोलांग संगठन अब एक त्रुटि फेंक नहीं है। – topskip

+0

प्रमाणपत्र बनाने के लिए openssl उपकरण का उपयोग करें। आप पूरी तरह से परीक्षण करने के लिए यूनिट परीक्षण लिख सकते हैं। – Rob

+0

यह उत्तर बहुत भ्रामक है। यदि आप होस्टनाम के बावजूद किसी भी वैध हस्ताक्षरित प्रमाणपत्र को स्वीकार करते हैं, तो आपको अभी भी वास्तविक सुरक्षा नहीं मिल रही है। मैं आसानी से किसी भी डोमेन के लिए एक वैध प्रमाणपत्र प्राप्त कर सकता हूं; यदि आप टीएलएस चेक के लिए अपना होस्टनाम निर्दिष्ट करने जा रहे हैं, तो आप सत्यापन खो देते हैं कि मैं वास्तव में हूं जो मैं कहता हूं कि मैं हूं। उस बिंदु पर, तथ्य यह है कि प्रमाण पत्र "कानूनी" है इससे कोई फर्क नहीं पड़ता; यह _still_ गलत है और आप मध्य में आदमी के लिए _still_ कमजोर हैं। –

संबंधित मुद्दे