协议连接html
本协议描述了如何使用TLS来对Internet上的HTTP进行安全加固。linux
2.1. Connection Initiation(连接初始化)安全
HTTP client同时也做为TLS client(后续统一称为client)。在创建连接的时候,由client初始化TCP连接,并发出TLS ClientHello报文来开始TLS协商。当TLS协商完成后,client能够初始化首个HTTP请求,全部HTTP数据都被标记为TLS"application data"。session
2.2. Connection Closure(连接结束)并发
TLS提供了安全关闭连接的方式,当client/server接收到一个有效的closure alert(rfc5246 7.2.1章节)报文时,认为该连接上不会接收到后续数据,TLS在结束连接前必须交换closure alert。但在实现中,当一端发送了closure alert以后,它可能会直接关闭连接而无需等待对端回复closure alert(此时上层应用应该接收了全部须要的数据),这种实现称之为"incomplete close",该实现可能用于重用tls session的场景。app
RFC2246中描述了一种场景,在接受到首个closure alert以前接收到了(premature close ,如底层tcp断链)断链请求,此时不能重用该session。这种状况下须要处理HTTP数据可能被截断的问题。tcp
2.2.1. Client Behavior(客户端行为)ide
因为HTTP经过执行关闭链接操做来表示数据传输的正常终止,所以当client遇到premature close的状况时,必须将其视为一种错误行为并假设已经接收到的数据可能会被截断。在一些状况下,HTTP协议容许client判断是否发生了数据截断,当接收到一个完整的数据回复时,client可能会"[be] strict when sending and tolerant when receiving" [RFC1958]容忍这些错误。以下两种情景须要特别注意:日志
(如上两种状况用于处理截断攻击,若是此时http首部不存在Content-Length,该报文是不可信的,且若是报文的Content-Length和实际数据不匹配也是不可信的。但接收到一个有效的报文,即Content-Length与实际数据匹配时,作特殊处理,见下文)
当client遇到premature close时,若是此时client接收到了Content-Length的数据,则认为是连接正常完成。
client在检测到incomplete close时应该进行优雅恢复,可能会重用TLS sessionorm
Client在结束连接前必须发送closure alert报文
Client在没有准备好接受更多数据时,可能会选择关闭连接而不等待server回复closure alert,这样会使得server处于incomplete close状态
2.2.2. Server Behavior(服务端行为)
RFC 2616 容许HTTP client在任意时间关闭连接,并要求server进行优雅恢复。server应该应对client形成的incomplete close,sever也应该重用这种状况下关闭的TLS session。
在使用非长链接的状况下,server端一般会经过关闭连接来发送数据传输结束信号。当HTTP使用Content-Length时,client端可能已经发送closure alert并断开连接。
server在关闭连接前必须尝试跟client交互closure alerts。server可能在发送closure alerts以后关闭连接,这样会使得client处于incomplete close状态
2.3. Port Number(端口号)
创建连接时,HTTP server指望接收的首数据为Request-Line(rfc2616),TLS server(即http/TLS server)指望接收的首数据为ClientHello。所以HTTP和TLS须要容许在不一样的端口上以区分不一样的协议类型。当HTTP/TLS容许在TCP/IP之上,默认端口为443。TLS假定仅容许在面向连接的数据流之上。
2.4. URI Format(URI 格式)
HTTPS/TLS经过"https"来与"http"协议进行区分
3. Endpoint Identification
3.1. Server Identity
一般HTTP/TLS 请求与URI关联,所以client须要知道server的hostname,而且将其与server Certificate消息中的server identity进行校验,以防止中间人攻击。
若是client拥有与server identity相关的额外信息,有可能忽略对hostname的校验(如客户端链接的机器的地址和hostname是动态的,但client知道server 提供的证书),在这种状况下,会尽量减小可接受证书的范围,以防止中间人攻击。特殊场景下,client可能会忽略server的identity,但必须意识到这种行为可能致使的攻击。
证书中若是subjectAltName(SAN)出现了dNSName,必须将该处定义的内容做为identity,不然使用Common Name字段做为identity。Certification Authorities鼓励使用dNSName。
若是证书中出现多种类型的identity(如多个dNSName名称,匹配任意一个便可),可能会包含通配符"*",表示能够匹配任意单个域名或域名段。如*.a.com匹配foo.a.com,但不匹配bar.foo.a.com。f*.com匹配foo.com,但不匹配bar.com(即通配符域名证书只匹配同级别的通配域名,不能跨级匹配)
一些场景下,URI使用IP而非hostname,这种状况下,证书中必须出现iPAddress subjectAltName且必须匹配URI中的IP。
若是hostname不匹配证书的identity,client端必须通知用户(是否继续链接)或结束连接(给出错误证书提示)。automated client必须记录该错误日志到审计日志(audit log --如linux的审计日志功能)并关闭链接
在不少状况下,URI的源不可信,此时须要检查server提供的证书的有效性,防止中间人攻击。
3.2. Client Identity
一般server并不了解client的identity,所以没法对client进行校验。反之,则应该对client进行校验