在提出这个问题之前,我做了大量的研究和实践。
说来话长:
我找到了一个关于如何用Node.js编写http代理的(非英语)教程。
到目前为止,我所知道和尝试的是:
- HTTP代理可以处理HTTP请求和HTTPS请求,但处理方式不同。HTTP代理通过读取客户端的请求,向目标发出新的请求,并将响应返回给客户端来处理HTTP请求。对于HTTPS请求,则通过HTTPTunnel来处理。
- Firefox代理设置中的
SSL proxy
字段和IE代理设置中的Secure
字段(Windows)都是关于HTTP隧道的设置,如果设置了SSL proxy
或Secure proxy
,当浏览器要连接https站点时,它会发送CONNECT
请求,而不是普通请求。
问题:
CONNECT
请求是纯文本的,所以防火墙可以看到我想连接的主机并切断连接。所以我一开始就在想我是否可以使用https与代理服务器通信。我阅读了所有相关的帖子,但没有找到直接谈论这个问题的答案。有些答案还说"没有https代理服务器这样的东西"。
但是教程说这是可以做到的(客户端和代理服务器之间的HTTPS,其他什么都不会改变)。所以我试了一下。我用我网站的证书把服务器改成了https。但是最终它只适用于Chrome中的Proxy SwitchOmega。在传统的设置中,比如Firefox代理或IE代理设置中,它不起作用。
代理交换机Omega设置:
Scheme|Protocol|Server|Port
.... | https | .... |...
如果我启动https服务器,我必须在这里选择https
协议。同样,如果我启动http服务器,我必须选择http
协议。我也不知道这个protocol
字段代表什么。
总结一下:
proxy server | Firefox proxy setting |work? | SwitchOmega setting |work?|
http | http + ssl setting | yes | protocol http |yes |
https | http + ssl setting | no | protocol https |yes |
https | - | - | protocal http |no |
所以我的问题是:
1.我可以通过普通的方式(没有扩展)连接到https代理服务器吗?如果可能,如何连接?
1.为什么可以通过SwitchOmega连接到https代理服务器?
1.我想我建立了一个https代理服务器,但是为什么其他人说"没有https代理服务器这样的东西?"
源代码
https服务器
var http = require('http');
var https = require('https');
var fs = require('fs');
var net = require('net');
var url = require('url');
console.log("qqqqq2");
function request(cReq, cRes) {
console.log("request=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("request=====end");
var u = url.parse(cReq.url);
var options = {
hostname : u.hostname,
port : u.port || 80,
path : u.path,
method : cReq.method,
headers : cReq.headers
};
var pReq = http.request(options, function(pRes) {
cRes.writeHead(pRes.statusCode, pRes.headers);
pRes.pipe(cRes);
}).on('error', function(e) {
cRes.end();
});
cReq.pipe(pReq);
// console.log(cReq.headers);
// console.log(cReq.method);
// console.log(cReq.url);
// console.log("^_^^_^^_^^_^^_^^_^");
// cRes.writeHead('200');
// cRes.end('hello world2222\n');
}
function connect(cReq, cSock) {
console.log("connect=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("connect=====end");
var u = url.parse('http://' + cReq.url);
var pSock = net.connect(u.port, u.hostname, function() {
cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
pSock.pipe(cSock);
}).on('error', function(e) {
cSock.end();
});
cSock.pipe(pSock);
}
var options = {
key: fs.readFileSync('./privkey1.pem'),
cert: fs.readFileSync('./fullchain1.pem')
};
https.createServer(options)
.on('request', request)
.on('connect', connect)
.listen(9999, '0.0.0.0');
http服务器
var http = require('http');
var net = require('net');
var url = require('url');
console.log('qqqqq2');
function request(cReq, cRes) {
console.log("request=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("request=====end");
var u = url.parse(cReq.url);
var options = {
hostname : u.hostname,
port : u.port || 80,
path : u.path,
method : cReq.method,
headers : cReq.headers
};
var pReq = http.request(options, function(pRes) {
cRes.writeHead(pRes.statusCode, pRes.headers);
pRes.pipe(cRes);
}).on('error', function(e) {
cRes.end();
});
cReq.pipe(pReq);
}
function connect(cReq, cSock) {
console.log("connect=====start");
console.log(cReq.headers);
console.log(cReq.url);
console.log(cReq.method);
console.log("connect=====end");
var u = url.parse('http://' + cReq.url);
var pSock = net.connect(u.port, u.hostname, function() {
cSock.write('HTTP/1.1 200 Connection Established\r\n\r\n');
pSock.pipe(cSock);
}).on('error', function(e) {
cSock.end();
});
cSock.pipe(pSock);
}
http.createServer()
.on('request', request)
.on('connect', connect)
.listen(9999, '0.0.0.0');
测试服务器
你可以很容易地建立一个http代理服务器并测试它。但是建立一个https代理服务器可能会很麻烦,因为你需要部署证书。所以提供了一个https代理测试服务器,基于上面的代码。
测试服务器已删除,因为我找到了答案。
2条答案
按热度按时间vx6bjr1n1#
我在Security StackExchange中找到了答案。Is it possible to connect to a proxy with an ssl (or otherwise encrypted) connection?
来自www.example.com:https://wiki.squid-cache.org/Features/HTTPS#Encrypted_browser-Squid_connection :
加密的浏览器-Squid连接
Squid可以使用https_port接受常规代理流量,就像Squid使用http_port指令一样。**不幸的是,流行的现代浏览器不允许配置TLS/SSL加密代理连接。**现在有针对大多数这些浏览器的公开错误报告,等待支持出现。如果您有任何兴趣,请帮助浏览器团队实现这一点。
...
chrome
如果在PAC文件或命令行开关中配置为使用SSL连接,Chrome浏览器可以通过SSL连接连接到代理。GUI配置似乎还不可能。
火狐
Firefox 33.0浏览器能够通过TLS连接连接到代理,如果配置为使用PAC文件中的一个。GUI配置似乎还不可能,尽管有一个嵌入PAC逻辑的配置黑客。
有关Chrome的更多信息可以在http://dev.chromium.org/developers/design-documents/secure-web-proxy中找到。
要回答以下问题:
1.我可以通过普通的方式(没有扩展)连接到https代理服务器吗?如果可能,如何连接?
传统的设置http代理服务器的方式(例如Firefox中的
Manual proxy configuration
字段)仅适用于HTTP代理服务器。用户只能通过pac
文件(例如Firefox中的Automatic proxy configuration URL
字段)设置https代理。1.为什么我可以通过SwitchOmega连接到https代理服务器?
SwitchOmega扩展实际上生成了一个
pac
文件供Chrome使用,尽管到目前为止我还不知道它如何与Chrome交互。通过单击SwitchOmega中的
Export PAC
按钮,我得到一个包含以下内容的文件:从https://developer.mozilla.org/en-US/docs/Web/HTTP/Proxy_servers_and_tunneling/Proxy_Auto-Configuration_(PAC)_file开始:
1.我想我建立了一个https代理服务器,但是为什么其他人说"没有https代理服务器这样的东西?"
是的,我在tls连接上建立了一个https代理服务器/一个http代理服务器。那些说"没有https代理服务器这样的东西"的人是错误的。
deikduxw2#
AFAIK没有官方的HTTPS代理规范。
Rick在他的回答中提到的是Squid的黑客攻击,通过终止浏览器TLS请求,然后向目标服务器发起另一个TLS请求,允许他们缓存以前由于https而无法缓存的内容。本质上,Squid充当了浏览器和服务器之间的MITM。尽管连接仍然受到TLS保护,但Squid可以看到流量。如果Web服务器正在实施HSTS,浏览器不允许我们连接。
我期望从HTTPS代理是浏览器启动两个TLS连接。它首先启动TLS连接到代理服务器,然后请求连接到预期的Web服务器,并启动另一个TLS。