我正在尝试立即测试期望SSL握手的代理,即使客户端将使用SSL CONNECT方法。问题是我的Golang和Python测试代码似乎都有相同的缺陷。它们以明文形式连接到代理,然后发出CONNECT,但代理拒绝这一点,因为它期待SSL握手。
有没有人知道如何使用可用的标准库强制任何一种技术将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 :(得分: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)
答案 1 :(得分: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()
}
答案 2 :(得分:0)
仅从Go 1.10开始支持使用https代理。来自draft release notes:
在客户端,HTTP代理(最常见的配置) ProxyFromEnvironment现在可以指定为https:// URL,意思是 客户端在发出之前通过HTTPS连接到代理 标准的,代理的HTTP请求。 (以前,HTTP代理URL是 需要以http://或socks5://开始。)