• HTTP代理


    HTTP代理存在两种形式:

    第一种是 RFC 7230 - HTTP/1.1: Message Syntax and Routing(即修订后的 RFC 2616,HTTP/1.1 协议的第一部分)描述的普通代理。这种代理扮演的是「中间人」角色,对于连接到它的客户端来说,它是服务端;对于要连接的服务端来说,它是客户端。它就负责在两端之间来回传送 HTTP 报文。

    第二种是 Tunneling TCP based protocols through Web proxy servers(通过 Web 代理服务器用隧道方式传输基于 TCP 的协议)描述的隧道代理。它通过 HTTP 协议正文部分(Body)完成通讯,以 HTTP 的方式实现任意基于 TCP 的应用层协议代理。这种代理使用 HTTP 的 CONNECT 方法建立连接,但 CONNECT 最开始并不是 RFC 2616 - HTTP/1.1 的一部分,直到 2014 年发布的 HTTP/1.1 修订版中,才增加了对 CONNECT 及隧道代理的描述,详见 RFC 7231 - HTTP/1.1: Semantics and Content。实际上这种代理早就被广泛实现。

    本文描述的第一种代理,对应《HTTP 权威指南》一书中第六章「代理」;第二种代理,对应第八章「集成点:网关、隧道及中继」中的 8.5 小节「隧道」。

    第一种普通代理:

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

    假如我通过代理访问 A 网站,浏览器首先通过 CONNECT 请求,让代理创建一条到 A 网站的 TCP 连接;一旦 TCP 连接建好,代理无脑转发后续流量即可。所以这种代理,理论上适用于任意基于 TCP 的应用层协议,HTTPS 网站使用的 TLS 协议当然也可以。这也是这种代理为什么被称为隧道的原因。对于 HTTPS 来说,客户端透过代理直接跟服务端进行 TLS 握手协商密钥,所以依然是安全的,下图中的抓包信息显示了这种场景:

    wireshark_connect

    可以看到,浏览器与代理进行 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 功能,可以清楚地看到浏览器和代理之间的数据传递:

    wireshark_connect_detail

    可以看到,浏览器建立到服务端 TCP 连接产生的 HTTP 往返,完全是明文,这也是为什么 CONNECT 请求只需要提供域名和端口:如果发送了完整 URL、Cookie 等信息,会被中间人一览无余,降低了 HTTPS 的安全性。HTTP 代理承载的 HTTPS 流量,应用数据要等到 TLS 握手成功之后通过 Application Data 协议传输,中间节点无法得知用于流量加密的 master-secret,无法解密数据。而 CONNECT 暴露的域名和端口,对于普通的 HTTPS 请求来说,中间人一样可以拿到(IP 和端口很容易拿到,请求的域名可以通过 DNS Query 或者 TLS Client Hello 中的 Server Name Indication 拿到),所以这种方式并没有增加不安全性。

    HTTP代理和HTTPS代理的区别?

    HTTP和HTTPS代理服务器,一般指的是代理服务器支持HTTPS协议和HTTP协议,
    如果请求的URL是http的,使用HTTP代理服务器,客户端->代理服务器->服务器之间数据都是明文的,不安全的。如果请求的URL是https,且代理服务器支持https协议,那么使用代理服务器时,代理服务器一般会使用CONNECT method(隧道模式,客户端和代理服务器之间建立隧道进行通信)数据是安全的。
    HTTP代理有多种做法,通常使用CONNECT method,通过proxy建立一条隧道(隧道代理),这样proxy无法解密数据;此外,还有一种类似于中间人攻击的代理手法。
     
    connect 建立过程都是明文的,但是 CONNECT 请求只需要提供域名和端口,这样子保证了请求的安全性,真正的数据需要等到TLS 握手成功后才用加密发送出去。
    也就是说,使用了proxy后,代理服务器和客户端之间的通信是明文的,但是两者之间交换的只有域名和端口,proxy对客户端传过来的数据做解析取出域名和端口,跟服务器建立连接,建立好连接后给客户端返回,此时就算是建立好隧道了,建立好隧道后,客户端直接在隧道里跟服务器通信,此时proxy只是做个转发,不会再处理客户端的数据

    connect方法
    http 1.1定义了8种方法,connect为其中之一,HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。通常用于SSL加密服务器的链接(经由非加密的HTTP代理服务器)。
    并非所有的http隧道支持connect方法,Http隧道分为两种:
    1  不使用CONNECT的隧道
    不使用CONNECT的隧道,实现了数据包的重组和转发。在Proxy收到来自客户端的Http请求之后,会重新创建Request请求,并发送到目标服务器,。当目标服务器返回Response给Proxy之后,Proxy会对Response进行解析,然后重新组装Response,发送给客户端。所以,在不使用CONNECT方式建立的隧道,Proxy有机会对客户端与目标服务器之间的通信数据进行窥探,而且有机会对数据进行串改。
     
    2  使用CONNECT的隧道
    而对于使用CONNECT的隧道则不同。当客户端向Proxy发起Http CONNECT Method的时候,就是告诉Proxy,先在Proxy和目标服务器之间先建立起连接,在这个连接建立起来之后,目标服务器会返回一个回复给Proxy,Proxy将这个回复转发给客户端,这个Response是Proxy跟目标服务器连接建立的状态回复,而不是请求数据的Response。在此之后,客户端跟目标服务器的所有通信都将使用之前建立起来的建立。这种情况下的Http隧道,Proxy仅仅实现转发,而不会关心转发的数据。这也是为什么在使用Proxy的时候,Https请求必须首先使用Http CONNECT建立隧道。因为Https的数据都是经过加密的,Proxy是无法对Https的数据进行解密的,所以只能使用CONNECT,仅仅对通信数据进行转发。

    用curl对使用代理和不使用代理做分析:

    使用代理,隧道模式

    curl -v -I   https://sp.com.cn/v
    * Uses proxy env variable https_proxy == 'http://127.0.0.1:808'
    *   Trying 127.0.0.1...
    * TCP_NODELAY set
    * Connected to 127.0.0.1 (127.0.0.1) port 808 (#0)
    * allocate connect buffer!
    * Establish HTTP proxy tunnel to xx
    > CONNECT sp.com.cn:443 HTTP/1.1
    > Host: xx
    > User-Agent: curl/7.61.0
    > Proxy-Connection: Keep-Alive
    >
    < HTTP/1.1 200 OK
    HTTP/1.1 200 OK
    < Date: Thu, 29 Apr 2021 03:29:45 GMT
    Date: Thu, 29 Apr 2021 03:29:45 GMT
    < Transfer-Encoding: chunked
    Transfer-Encoding: chunked
    * Ignoring Transfer-Encoding in CONNECT 200 response
    <
    
    * Proxy replied 200 to CONNECT request
    * CONNECT phase completed!
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: none
      CApath: /etc/ssl/certs
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * CONNECT phase completed!
    * CONNECT phase completed!
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384

    不使用代理: 

    curl -v -I   https://sp.com.cn/v
    *   Trying 121.46.8.134...
    * TCP_NODELAY set
    * Connected to sp.com.cn  port 443 (#0)
    * ALPN, offering h2
    * ALPN, offering http/1.1
    * successfully set certificate verify locations:
    *   CAfile: none
      CApath: /etc/ssl/certs
    * TLSv1.3 (OUT), TLS handshake, Client hello (1):
    * TLSv1.3 (IN), TLS handshake, Server hello (2):
    * TLSv1.2 (IN), TLS handshake, Certificate (11):
    * TLSv1.2 (IN), TLS handshake, Server key exchange (12):
    * TLSv1.2 (IN), TLS handshake, Server finished (14):
    * TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
    * TLSv1.2 (OUT), TLS change cipher, Client hello (1):
    * TLSv1.2 (OUT), TLS handshake, Finished (20):
    * TLSv1.2 (IN), TLS handshake, Finished (20):
    * SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
    
    

      

    以上可以看使用隧道模式的代理和不使用代理,都会进行TLS握手,隧道模式的代理是安全的。

    参考资料:

    https://imququ.com/post/x-forwarded-for-header-in-http.html

    http://www.verydoc.net/http/00004337.html

    https://lilywei739.github.io/2017/01/25/principle_for_http_https.html

    https://www.cnblogs.com/a3192048/p/12241059.html

    https://blog.csdn.net/dashenpanguge/article/details/105290116

    《HTTP 权威指南》

  • 相关阅读:
    POWERDESIGNER中显示样式设置
    DatagridView 最后编辑状态数据无法自动提交的问题
    oracle 10G以上版本 树形查询新加的几个功能
    net farmework 4安装不了 原因是 HRESULT 0xc8000222
    npoi 导出
    oracle rowtype
    fiddler https
    一次linux站点安装经验
    小米手机安装https证书报错:无法安装该证书 因为无法读取该证书文件
    日志系统
  • 原文地址:https://www.cnblogs.com/wuyepeng/p/14736557.html
Copyright © 2020-2023  润新知