2017-07-11 13 views
7

クライアントがSSL CONNECTメソッドを使用する場合でも、SSLハンドシェイクを直ちに期待しているプロキシをテストしようとしています。問題は、私のGolangとPythonテストコードの両方に同じ欠陥があるようです。彼らは、明確にプロキシに接続し、次にCONNECTを発行しますが、プロキシはSSLハンドシェイクを期待しているのでこれを拒否します。SSLを含む、完全に暗号化されたHTTPSプロキシ接続

いずれかの技術が、利用可能な標準ライブラリを使用してプロキシにSSLを使用する方法を知っていますか?

ありがとうございました。

サンプルコードは次のとおりです。

#!/usr/bin/python 

try: 
    import urllib2 

    proxy = urllib2.ProxyHandler({'https': "myproxyip:6881"}) 
    opener = urllib2.build_opener(proxy) 
    urllib2.install_opener(opener) 
    print urllib2.urlopen('https://www.google.ca').read() 

except Exception as err: 
    print err 


try: 
    import httplib 

    c = httplib.HTTPSConnection('myproxyip', 6881) 
    c.set_tunnel('google.ca', 443) 
    c.request('GET', '/') 
    res = c.getresponse() 
    print res.status, res.reason 

except Exception as err: 
    print err 

とgolang

// vim: ft=go ts=4 sw=4 et ai: 
package main 

import (
    "net/http" 
    "log" 
    "io/ioutil" 
    "time" 
    "crypto/tls" 
    "net/url" 
    ) 

var use_proxy = true 
var proxy = "https://myproxyip:6881" 
var req_url = "https://google.ca" 
var n_seconds time.Duration = 15 
var period = time.Second * n_seconds 
var n_threads = 50 
var thread_start_delay time.Duration = 1 

func http_fetch(req_url string) { 
    tr := http.Transport { 
     TLSClientConfig: &tls.Config { 
      InsecureSkipVerify: true, 
     }, 
    } 
    proxy_url, err := url.Parse(proxy) 
    if err != nil { 
     log.Fatal(err) 
    } 
    if use_proxy { 
     tr.Proxy = http.ProxyURL(proxy_url) 
    } 
    client := &http.Client{} 
    client.Transport = &tr 

    req, err := http.NewRequest("GET", req_url, nil) 
    if err != nil { 
     log.Fatal(err) 
    } 
    req.Header.Set("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36") 

    res, err := client.Do(req) 
    if err != nil { 
     log.Fatal(err) 
    } 
    body, err := ioutil.ReadAll(res.Body) 
    defer res.Body.Close() 
    document := string(body) 
    print(document) 
} 


func main() { 
    println("main: Starting", n_threads, "threads to hammer", req_url, "every", n_seconds, "seconds, ctrl-c to quit...") 
    done := make(<-chan bool) 
    for i:= 0; i < n_threads; i++ { 
     go func(thread_id int) { 
      println("thread", thread_id, ": starting periodic_hammer") 
      for { 
       println("thread", thread_id, ": fetching", req_url) 
       http_fetch(req_url) 
       println("thread", thread_id, ": done, sleeping for", n_seconds, "seconds") 
       time.Sleep(period) 
      } 
     }(i+1) 
     println("main: delaying", thread_start_delay, "seconds before starting next thread") 
     time.Sleep(thread_start_delay * time.Second) 
    } 
    <-done 
} 
+0

が見えます:/ /golang.org/src/net/http/transport.go?s=10819:10884#L1030)) - 私はHTTPSについてよく知らないが、これが標準に準拠していない場合は、[バグレポートを提出する] (https://github.com/golang/go/issues)。 – Adrian

+0

私は以前は標準に準拠していたと思っていますが、私たちはHTTPSのプロキシで純粋なSSLに移行しています。ブラウザはそれをサポートしていますが、それをサポートする最新のlibcurl以外は何も見つかりません。 –

+0

標準に準拠していない場合は、不幸にもサポートは不自然になります。 – Adrian

答えて

0

にproxyHandlerに加えて、Pythonの標準ライブラリを使用して、この問題への可能な解決はあなたが持っている:

import ssl, urllib2 

# Set ciphers and ssl settings 
ctx = ssl.create_default_context() 
ctx.check_hostname = False 
ctx.verify_mode = ssl.CERT_NONE 
ctx.set_ciphers('HIGH:!DH:!aNULL') 

# Set proxy settings 
proxy = urllib2.ProxyHandler({'https':'<https proxy host>:443', 'http':'<http proxy host>:8080'}) 
opener = urllib2.build_opener(urllib2.HTTPSHandler(context=ctx), proxy) 
urllib2.install_opener(opener) 
+0

同じ問題が発生しているようです。 –

+0

この行の場合:proxy = urllib2.ProxyHandler({'https': ':443'、 'http': ':8080'})独自のプロキシ実装を使用していますか? –

+0

はい。私はパケットのトレースで再確認しますが、まだ明らかに接続していると思います。 –

0

で私は自分のクライアントを本質的にやらなければなりませんでした。

func http_fetch(req_host string) { 
    buf := make([]byte, 1024) 
    conf := &tls.Config { 
     InsecureSkipVerify: true, 
    } 

    conn, err := tls.Dial("tcp", proxy_host, conf) 
    if err != nil { 
     //panic(err) 
     failure() 
     return 
    } 
    defer conn.Close() 

    // SSL CONNECT 
    if _, err = conn.Write([]byte("CONNECT " + req_host + " HTTP/1.0\r\n\r\n")); err != nil { 
     // FIXME: need debug logger? 
     //panic(err) 
     failure() 
     return 
    } 

    // Read response 
    if _, err = conn.Read(buf); err != nil { 
     //panic(err) 
     failure() 
     return 
    } 

    // Send http GET 
    if _, err = conn.Write([]byte("GET/HTTP/1.0\r\n")); err != nil { 
     //panic(err) 
     failure() 
     return 
    } 
    if _, err = conn.Write([]byte("User-Agent: golang\r\n\r\n")); err != nil { 
     //panic(err) 
     failure() 
     return 
    } 

    // Read response 
    if _, err = conn.Read(buf); err != nil { 
     //panic(err) 
     failure() 
     return 
    } 
    success() 
} 
関連する問題