2017-07-11 15 views
7

Próbuję przetestować serwer proxy, który oczekuje natychmiastowego uzgadniania SSL, nawet jeśli klient zamierza użyć metody SSL CONNECT. Problem polega na tym, że mój kod testowy Golanga i Pythona wydaje się mieć tę samą wadę. Łączą się z serwerem proxy w sposób przejrzysty, a następnie wysyłają połączenie, ale serwer proxy odrzuca to, ponieważ spodziewa się uzgadniania SSL.HTTPS przez proxy całkowicie zaszyfrowane, w tym SSL CONNECT

Czy ktoś wie, jak zmusić obie technologie do korzystania z protokołu SSL do proxy przy użyciu dostępnych standardowych bibliotek?

Dzięki.

Przykładowy kod następująco:

#!/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 

i 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

Wygląda wersja Go zawsze wystawia "CONNECT" dla HTTPS ([patrz źródło] (https://golang.org/src/net/http/transport.go?s=10819:10884#L1030)) - Nie wiem zbyt wiele na temat HTTPS, ale jeśli nie jest to zachowanie zgodne z normami, możesz [zgłoś zgłoszenie błędu] (https://github.com/golang/go/issues). – Adrian

+0

Sądzę, że kiedyś były zgodne ze standardami, ale jesteśmy w trakcie przejścia na protokół SSL na proxy dla HTTPS. Przeglądarka obsługuje to, ale nie znajduję niczego poza najnowszą biblioteką libcurl, która ją obsługuje. –

+0

Jeśli nie jest zgodny ze standardami, wsparcie będzie w najlepszym razie niecodzienne. – Adrian

Odpowiedz

0

Możliwe rozdzielczości do tej kwestii przy użyciu standardowych Python bibliotek oprócz ProxyHandler masz:

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

Wygląda na to, że wyświetlany jest ten sam problem. –

+0

Dla tego wiersza: proxy = urllib2.ProxyHandler ({'https': ': 443', 'http': ': 8080'}) Czy zastąpiłeś host hosta i z własną implementacją proxy? –

+0

Tak. Sprawdzę dwa razy, śledząc pakiet, ale myślę, że nadal się łączy. –

0

W Koniec końców, musiałem w zasadzie zrobić własnego klienta.

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() 
}