Giter Site home page Giter Site logo

tlstunnel's Introduction

tlstunnel

工作原理

使用 TLS 加密 HTTP 代理

HTTP 代理在企业中有着应泛的应用。但 HTTP 代理信令是明文传输的,非常不利于商业秘密和个人隐私的保护。本文介绍一种使用 TLS 技术对 HTTP 实行加密保护的方法。

对于明文 HTTP 请求,代理通信的流程如下:

Agent Proxy Site | | | | <1> tcp dial to proxy:8080 | | |<--------------------------->| | | <2> GET / HTTP/1.1 | | | Host: baidu.com | <3> tcp dial to baidu.com:80 | |---------------------------->|<---------------------------->| | | <4> GET / HTTP/1.1 | | | Host: baidu.com | | |----------------------------->| | | <5> HTTP/1.1 200 OK | | <4> HTTP/1.1 200 OK |<-----------------------------| |<----------------------------| | | | | <1> 客户端同代理服务器建立 TCP 连接 <2> 客户端将 HTTP 请求发送给代理服务器 <3> 代理服务器解析 HTTP 请求,获取目标服务器地址并建立 TCP 连接 <4> 代理服务器将客户端 HTTP 请求发送给目标服务器 <5> 目标服器将响应内容发送给代理服务器 <6> 代理服务器将目标服务器的响应内容发送给客户端 如是你要访问 HTTPS 站点,则需遵循另外一套流程:

Agent Proxy Site | | | | <1> tcp dial to proxy:8080 | | |<--------------------------->| | | <2> CONNECT baidu.com:443 | | |---------------------------->| <3> tcp dial to baidu.com:443| | <4> HTTP/1.1 200 OK |<---------------------------->| |<----------------------------| | | | | | https data | https data | |<--------------------------->|<---------------------------->| | | | <1> 客户端同代理服务器建立 TCP 连接 <2> 客户端向发送给代理服务器发送 CONNECT 请求 <3> 代理服务器解析 HTTP 请求,获取目标服务器地址并建立 TCP 连接 <4> 代理服务器向客户端发送 Connection Established 响应(图中标为 OK) 接下来代理服务器会不断将客户端发来数据转发给目标服务器,并把目标服务器的发来的数据转发给客户端。

那为什么 HTTP 请求和 HTTPS 请求的代理通信流程不一样呢?因为对于明文的 HTTP 请求,代理服务器可以通过解析请求内容获取目标服务器的域名和端口,进而发起 TCP 连接。可对于 HTTPS 请求,客户端在发送 HTTP 请求之前要发送 TLS 握手数据。Proxy 收到 TLS 握手数据后是不知道要把这些数据转发给哪台服务器的。所以,协议要求客户端要先发送一个 CONNECT 请求来告诉代理服务器目标服务器的域名和端口。

大家注意,对于 HTTP 请求,Agent 和 Proxy 之间的通信中全明文的;对于 HTTPS 请求,Agent 的 CONNECT 请求也是通过明文发送给 Proxy 的。因为是明文协议,所以存在安全风险。

我们知道,HTTPS 就是使用 TLS 对明文 HTTP 协议进行的加密的。那我们可不可以使用 TLS 对 Agent 和 Proxy 之间的通信进行加密呢?理论上是可行的,但现实中却不可行,因为改造现有系统来支持 TLS 版 HTTP 代理的工作量太大了。那就没有其他办法了吗?有,那就是引入二级代理,其代理通信流程如下:

Agent Local Proxy Remote Proxy Site | | | | | <1> tcp dial to proxy:8080 | | | |<--------------------------->| | | | <2> GET / HTTP/1.1 | | | | Host: baidu.com | | | |---------------------------->| <3> tls handshake | | | |<--------------------------->| | | ================================= | | | <4> CONNECT baidu.com:80 | | | |---------------------------->| | | | | <5> tcp dial to baidu.com:80 | | | <6> HTTP/1.1 200 OK |<---------------------------->| | |<----------------------------| | | | <7> GET / HTTP/1.1 | | | | Host: baidu.com | <8> GET / HTTP/1.1 | | |---------------------------->| Host: baidu.com | | | |----------------------------->| | | | <9> HTTP/1.1 200 OK | | | <10> HTTP/1.1 200 OK |<-----------------------------| | |<----------------------------| | | ================================= | | <11> HTTP/1.1 200 OK | | | |<----------------------------| | | | | | | 对于 HTTPS 请求,通信流程则稍微简单一些:

Agent Local Proxy Remote Proxy Site | | | | | <1> tcp dial to proxy:8080 | | | |<--------------------------->| | | | <2> CONNECT baidu.com:443 | | | |---------------------------->| <3> tls handshake | | | |<--------------------------->| | | ================================= | | | <4> CONNECT baidu.com:443 | | | |---------------------------->| | | | | <5> tcp dial to baidu.com:443| | | <6> HTTP/1.1 200 OK |<---------------------------->| | <7> HTTP/1.1 200 OK |<----------------------------| | |<----------------------------| | | | https data | https data | https data | |<--------------------------->|<--------------------------->|<---------------------------->| | ================================= | | | | | 这里的核心是引入 Local Proxy 和 Remote Proxy 两台代理服务器。对 Agent 来说,Local Proxy 就是一台普通的代理服务器,一般部署在本机。Local Proxy 收到代理请求后不会直接连接目标服务器,而是先跟 Remote Proxy 建立 TLS 连接,并使用 CONNECT 请求将目标服务器的信息发送给 Remote Proxy,Remote Proxy 收到 CONNECT 请求后执行代理连辑。Local Proxy 既是 Agent 的 Proxy,又是 Remote Proxy 的 Agent,具有双重人格。Local Proxy 和 Remote Proxy 之间的通信使用 TLS 加密,保证不被恶意用户窃取。

最后,TLS 加密 HTTP 代理的缺点。

第一,TLS 通信需要 SSL 证书。SSL 证书一般只签发给域名,所以还需要注册一个域名。好在我们可以去 https://www.freenom.com 注册一年期免费域名,然后使用 https://letsencrypt.org/ 签发三月期证书,所以这个问题不大。

第二,就是 TLS 握手效率的问题。TLS v1.2 握手流程确实很繁琐,至少要四次通信才能完成握手,延迟的确很大。但是,TLS v1.3 对握手流程做了大幅优化,只需两次通信即可,大大缩短了握手延迟。所以,只要能使用 TLS v1.3,这个问题也不大。

tlstunnel's People

Contributors

taoso avatar luckypoem avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.