HTTP【袋里】是如何对待HTTPS的?
HTTPS已经成为今天web内容安全访问的事实性标准,本质上是要求client和server两端之间建立一个安全管道,然后之间进行加密的数据传输。然而,HTTP【袋里】作为client和server之间的一个中间人,显然破坏了HTTPS要求的端到端的原则,那么HTTP【袋里】究竟是如何支持HTTPS传输的呢?
HTTPS
HTTPS其实就是HTTP协议,只不过在传输HTTP Request和Response之前,先在client和server间建立了一个TLS连接,然后才传输加密后的Request和Response。从具体过程来看,首先是client向server发起TCP连接请求,经三步握手建连成功后,client再发起TLS握手请求。经过client hello、server hello、server certificate、client key exchange和server key exchange几步后,TLS连接成功,这样双方就已经协商好了密钥,之后就可以进行安全传输了。
HTTP【袋里】
当有【袋里】存在于client和server间时,对于普通HTTP协议,client会先把Request交给【袋里】,然后【袋里】再转发给server,server给【袋里】返回Response后,【袋里】最终把Response交给client。多数【袋里】在转发Request或是Response之前,都会对其进行一定的修改,这就要求【袋里】能读懂HTTP消息格式。尤其是有些【袋里】还具有缓存功能,甚至可以直接满足Request而不必惊动server。CDN节点其实就可以被视为一种HTTP【袋里】。
HTTP【袋里】支持HTTPS
现在我们考虑让HTTP【袋里】支持HTTPS的情况。如果我们要让【袋里】理解HTTP消息格式,那就只能采用(client到proxy的安全管道+proxy到server的安全管道)这种前后端分离的机制。且不说我们是否无条件相信【袋里】,假设【袋里】没有问题,我们还是会碰到很大的麻烦:证书问题。在建立TLS连接的过程中,server需要向client返回其证书,只有其证书是有效的,client才会信任这个连接。当然,无效的证书并不一定会阻断连接,一些浏览器都会让用户选择是否继续。因为【袋里】和server未必属于同一管理实体,所以他们之间未必共享证书和密钥。这样一来,要想让client信任和它直接连接的【袋里】,就只能设置一种证书分发机制。当前的CDN提供商在HTTPS的支持上就碰到了很多问题。关于这些问题,具体可参见清华大学发表的一篇论文:When HTTPS meets CDN。
上面的问题都是由于要求【袋里】理解HTTP消息而言的。如果对于HTTPS,【袋里】可以不理解HTTP消息,那么就很简单了:让【袋里】只做为一个透明的传输层中继即可。现有的一些【袋里】软件也都是这么做的。client首先发送一个HTTP CONNECT请求给【袋里】,【袋里】看到这个请求后和server建立一个连接。然后【袋里】会把其和client的连接与和server的连接绑定起来,从一个连接接收到的数据会直接转发给另一个连接,根本不做任何额外的操作。这就是我们一般看到的HTTP【袋里】如何对待HTTPS的方式了。
[via]
评论