協議連接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進行校驗