首页 新闻页 最新可以使用的http代理IP怎么样才能扫描到

最新可以使用的http代理IP怎么样才能扫描到

本文关键次:http代理IP,IP代理,代理IP

HTTP 代理IP存在两种形式,分别简单介绍如下:

第一种,普通IP代理,扮演中间人的角色,对于链接到他的客户来说,他是服务端;对于要链接的服务端来说,他就是客户端。

他就是负责两端之间来回传送http报文。用通俗的话来说他就是跑腿的。

第二种 隧道代理IP。隧道代理IP通过 HTTP 协议正文部分(Body)完成通讯,以 HTTP 的方式实现任意基于 TCP 的应用层协议代理。

普通代理

以web代理原理是比较简单的:

http客户端向IP代理发送请求报文,代理服务器需要正确地处理请求和连接,同时向服务器发送请求,并将收到的回应的信息转发给客户端。

下面这张图片来自于《HTTP 权威指南》,直观地展示了上述行为:

text

假设我通过代理IP访问了A网站,对于A来说,他的客户端就是代理IP 的地址,并不能察觉到真正的客户端是谁,可以实现隐藏客户端IP的目的。 当然IP代理也可以修改 HTTP 请求头部,

通过X-Forwarded-IP

复制代码

这种自定义的模式告知了服务端真正的客户端IP是什么。但是服务器没有办法验证这个自动以头部真的是由代理添加的,还是说客户端更改了请求头,所以从http 头部字段获取 IP 时,要谨慎小心

给浏览器显式的指定代理,需要我们手动的更改浏览器或操作系统相关设置,或者是指定自动配置代理IP,文件会选择自动设置

浏览器或操作系统相关设置,或者指定 PAC(Proxy Auto-Configuration,自动配置代理)文件自动设置,

还有些浏览器支持 WPAD(Web Proxy Autodiscovery Protocol,Web 代理自动发现协议)。显式指定浏览器代理这种方式一般称之为正向代理,浏览器启用正向代理后,

会对 HTTP 请求报文做一些修改,来规避老旧代理服务器的一些问题。 还有一种情况是访问 A 网站时,实际上访问的是代理,代理收到请求报文后,再向真正提供服务的服务器发起请求,并将响应转发给浏览器。

这种情况一般被称之为反向代理,它可以用来隐藏服务器 IP 及端口。

一般使用反向代理后,需要通过修改 DNS 让域名解析到代理服务器 IP,这时浏览器无法察觉到真正服务器的存在,当然也就不需要修改配置了。

反向代理是 Web 系统最为常见的一种部署方式,例如本博客就是使用 Nginx 的

proxy_pass

复制代码 功能将浏览器请求转发到背后的 Node.js 服务。

了解完第一种代理的基本原理后,我们用 Node.js 实现一下它。只包含核心逻辑的代码如下:

var http = require('http');

var net = require('net');

var url = require('url');

function request(cReq, cRes) {

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);

}

http.createServer().on('request', request).listen(8888, '0.0.0.0');

以上代码运行后,会在本地 8888 复制代码

端口开启 HTTP 代理服务,这个服务从请求报文中解析出请求 URL 和其他必要参数,新建到服务端的请求,并把代理收到的请求转发给新建的请求,

最后再把服务端响应返回给浏览器。修改浏览器的 HTTP 代理为

127.0.0.1:8888

复制代码

后再访问 HTTP 网站,代理可以正常工作。

但是,使用代理服务后,HTTPS 网站完全没有办法访问访问,原因就是这个代理提供的是 HTTP 服务,根本没办法承载 HTTPS 服务。

那么是否把这个代理改为 HTTPS 就可以了呢?很显然并不行,因为这种代理的本质是中间人,而 HTTPS 网站的证书认证机制是中间人劫持的克星。

普通的 HTTPS 服务中,服务端不验证客户端的证书,中间人可以作为客户端与服务端成功完成 TLS 握手;但是中间人没有证书私钥,是没有办法伪造成服务端跟客户端建立 TLS 连接。

如果你拥有证书私钥,代理证书对应的 HTTPS 网站当然就没问题了。

HTTP 抓包神器 Fiddler 的工作原理也是在本地开启 HTTP 代理服务,通过让浏览器流量走这个代理,从而实现显示和修改 HTTP 包的功能。

如果要让 Fiddler 解密 HTTPS 包的内容,需要先将它自带的根证书导入到系统受信任的根证书列表中。

一旦完成这一步,浏览器就会信任 Fiddler 后续的「伪造证书」,从而在浏览器和 Fiddler、Fiddler 和服务端之间都能成功建立 TLS 连接。而对于 Fiddler 这个节点来说,两端的 TLS 流量都是可以解密的。

如果我们不导入根证书,Fiddler 的 HTTP 代理ip还能代理 HTTPS 流量么?通过实践,Fiddler 只是无法解密 HTTPS 流量,但是HTTPS 网站还是可以正常访问。

这是如何做到的,这些 HTTPS 流量是否安全呢?这些问题将在下一节揭晓。

[h1]隧道代理[/h1]第二种 Web 代理的原理也很简单:

HTTP 客户端通过 CONNECT 方法请求隧道代理创建一条到达任意目的服务器和端口的 TCP 连接,并对客户端和服务器之间的后继数据进行盲转发。

下面这张图片同样来自于《HTTP 权威指南》,直观地展示了上述行为:

text

假如我通过代理访 A 网站,浏览器首先通过 CONNECT 请求,让代理创建一条到 A 网站的 TCP 连接;一旦 TCP 连接建好,代理无脑转发后续流量即可。

所以这种代理,理论上适用于任意基于 TCP 的应用层协议,HTTPS 网站使用的 TLS 协议当然也可以。

这也是这种代理为什么被称为隧道的原因。对于 HTTPS 来说,客户端透过代理直接跟服务端进行 TLS 握手协商密钥,所以依然是安全的,下图中的抓包信息显示了这种场景:

可以看到,浏览器与代理进行 TCP 握手之后,发起了 CONNECT 请求,报文起始行如下: CONNECT imququ.com:443 HTTP/1.1 复制代码 对于 CONNECT 请求来说,只是用来让代理创建 TCP 连接,所以只需要提供服务器域名及端口即可,并不需要具体的资源路径。代理收到这样的请求后,需要与服务端建立 TCP 连接,并响应给浏览器这样一个 HTTP 报文: HTTP/1.1 200 Connection Established 复制代码 浏览器收到了这个响应报文,就可以认为到服务端的 TCP 连接已经打通,后续直接往这个 TCP 连接写协议数据即可。通过 Wireshark 的 Follow TCP Steam 功能,可以清楚地看到浏览器和代理之间的数据传递:

可以看到,浏览器建立到服务端 TCP 连接产生的 HTTP 往返,完全是明文,这也是为什么 CONNECT 请求只需要提供域名和端口:如果发送了完整 URL、Cookie 等信息,会被中间人一览无余,降低了 HTTPS 的安全性。

HTTP 代理承载的 HTTPS 流量,应用数据要等到 TLS 握手成功之后通过 Application Data 协议传输,中间节点无法得知用于流量加密的 master-secret,无法解密数据。

而 CONNECT 暴露的域名和端口,对于普通的 HTTPS 请求来说,中间人一样可以拿到(IP 和端口很容易拿到,请求的域名可以通过 DNS Query 或者 TLS Client Hello 中的 Server Name Indication 拿到),所以这种方式并没有增加不安全性。 了解完原理后,再用 Node.js 实现一个支持 CONNECT 的代理也很简单。核心代码如下:

var http = require('http');

var net = require('net');

var url = require('url');

function connect(cReq, cSock) {

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('connect', connect).listen(8888, '0.0.0.0');

以上代码运行后,会在本地 8888 复制代码 端口开启 HTTP 代理服务,这个服务从 CONNECT 请求报文中解析出域名和端口,创建到服务端的 TCP 连接,并和 CONNECT 请求中的 TCP 连接串起来,最后再响应一个 Connection Established 响应。修改浏览器的 HTTP 代理为 127.0.0.1:8888 复制代码 后再访问 HTTPS 网站,代理可以正常工作。

最后,将两种代理的实现代码合二为一,就可以得到全功能的 Proxy 程序了,全部代码在 50 行以内: var http = require('http');

var net = require('net');

var url = require('url');

function request(cReq, cRes) {

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) {

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(8888, '0.0.0.0');

需要注意的是,大部分浏览器显式配置了代理之后,只会让 HTTPS 网站走隧道代理,这是因为建立隧道需要耗费一次往返,能不用就尽量不用。

但这并不代表 HTTP 请求不能走隧道代理,我们用 Node.js 写段程序验证下(先运行前面的代理服务):

var http = require('http');

var options = {

hostname : '127.0.0.1',

port : 8888,

path : 'imququ.com:80',

method : 'CONNECT'

};

var req = http.request(options);

req.on('connect', function(res, socket) {

socket.write('GET / HTTP/1.1\r\n' +

'Host: http://imququ.com\r\n' +

'Connection: Close\r\n' +

'\r\n');

socket.on('data', function(chunk) {

console.log(chunk.toString());

});


socket.on('end', function() {

console.log('socket end.');

});

});

req.end();

这段代码运行完,结果如下:

HTTP/1.1 301 Moved Permanently

Server: nginx

Date: Thu, 19 Nov 2015 15:57:47 GMT

Content-Type: text/html

Content-Length: 178

Connection: close

Location: https://imququ.com/

301 Moved Permanently

301 Moved Permanently

nginx

socket end.

可以看到,通过 CONNECT 让代理打开到目标服务器的 TCP 连接,用来承载 HTTP 流量也是完全没问题的。

最后,HTTP 代理IP的认证机制可以跟代理配合使用,使得必须输入正确的用户名和密码才能使用代理。