High Performance Browser Networking - TCP UDP TLS

延遲

定義和標準延遲

延遲簡單地說,它是一種轉移或信息包從起點到終點,所花費的時間。html

延遲=發送延遲+傳播延遲+處理延遲+排隊延遲:前端

Propagation delay 傳播時延git

傳播時延這個概念。是指電磁信號或者光信號在傳輸介質中傳輸的時延。而在光纖或者銅線中。光信號和電磁信號的傳播速度都在20萬千米/秒以上,在傳輸介質中傳輸的是電磁信號或者光信號,而不是數據!web



Transmission delay 傳送時延
發送時延是指結點在發送數據時使數據塊從結點進入到傳輸媒體所需的時間,也就是從數據塊的第一個比特開始發送算起,到最後一個比特發送完成所需的時間。算法

發送時延又稱爲傳輸時延

Processing delay 處理時延
處理數據包的頭部。校對位錯誤, 並肯定數據包要傳輸的方向

Queuing delay 排隊時延
數據包等待處理的時間瀏覽器

總的時延是從client到server所有時延的總各。Propagation 時間是由二者之間的距離和傳播的介質(光纖或銅線)決定。緩存

還有一方面。Transmission delay 是由二者創建起來傳輸連接的傳輸速率決定的,跟二者之者的距離沒有關係。 舉例來講, 若是咱們分別在1Mb的連接和100Mb的連接,傳遞一個10Mb的文件。 前者的時間爲10秒,而100Mbps時,僅僅需花費0.1秒。

下一步。 當數據包到達一個路由器。 路由器必需檢測數據包的頭,從而決定下一個路由。 同一時候還需要對數據進行校驗, 所有的這些邏輯都是在路由器硬件上完畢。因此Processing delay是很小的, 但它也確時存在。 最後來說講Queuing delay. 當數據包從較快的傳速速率(光釺)到一個100MB的路由器。這就常過了路由器的處理速度, 那麼這個數據包就需要進入到緩存區提排隊。 這個排隊時間。就是Queuing Delay.

安全

光速與Propagation delay

光速是299, 792, 458米每秒, 但光速在介質中傳播會有能量損耗, 這僅僅是一個理論的值。經過下面圖表,可以清楚的瞭解光纖實際的速度和形成的Propagation 延時性能優化

路徑 距離 真空光速延時 光纖延時 光纖信號往返時間
New York to San Francisco 4,148 km 14 ms 21 ms 42 ms
New York to London 5,585 km 19 ms 28 ms 56 ms
New York to Sydney(悉尼) 15,993 km 53 ms 80 ms 160 ms
繞赤道一週 40,075 km 133.7 ms 200 ms 200 ms

光纖上的傳輸速度是挺快的, 但從紐約到悉尼仍是花費了160毫秒.  這也不過理論上的值(兩個城市是直接經過光纖相連),  實際上數據包會通過不一樣的路徑(悉尼到舊金山, 在到紐約等等)。經理的路徑越多,就會引入不少其它的處理延時。等待延時, 傳輸延時。終於RTT(Round-trip time)將達到 200 - 300ms.
服務器

一般100-200ms是正常的值, 假設超過了300ms, 那麼整個交互就變慢了.  可以使用Content delivery network(CDN),  將server的資料緩存在離client近期的server。 下降二者之者的距離.

構建TCP

互聯網由兩個重要的協議組成,IP 和 TCP.   IP(Internet Protocol) 提供了通訊兩方之間的路由以及尋址,它僅僅管發送數據。而不保證數據是否完速的傳送到了接收端。TCP(Transmission Control Protocal), 提供了在不可靠的通道上。創建一個抽像的可靠網絡。

TCP 提供了一個可靠的抽像網絡。

它嚮應用程序隱藏了複雜的網絡通訊細節: 重發丟失的數據。 按序發送。擁塞控制。 數據的完整性等。 當你使用TCP時。你可以保證發送和接受到的數據是同樣的,而且順序也是同樣的。 因此TCP是保證準確傳輸最佳化的協議。

TCP 並不是 HTTP惟一的傳送協議。 HTTP也可以創建在用戶數據報協議(User Datagram Protocal) 或者 UDP,  也可以選擇其餘傳送協議。 但在實際中, HTTP在互聯網的通訊都是經過 TCP。

因此理解TCP的核心執行原理,是咱們優化web性能的基礎知識。 

三次握手

所有的TCP都是從三次握手開始。 在client或者server交換隨意應用數據以前,它們必須先創建鏈接,確認數據包的序列號, 以及其餘用於鏈接的特殊變量。 由於安全緣由,序列號是從兩方中隨機挑選。

SYN

client會挑選出一個數字序列號 X, 並且發送一個SYN 數據包(包括額外的TCP 標記和選項)

SYN ACK

server接受到 syn 包, 在序列號X上加1. 並且挑選一個序列號Y,  並附上它本身的標記和選項。 並響應這個數據包

ACK

client對x, y 加1 , 併發回ACK包, 完畢握手。

圖1-1

當三次握手完畢, 應用層數據就可以在client和server之間傳送。 client可以在ACK 包發送完後立刻傳送數據包。 但server必須在接受到ACK包以後,才幹夠。

整個的啓動過程(三次握手) 。 每一個TCP鏈接都需要進行, 因此對於使用TCP的應用程序。 這個過程會很重要: 每一個新的鏈接在傳輸數據以前都會有一個響應延時。

舉一個樣例, 假設咱們的client在New York, 但server是在London,  TCP鏈接是創建在光纖上的, 三次握手將至少花費56 毫秒(client可以在第三次ACK後,立刻數據傳輸): 28ms 是一個方向的Propogation delay.

三次握手產生的延時,使得創建新的TCP鏈接是昂貴的, 這也是爲何在使用TCP時。需要對已有鏈接進行重要最大的緣由之中的一個.


Slow-Start 慢啓動

你可以經過 http://www.cnblogs.com/fll/archive/2008/06/02/1212479.html 瞭解TCP 對端到端數的可靠性, 以及流量控制, 網絡擁塞。 在來看這一段文章。

TCP的提出攻克了流量控制的問題(經過rwind, 告知client,我能處理的數據量). 但是網絡擁塞的問題出現在了。 流量控制防止了發送端(sender) 發送數據的速度超過接收者(receiver)的處理速度。 但TCP尚未考慮到不論什麼一端的網絡帶寬是否被全部佔用(發生擁塞)。 因此需要有一種機制來保證兩端之者的有一個合理的傳輸速度.

咱們看一個樣例, 若是你在家裏看一個很大的視頻(在線) 。 爲了保證你有最好的體驗,整個帶寬都會被視頻佔用。

這時你的朋友用你家的網絡下載一個軟件。 但這裏你家的網絡帶寬已經不多了,因此 video server必須調速它的數據傳送率。 不然,若是它仍是以一樣的速度傳送的話,數據僅僅會僅僅簡單的堆積在某個中間網關,並且數據包將會被丟棄。致使網絡的低效利用。


1988年, Van Jacobson 和 Michael J.Karels 提出了幾個算法,來解決這些問題: slow-start(慢起動), congestion avoidance(擁塞避免), Fast retransimit(高速重傳),  Fast recovery(高速恢復)。

很是快這四個算法成爲了TCP規範中的強制部分。 


爲了理解slow-start 在實際應用中形成的影響,咱們回到以前的樣例, 咱們的客戶位於New York.  嘗試從London的server獲取一個文件。

首先經歷三次握手, 在此其間。雙方都經過ACK包,向對方告知本身的 receive window(rwnd)的大小。  一旦後一個ACK包進入網線。咱們就可以交換應用數據。


client和server之間交換的數據大小是多少才合適呢? 這偏偏就是slow-start 被設計出來的緣由了。

一開始, server初始化每一個TCP鏈接 初始化一個 congestion window(cwnd 擁塞窗體), 並且保守的設置一個初始值 (由Linux系統指定大小).


Congestion window size(cwnd)  
在接收到還有一端返回 的acknowlledgment(ACK)以前, 發送端可以發送最大的數據。 最初。 cwnd的開始值爲 1個MSS(最大報文段,  可以經過 http://blog.csdn.net/wilsonpeng3/article/details/12869233瞭解TCP報文頭 ), 在1999年, R2581添加一以了4個MSS. 到2013年已經添加到10MSS。


cwnd 變量不會在發送端和接收端之間告知對方和交換。 因此在這樣的狀況下,它將是一個私有變量。在兩個發送端維護。

client和server都是在三次握手後,發送第一個數據包時。 初始化1MSS.

比方瀏覽器(圖1-1的第二步。 y+1, x+1 後就可以發送數據了, 那麼此時瀏覽器的cwnd 爲 1MSS, 在一個RTT時間內,收到帶ACKed的數據包後,會添加1個MSS. 可以發送兩個數據包了。)

而server要在接到收到瀏覽器的ACK包後,才幹夠發送數據, 它的cwnd 爲1MSS, 在下一次接收到client的ACKed包後,會添加1MSS.




那咱們slow-start對咱們的瀏覽器應用程序有什麼影響呢? HTTP 和很是多其餘應用程序都是執行在 TCP協議之上。  不管帶完是多少。 每一個TCP邊接必須經歷 slow-start。

咱們不能直接將合適的流量應用到每一個鏈接。

咱們都是以最小的 cwnd 開始, 在每次  RTT以後, 指數添加cwnd的大小.

方程式 2-1 表式的是, 達到指定的傳輸速度所需要的時間:


讓咱們若是下面情下:
  • client和server的速度達到 65,535 (64KB)
  • 初始cwnd: 4 MSS (RFC2581)
  • RTT(一個響應用的時間): 56ms (London to New York)

每一個新建的TCP鏈接的吞吐量都被限制爲 cwnd的大小。 實際上, 要達到64 KB的限制, 咱們將添加cwnd的大小爲45 MSS,  這需要花費244毫秒:


如圖2-4所看到的。 這裏4次請求與響應, 要經歷好幾百的延遲。才幹夠達到client與server的吞吐量, 64KB.  而在實際。server與client以前的速度以Mbps爲單位, 在慢啓動以前,這些都是速度都是無效的。



圖 2-4

爲了減少在添加擁塞空口大小,所花的時間,咱們可以減少 server與client RTT的時間。

好比, 將server佈置到離client更進的位置。 或者。咱們可以添加初始的 cwnd的大小 到 10 MSS (RFC 6928).

對於視頻以及大型文件來講, Slow-start不是特別大的問題。 但對於很是多短的和突發的http來講。 因爲它限制了帶寬吞吐量的能力(高帶寬,但使用不上).  這就會對性能形成影響。


注: slow-start restart 對於空暇的鏈接(比方http keepalive connections, 不傳送數據時), 進行重置到安全 cwnd 值。 這個機制對於 http 長鏈接形成性能影響。可以經過下面命念關閉
  • $> sysctl net.ipv4.tcp_slow_start_after_idle
  • $> sysctl -w net.ipv4.tcp_slow_start_after_idle=0

爲了瞭解三次握手和慢啓動對http請求形成的影響,咱們若是  New York的客戶 從 London的server請求一個20  KB的文件。新的TCP鏈接。如圖 2-5所看到的。

  • RTT 的時間爲 56ms
  • Client 和 Sever 之間的帶寬 5 Mbps;
  • Client 和 server 的 receive window(rwnd): 65,535 bytes (64KB)
  • 初始 cwnd : 4 MSS (4 × 1460 bytes ≈ 5.7 KB)
  • 服務器處理響應的時間: 40 ms
  • GET請求大小,小於單個 segement( 1460)

圖2-5

0 ms  Client 經過SYN包,進行TCP第一次握手

28ms  server返回一個SYN-ACK, 並且有指定 rwnd 大小

56ms  Client  發送一個對SYN-ACK所的確認包。 並指定 自已的 rwnd大小, 並立刻發送一個 HTTP GET  請求

84ms  server接受 HTTP  request, 並花 40 ms處理

124ms  server完畢,併產生一個20kb的響應, 並且發送4 TCP segments的數據(5480 bytes), 並暫停,等待client返回一個 ACK包

152ms  client接收到 4 個片斷的數據。 並確認每一段數據, 並返回一個ACKed 包。

180ms server添加cwnd的值, 併發送8 個數據段

208ms  client接收到 8個數據段。並確認每一段數據

236ms  server添加每個ACK 包的 cwnd,  併發送剩餘的數據段

264ms  client接收剩餘數據段,並返回每一個段的ACKs包

在一個新的TCP傳遞一個20KB的數據,  花費了264ms . 讓咱們對照一下,重用一樣的TCP鏈接,  並請求一樣的內容


圖2-6

0 ms client發送請求

28ms server接收到請求

68ms server處理完請求。並生成20KB的響應。但是當前的cwnd爲15 segments,  所以可以一次性發送完20KB的數據

96ms client接收到15個數據段。並ACKs  它們


一樣一樣的請求在一樣的鏈接上(除了三次握手)。  性能上提高了275%;

在這兩個樣例中, 5 Mbps的帶寬沒有對性能產生不論什麼影響,基本的影響因素是擁塞窗體大小。 


擁塞避免


要認識到一點, TCP是經過數據包丟失返饋機制來調節 網絡性能。

從慢啓動可以看到,cwnd可以很是快的增加上來(2的N次方)。從而最大程度利用網絡帶寬資源,但是cwnd不能一直這樣無限增加下去,必定需要某個限制。TCP使用了一個叫慢啓動門限(ssthresh)的變量。當cwnd超過該值後,慢啓動過程結束,進入擁塞避免階段, 或者發生了丟包現像。也會進入到擁塞避免階段.  (http://www.cnblogs.com/fll/archive/2008/06/10/1217013.html)


假設發現丟包現像。 擁塞避免算法。以爲網絡發生了擁塞:  在網絡中的某處。咱們遇到了擁塞的線路或者路由器。 它們強制性的丟棄了數據包。 在此時, 咱們需要調速 擁塞窗體的大小, 以避免丟失不少其它的包, 同一時候避免擠佔網絡。

一旦擁塞窗體被重置, 擁塞避免會採用它本身的算法添加窗體的大小。 保證包的最小丟失。 假設你之前觀察過TCP鏈接的,就知道圖表的線爲何是鋸齒形的。

TCP 經過擁塞控制和擁塞避免,調整擁塞窗體的大小, 以避免在網絡中發生丟包。



Bandwidth-Delay Product (帶寬拖延乘積)

TCP 內製的擁塞控制和擁塞避免帶來了還有一個重要的性能優化: 發生者和接收者最佳值,這取決於RTT  和 二者以前的帶寬( data rate)

咱們回顧一下以前內容。 在發送者和接收者之間傳送中的數據大小(unacknowledged),取決於 rwnd 和 cwnd 中最小的一個。

rwnd 的大小每次都會出現在ACK包中(固定), 而 cwnd 根據發送者的擁塞控制和擁塞避免。動態調整的。 

假設發生者 或 接收者 超過了最大的unacknowledged data(未確認數據), 它必須停下來,等待其餘以前發送過的包的確認信息(ACK).  那麼它需要等待多久呢? 這取決於二者之者的響應時間RTT.

Bandwidth-Delay Product

數據鏈路上帶寬與 end-to-end 之間的延時乘積。 它所表示的是。 任一時間點, 可以發送的最大 未確認(unacknowledged)的數據.

sender 或 receiver 在停下來等待以前發送的包確認信息, 就會有一段時間空隙(data gap), 在這段空隙內。發送端是不能在發送數據的。

爲了解決問題, 窗體的大小就需要調整到足夠大。 這樣服sender在接受到receiver 返回的ACK包以前,也可以繼續發送數據。 這樣就沒有gaps。

所以最優的窗體大小依賴於 Round-trip time (RTT).  當窗體比較小的時候, 你將會限制鏈接的吞吐量。

 


圖2-7 Figure 2-7. Transmission gaps due to low congestion window size

那麼流量控制窗體(rwnd) 和 擁塞控窗體(cwnd) 需要多在布呂尼 ? 計算這個值很easy, 首先, 讓咱們若是cwnd 和 rwnd中。最小的值爲 16KB.  RTT時間爲 100ms:

不管在sender 和 receiver的有效帶寬是多大, 這個TCP 鏈接不會超過 1.31 Mbps; 爲了達到更大的輸出, 咱們需要添加 最小窗體值 或者下降二者之間的RTT.
相同。咱們也可以經過 RTT 和 二者之者的有效帶寬, 計算出最佳的 window 大小, 讓咱們若是RTT 相同爲 100 ms. 但發送者有10 Mbps的有效帶寬。 並且接收者的帶寬高於100Mbps.  若是二者之者沒有網絡擁塞, 那咱們發送到client的速度爲 10Mbps;

窗體大小最少需要122.1 KB 才幹適應 10 Mbps 的數據鏈路。 但rwnd最大的值爲64KB, 除非經過其餘方法調整 - 查看 "Window Scaling (RFC 1323" on Page 18"


Head-of-Line Blocking  線頭堵塞

TCP 是在不可靠的信道上提供了一條抽像的可靠網絡。

這包含基礎包的錯誤檢察和改動, 按序發送, 重發丟失的包, 以及流量控制, 擁塞控制 和擁塞避免(保證網絡資源的最有效利用).  因此很是多應用都是使用TCP.


但TCP不是惟一可以選擇的, 有時TCP不是最好的選擇。 特別是TCP有一些特性會引入沒必要要的延遲和性能問題。 比方有序 和 可靠的數據包傳遞(有些應用並不老是需要這些特性).

爲了更好的理解這個問題。 咱們回憶一下。每個TCP 包 會攜帶一個惟一的序列號(Number)。 並且數據必須有序的傳遞到接收者那。  如圖2-8所看到的. 假設一個包在路由中丟失了, 則所有的後序的包(2,3)都必須在接收者的 TCP 緩存裏等待 丟失包(1)的重傳。由於這個工做是在TCP層。 咱們的應用程序不能看到TCP重傳或者緩存中的包隊列。 應用程序在可以訪問到這些數據以前,必須等待完整的包序列。 可以簡單點說。 應用程序嘗試從socket讀取數據會有遲時發生。

這就是 TCP head-of-line(HOL) blocking(線頭堵塞)

線頭堵塞使咱們的應用程序避免了對數據包進行又一次排序。 使得應用程序代碼easy編寫。

可是。 這會引入不肯定的延時,以等待丟失的數據包重發。

這樣的延時可以稱爲 (jjitter, http://blog.csdn.net/junllee/article/details/6110912) 。這影響到程序的性能。



圖2-8
更進一步的說。 有的應用程序甚至不需要可靠的遞送。或者有棄的遞送: 比方數據包是一個獨立的消息, 則有序遞送就全然沒有必要。 又比方,每一條消息都會覆蓋以前的傳送的消息。 那麼可靠傳送也沒有必要。丟失了可以在以後中得到。 但不幸的是TCP 不提供這些配置 - 所有的數據包都是以可靠而有序的方式傳遞數據.

應用程序執行以無序或者忽略丟包的的方式執行,但必須使用其餘的傳輸協議, 這就是UDP.

Packet Loss is OK (丟包的發生也是有優勢的)
實際上, 數據包的丟失會使TCP得到更好的性能。 丟失的包做爲一種反饋機制,TCP知道網絡擁塞。 就會調整接收者和發送者之間的發送速率。 避免形成整個網絡癱瘓。

而且, 有的應用程序可以忍受數據包丟失: audio, video , 遊戲狀態更新。

  它們都不需要可靠和有序的數據傳遞。 順便說同樣, 這也是什麼WebRTC(網頁實時通訊()是基於UDP做爲傳輸協議的緣由.
假設一個包丟失。 視頻解碼器會簡單的在視頻中插入一小段空白, 並繼續處理以後的處據包。 假設這個空隙很小。視頻解碼都不會通知使用者,這樣就不用在視頻輸出的時候。 以暫停的方式等待丟失的包。
相同的。假設咱們正在傳遞的數據是 3D遊戲中一個角色的狀態更新, 這時咱們等待的數據是用來描寫敘述 T-1 時間點的狀態。 而T時間點的數據包已經接收。那麼T-1 秒的數據包就是不需要的了。 理想的是,咱們可以接收到每一個狀態更新。 但是爲了保證遊戲的不發生延遲。 咱們可以接愛間歇性的丟包。 以保證較低的延遲.


TCP 優化

TCP 協議是一種自適應的協議,以保證公平的對待網絡的各節點,並最有效的利用各類網絡。(公平, 有效利用)。 所以, 優化TCP最好的方法是讓TCP知道當前的網絡條件, 並且根據上次和下層的協議類型和要求,調整TCP的行爲。 比方, 無線網絡,它需要不一樣的擁塞算法; 有的應用程序爲了達到最好的體驗,會本身定義QoS語義。

不一樣的應用程序有不一樣的要求, 而每一個TCP算法,也有很是多影響因子。這些都致使TCP的優化。成爲了學術和商業研究中永恆的課題。 在眼下爲前。咱們僅僅是簡單的介紹了影響到TCP 性能的一些因素。  固然另外一些其餘的因素,比方 selctive acknowledgments(SACK 選擇性確認), delayed acknowledgments (拖延性確認),  高速重發等等。 這使得每一個TCP會話都變得複雜, 難以理解, 分析, 調整。


儘管每一個TCP算法都有自已特定的細節,並繼續發展出不一樣的反饋(feedback)機制,但核心的原理依舊一樣, 這些原理致使的性能問題也沒有改變:

  • TCP  三次握手 引入的延遲  2 RTT
  • TCP slow-start 都會發生在每個新的TCP鏈接
  • TCP 流量 和 擁塞控制。 影響到所有TCP鏈接的吞吐量(帶寬)
  • TCP 吞吐量會受到cwnd(擁塞窗體)大小的影響

所以, 每個tcp 鏈接在現代化的快速網絡下,傳送數據的速率也是受限於 發送者和接受者之間的 roundtrip 時間的影響(可以看看帶寬拖延積)。或者這麼解釋, 儘管可以無限制的添加帶寬, 採用光速傳送數據,從New York 到 London的拖延仍是有28ms.  在很是多狀況下,TCP的瓶頸不是帶寬的大小。而是延遲的大小。 可以查看圖2-5.

調優server配置

首先需要調優TCP 會使用到的每一個 buffer(rwnd, cwnd)的值 和超時變量。這裏的影響TCP的因素許多。 因此最簡單有效的方法是 升級server到最新的系統。 TCP 最佳的實踐和算法都存在於最新的系統內核中。

有了最新的系統內核, 就能保存你的server配置使用下面最佳實踐:
  • 提高TCP's 的初始化擁塞窗體的大小  原書 26頁:  cwnd 在一開始假設有一個很是大的值, 它贊成TCP 在第一次RTT內傳遞不少其它的數據。

    同一時候意味着它可以加速window的增加。 特別是 在優化突發性。短鏈接中起來決定性的做用。

  • Slow-Start Restart 原書23頁 : 禁用在TCP閒置時。進行慢啓動。 這將明顯的作優化長鏈接TCP的性能。
  • Window Scaling  添加 接收窗體的大小  原書18 : 添加 rwnd 大小,達到網絡最好的吞吐量
  • TCP 高速打開 原書 16: 在某些狀況下, 贊成應用程序數據可以在初始的SYN包。一塊兒發送。 TFO是一種新的優化方式, 要求在client和server都支持。

     

除了這些, 依據你的應用程序。 你也可以調整server其餘的TCP設置。以優化快速鏈接。 內存使用 或者其餘。 但這些配置會依賴於系統平臺,應用程序, 以及硬件 -- 在此以前,你必須查閱系統文檔。

調優應用程序行爲

  • 儘可能減少要發送數據的大小
  • 咱們不能改變數據發送大小的速度, 但是可以將數據放到離client更近的地方。
  • TCP 鏈接的重用,對性能的改善很是明顯
減少沒必要要的數據量傳輸。是最佳的一個優化。  e.g : 減少沒必要要的資源 或者 經過壓縮算法將數據壓縮後傳輸。 以後。 將數據放到離客戶近期的地方。 比方使用CDN,  它會減少網絡RTT 帶來的延遲, 改善TCP性能。  最後 , 在可能的狀況下,重用TCP鏈接

性能檢測清單

下面是一個簡短的優化清單。可以用在尋常的工做中:
  •  升級你的系統內核到最新的版本號
  • 確保cwnd 的大小設置爲了 10 MSS
  • 禁用 slow-start after idle
  • 贊成窗體可伸縮
  • 消除多餘數據的傳輸
  • 壓縮傳送的數據
  • 將server部署在離客戶近期的地方。減少RTT
  • 在可能的狀況下, 重用TCP

UDP

udp 對前端沒有什麼影響,它是一種不可靠的協議, 可以經過google 瞭解udp的特性。以及NAT.  最新的採用的技術是Google 在瀏覽器提供的WebRTC. 

TLS

SSL 協議最初是由Netscape公司開發的, 保證web中的電子商務的安全性。 它經過加密技術保護客戶的私有數據。 以及安全的傳輸認證信息和信息的完整性。 爲了達到這幾個目標, SSL協議是在應用層實現, TCP的上一層就是SSL層, 以後贊成其餘的協議執行在它上面,比方HTTP, email, 即時通訊等等。


當使用了SSL 時, 第三方的僅僅能判斷出鏈接的兩方是誰。 加密協議是什麼, 以及數據傳送的頻率和大概的數據量。 但不能查看和改動不論什麼實際的數據。


圖 4-1
SSL 2.0 是第一個公佈的版本號。 但很是快被SSL3.0代替, 因爲2.0被髮生有安全漏洞。 SSL一開始是屬於網景公司, 通過IETF的努力,成爲了RFC2246 中的一個標準協議。

這就是TLS1.0, 它其實是SSL 3.0的一個升級。


加密、 認證、 完整性

TLS 會爲所有執行在它上面的應用程序提供三方面的基礎服務: 加密, 認識。 以及數據的完整性。 從技術上來講。你可以依據本身的需要,使用一種或者兩種。比方你可以使用未被驗證的安全證書, 但你知道這會致使安全問題, 在實踐中。 一個安全web應用將會使用到三種服務。


加密 Encryption
提供一種機制,使數據以密文的形式發送
Authentication
提供一種機制,數據發送者的身份。 而不是第三方發送的數據
完整性
提供一種機制。保證數據不會被篡改和僞造

爲了創建一個安全的password數據通道, 鏈接的兩端必須協商好,使用哪一種password套件來加密數據。 TLS 協議規範中定義了握手協議。用來處理處據交換, 咱們將在 "TLS Handshake"  原書 50頁 有具體講解。 握手協議使用對方的公共密鑰加密數據(非對稱加密)。 數據接收方本身的私鑰進行解密, 這樣就可以在非安全信道上共享公共密鑰。


握手協議也贊成鏈接的兩方,認證對方的身份。 當使用者在瀏覽器端。 認證機制充許客戶校驗自稱的server是誰(比方你的銀行), 而不是簡單冒充的目的名稱和IP 地址。 這樣的認證是基於創建的信任鏈(可以經過 信任鏈和認證中心。即有一個權威的頒證機構,幫你確認,這個證書所相應的銀行)。 另外, server也可以校驗客戶的身份, 比方, 一個公司代理server可以識別所有的員工。 每一個員工都有它們本身的一個惟一證書(不是CA發的。而是公司本身經過軟件生成).

現在TLS 有了加密和身份認證, TLS協議也提供了它,本身擁有的消息分幀機制, 並經過 message authentication code(MAC) 對每一條消息進行簽名。

MAC算法是一種單向加密散列函數, 它的key 是通訊兩方協商 的一個結果(session key) ,  可以查看http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html 。 每當TLS record  要發送, 就會產生一個MAC值, 並附加在消息的後面。這樣接收者,就可以計算和校驗發送過的值, 以確保消息的完整性和身份認證。 (簡單點說,密文經過MAC算法,基於session key 生成密文的校驗值。 並把這個校驗值一塊兒發送到接收端,接收端使用MAC算法和一樣的session key 對接到的信息生成校驗值。並對照是否同樣。就能保證消息的一致性)


綜述, 加密,認證,數據的完整性保證了Web的安全性。 所有的現代瀏覽器都支持多種password套件, 可以用來認證client和server身份,並且透明的完畢信息的完整性校驗和每一個record的校驗。


TLS 握手

在client和server開始效換應用數據以前, 二者必須協調一個加密通道: client和server協商好兩方使用的TLS協議版本號, 加密的方法(比方RSA公鑰加密),假設有需要。還要校對證書。 但每一步都會有新的數據包往返於client和server。 所有的TLS鏈接在啓動的時候都有這種延遲發生。



圖 4-2 TLS握手協議

0 ms TLS 執行在TCP鏈接上, 因此咱們必須先完畢TCP的三次握手, 將花費一次往返的時間 56 ms

56ms 此處TCP可以使用了, client以文本的形式,發送多個參數。 比方client需要執行的TLS協議版本號, 它支持的加密算法, 和其餘TLS  會用到的選項

84ms  server選擇TLS 版本號(根據client要求)。 並根據client支持的加密算法,肯定加密套件。

並附上本身的證書, 發回一個響應給client。 在這裏,另外一些可選項。 server也可以要求客戶商提供證書, 以及擴展TLS的參數


112ms 若是兩端可以使用協商的TLS 版本號和password套件, 並且client對server提供的證書是信任的, 客戶商這時候會生成一個新的對稱密鑰, 並使用server的公共密鑰進行加密, 並告訴server。將來的通訊以加密的方式進行。

到眼下爲此。所有交換過的數據都是以明文的方式進行, 除了新的對稱密鑰。 是使用server的公共密鑰進行了加密。


140ms server使用本身的私鑰對client發過來的 對稱密鑰進行解密, 並經過MAC確認消息的完畢性, 並使用(用解密後的對稱密鑰), 加密 "Finished" 信息,並返回給client.

168ms client以前的生成的對稱密解, 解密server返饋的信息, 並覈實MAC是否一致。 假設都是正確的。 則創建起了安全加密鏈路, 應用數據現在就可以發送。


你可以經過 http://www.ruanyifeng.com/blog/2014/02/ssl_tls.html 瞭解更具體的握手過程

新的TLS鏈接需要兩次的往返(上圖中的綠色線)。才幹完畢整個握手過程。

另外,你可以選擇一種簡單的握手, 它僅僅需一次往返。 可以查看 55頁的 」TLS Session Resumption"


協商創建一條安全的TLS 遂道是一個複雜的過程。 不少的子過程均可能會致使錯誤的發生。 但好的消息是,所有的工做都是經過瀏覽器和server完畢, 咱們僅僅需要提供和配置本身的證書。

話雖如此, 咱們的應用程序不用管TLS 遂道的創建, 但是它必須等待整個TCP, TLS 握手的完畢。 才幹夠發送數據。 假設不精心管理, 在TLS上傳遞數據, 會引入上百,上千毫秒的延時。

應用層協議協商(ALPN)

網絡的兩端但願使用本身定義的應用層協議,彼此進行通訊。

可以直接經過port進行肯定, e.g HTTP使用 80port。 TLS  使用  443port。 所有的client和server都是使用的這些公認的port。但在實際中。經過port來配匹配應用層協議是不可靠的,每一個port都需要由系統開發。 而且防火牆和其餘的中間機構僅僅贊成 80 和 443port的信息經過。


因此, 爲了可以簡單的部署本身定義的協議, 咱們必須重用80  或者 443port。 並且可以使用額外的機制協商應用程序協議。 80 port是爲HTTP保留。 HTTP規範也指出,新的協議可以執行在HTTP協議層之上。但這會加入額外的RTT 和 延遲。 並且在實際中。也是不可靠的。 可以查看   「Proxies, Intermediaries, TLS, and New Protocols on the Web」 原書50頁.

那麼剩下的解決方式就是443port, TLS執行在這個端品。 它使用端到端加密遂道。對通過的數據進行模糊處理。 因此中間機構不需要知道傳遞的是什麼類型的協議數據, 這樣贊成高速而且可靠的創建隨意的應用層協議。

可是。 使用TLS 攻克了可靠性的問題, 咱們依舊需要有一種方法。協商新的應用層協議。


咱們可以將協商新的協議(HTTPS),做爲TLS 握手的一部分:
  • client向ClientHello消息中,加入一個, 新的ProtocolNameList 字段。 這個字段包括了它所支持的應用協議列表
  • server檢查ProtocolNameList  字段。 並在返回的SeverHello 消息中包括 ProtocolName字段,包括選中的協議
server可能會返回單個的協議名稱。 假設它不支持client要求的協議。 則會選擇終止鏈接。 所以,一旦TLS握手完畢。 兩方之間的安全遂道已經創建。 同一時候client和server也協商好了要使用到的應用程序協議。 它們即可以立刻用協商的進行通訊。


ALPN 沒有經過HTTP Upgrade exchange 的方式,減少了RTT致使的延時, 但需要注意, TLS握手自身也會產生一個響應延時, 所以 , ALPN 協商並不會比 HTTP Upgrade快,僅僅是它創建的是一個加密,哥靠的協議。

Server Name Indication (SNI)

在TCP兩端創建好的TLS遂道, client僅僅需要知道server的IP地址就可以運行握手協議,但假設一臺server有多個站點, 哪個站點纔是需要創建TLS鏈接呢?

爲了解決問題。 Server Name Indication(SNI) 做爲一個擴展,被引入到TLS協議, 它贊成client在握手開始的時候,經過hostname字段,標識出它想要創建server的名稱。 web server會檢查SNI 中的 hostname. 並選擇合適的證書, 並繼續完畢握手。



但在不少老的client並不支持SNI,  比方執行在 Windows XP的瀏覽器, Android 2.2 等。

TLS Session Resumption

在所有使用安全通訊的應用程序中, 握手階段致使了額外的延遲和CPU計算, 嚴重的影響了應用程序的性能。爲了減少一樣的浪費, TLS 提供了在多個鏈接中。共用一樣的安全密鑰(生成的對稱密鑰)的能力。


Session Indentifiers  

會話標識重用是在SSL 2.0版本號被引入, 它充許server建立併發送 32 字節的會話標識,做爲 」ServerHello" 消息的一部份。

在server內部,它需要爲每一個client緩存 session ID 以及TLS鏈接參數 (key,  加密算法)。 相同。 client也需要保存sessionID 信息, 並且在下次的TLS請求中, 在ClientHello 消息中帶上sessionID.  當server收到sessionID時, 就知道client依舊保存了以前加密套件和 從上次握手所得到的 對稱密鑰。如圖 4-3所看到的。 一個簡短的握手過程。

假設兩方沒有從緩存在找到以前的信息,那麼將會產生一個新的 session ID.


圖4-3 簡短的握手過程


利用會話標識。讓咱們減少了一個RTT時間。 以及計算開銷。


在實際工做中, 不少web應用程序, 爲了獲取資源 會以並行的方式向一樣的server創建鏈接, 就必須使用 會話重用,以減少延遲和計算開銷。 現代化的瀏覽器會有意的等待第一個TLS鏈接完畢,在打開一條新的鏈接。



可是,在實際的工做中。使用server建立和保存session  標識符 具備侷限性。 比方天天都會有成千上萬的鏈接需要保存到緩存,這會致使緩存被使用完成, 有的站點是採用多個server,假設共享這些session也是一個問題。

(session  保存在server會帶來哪些實際問題,可以查看 http://nil-zhang.iteye.com/blog/1279214)


Session Tickets

爲了避免在server緩存 TLS 的 sesion., 有了 "Session Ticket" (RFC5077) 機制, 它不需要server爲每一個已鏈接的client保存 session 狀態。

取代的是, 假設client代表。它支持 Session Tickets, 在 TLS  握手的最後。 server會包括進一個新的  Session Ticket record. 這個記錄包括了所有會話數據, 並且會以server才知道的安全密解加密。

會話船票會保存在client。 在以後的鏈接中,會以  SessionTick 擴展,包括進ClientHello 信息中。 這樣所有的信息就僅保存在client。 而且 ticket 依舊是安全的, 因爲它是使用server才知道的密鑰加密的。



session indentifiers 和 session ticket 機制可以分別稱爲  會話緩存 和 無狀態恢復。 無狀態恢復的最大改進是不需要server端緩存。 client僅僅需在新的鏈接中提供 session ticket, 除非ticket 已通過期。


信息鏈 和 CA

咱們如何才幹知道,在創建加密遂道是咱們信任的一方,而不是一個攻擊者, 因此身份證認證在TLS 鏈接中是不可切割的一部分。爲了知道如何驗證兩方的身份, 咱們舉了在 Alice 和 Bob  之間的一個樣例:

  • Alice 和 Bob 都有本身的公共密鑰和私有密鑰
  • 兩方都會隱藏本身的私有密鑰
  • Alice 向 Bob 分享本身的公共密鑰, Bob 也向 Alice 分享了本身的公共密鑰
  • Alice 向 Bob 發了一條消息,這條信息是用她本身的私有密鑰加密的
  • Bob 使用 Alice's 的公共密鑰來校對信息提供者的簽名, 這條消息是由Alice發送過來,而不是其餘人

信任是交換數據以前的關鍵, 公鑰加密算法,贊成咱們使用信息發送者的公共密鑰, 確認被簽名的信息是正確人發送過來的。

  但這樣的信任全然是基於 Alice 和 Bob 相互認識的基礎上。才交換的公共密鑰。


下一步, Alice 從Clarlie那裏接收到一條信息, Alice 沒有見過Clarlie,   但Clarlie 聲稱它是 Bob's 的朋友。

實際上, Clarlie 爲了證實本身是Bob的朋友。 Clarlie 要求Bob 對本身的公開密鑰 使用 Bob 的私有密鑰進行籤時。 並以消息的附件,一塊兒發送給Alice.  如圖4-4.  在這樣的狀況下, Alice 首先確認 Clarlie的公共密鑰中Bob的簽名。 她已經有了Bob 的公開密鑰, 因此知道Clarlie 的公開密鑰的確是由 Bob簽過的。Alice 接受了這條消息。 並使用消息中的Clarlie 公開密鑰, 確證發送條消息的人確實是Clarlie.

圖4-4


這樣咱們就創建了一條信息鏈: Alice 信任 Bob, Bob 信任 Charlie. 並且經過傳遞信任, Alice 肯定信息 Charlie.

互聯網和你的瀏覽器之間的認證也是採用一樣的處理。 瀏覽器可以經過下面幾種方式,加入信任
  •  手動指定證書: 每一個瀏覽器和操做系統都提供了一種機制,你可以手動的導入你信息的證書
  • CA認證中心的證書
  • 瀏覽器和操做系統自帶的證書

在實際中,你不可能存放所有站點的證書。所以最通用的解決方法是使用CAs來幫咱們進行校驗.  如圖 4-5.  站點會讓認證中心對他的名字和公鑰進行簽名,並將這個簽名發送到瀏覽器。假設瀏覽器的CAs的根文件夾下。有認證中心的公開密鑰,就能確認這個站點是真實的。



圖4-5
每一個瀏覽器都贊成你檢查你安全鏈接中的信任鏈, 你可以當擊URL 的中鎖, 如圖 4-6

圖 4-6

Certificate Revocation

不重要。忽略

TLS Record Protocol

不一樣於IP 或者 TCP協議, 在TLS會話中的所有數據交換都是由TSL Record協議負責。 該協議需要負責識別不一樣類型的消息(握手信息,警告,數據), 並校對每一個信息的完整性。

圖 4-8 TLS record  結構

傳遞應用程序的數據的流程例如如下:

  • Record  協議得到應用程序的數據
  • 對接收到的數據進行分塊: 最大爲2的14次 bytes 或者16KB一個記錄
  • 應用數據可以選擇壓縮
  • Message autentication code(MAC) 或 HMAC。 加入消息的校驗碼
  • 使用協商好的加密算法,對數據進行加密

完畢以上步聚, 被加密的數據就會向下傳入TCP層,進行傳輸。 在接收端, 則是相反的過程。

這個過程看起來很是easy。但需要注間幾個地方:

  • TLS record 最大爲16KB
  • 每一個記錄會包括 5-byte header,   一個MAC (SSLv3, TLS1.0, TLS1.1 爲 20 bytes, TLS 1.2 需要32字節), 假設使用了塊分組password, 還需要把password加上。

  • 爲了解密和校對record, 整個record 必須有效。

爲你的應用程序挑選出最佳的record 的大小。對性能的優化很是重要,小的records 會致使很是大的開銷,  然而大的records 會被TCP又一次進行組裝

優化TLS

TLS的優化主要是配置你的server,比方TLS records 的大小。 內存緩衝區, 證書的大小, 是否支持簡短的握手等等, 經過對這些參數的正確配置,會明顯改善用戶體驗,減小操做開銷。

計算開銷

創建和維護一個加密的通道。在鏈接的兩端都會引入額外的計算開銷, 特別是在TLS握手時使用公共密鑰加密對稱密鑰。 當鏈接創建以後,可以使用對稱password加密所有的TLS records.

咱們以前說過, 使用公鑰加密 對照 對稱密鑰加密 會致使很是大的計算開銷。 早先的站點一般需要額外的硬件來完畢 SSl計算。

但現在的硬件的性能有很是大的提高。都能直接完畢
但對於TLS Session 的恢復。 仍是可以下降使用公鑰加密。 除低計算的開銷。

提早終止

 不管是新建仍是重用一個鏈接,都會有延遲的發生。 對於優化來講。 鏈接的創建是一個重要的區域。

  咱們看看一個TLS鏈接有哪些: TCP 三次握手, 以後是TLS握手, 添加兩個RTT時間(新建)。

或者一個RTT(重用)。

在最壞的狀況下,數據交換以前, TCP 和 TLS鏈接的設置過程就將花費三個 RTT.  以咱們以前New York到London的樣例, 一個RTT 時間爲56ms, 那麼新建一個TLS 將花費168ms, 而重用一個將花費112ms.  

因爲TLS是執行在TCP之上。因此對TCP的優化。也適用於這裏。 經過CDN將server位置到離client近期的地方,減少RTT的值。

CDN不只可以優化靜態資源。你也可以應用動態內容上,提早終止TLS 會話。 如圖 4-9所看到的,在本地代理server上,創建與client的鏈接(加速完畢握手),代理server與原始server之間創建一個長久(沒有握手。僅僅負責數據傳送),加密的鏈接。

這樣所有的請求和響應都是從原server獲取

圖4-9 提早終止client鏈接

要作到這一點很是easy,很是多CDN都提供這種服務。 你也喜歡冒險。也可以以最小的花費搭建本身的基礎設施: 在全球各地的數據中心部署雲server,並配置代理server,將請求轉發到你的原始server中。

並可以增長基於地理位置的DNS 負載均衡。


Session Caching and Stateless Resumption

瞭解概念就能夠

TLS Record Size

經過TLS傳輸的應用數據,都是使用 record 協議。 查看圖 4-8.   每一個記錄都將加入20-40不等字節大小的頭部信息。 MAC 信息,以及其餘的信息。

假設一個記錄恰好可以裝入一個 TCP數據包, 咱們還需要加入IP 和 TCP的信息, 比方 IP會有20字節的頭部信息, TCP也會有20字節的頭部信息。

終於, 每一個記錄大概會加入60-100字節的頭部信息。

電路中一個標準的最大傳輸單位(MTU) 大小是1500 字節。 數據包的結構就佔領了 6% 的大小(overhead,在計算機網絡的幀結構中,除了實用數據之外,還有很是多控制信息,這些控制信息用來保證通訊的完畢。

這些控制信息被稱做系統開銷).


假設是一個很是好的記錄,那麼就不是 6%的系統開銷。仍是更高的比例。

可是,簡單的添加記錄的值,使它達到最大讚成傳遞的16KB, 這也不是一個很是好的方法。 假設一個record 很是大,它會被分裝進多個TCP 數據包。 則TLS的還有一端必須等待所有的TCP包到達以後才幹夠對數據進行解碼(如圖4-10)。

 假設某些TCP數據包丟失, 還需要重傳, 形成額外的延遲。

在實際中, 這樣的延遲對於瀏覽器形成很是大的延遲,  還不如對數據一個字節一個字節的傳遞, 這樣還可能會更快。



圖 4-10. WireShark capture of 11,211-byte TLS record split over 8 TCP segments

假設records 過小,添加系統開銷, 傳到還有一頭的實用數據就越少。

對應的,傳送可用數據越少意味着傳送的數據要不少其它的數據包。

這還意味着完畢傳輸數據需要額外的時間。

假設是大的records 又會引起延遲的發生。   這裏很是難找到一個「正確」 的 record大小。   還好。瀏覽器會本身主動將web應用程序的值,設置爲TCP MSS的大小,即records 值爲 一個MSS(1460 bytes). 這種個TCP數據包傳遞一個record。 這樣一個record就可以分配到多個TCP 數中包其中。

經過下面的方式。咱們能計算出一個最佳的record:

  • 電路中傳輸的數據包, 會包括IPv4 20bytes 地址, 假設是IPv6會是40 bytes
  • TCP 會有20 bytes頭部信息
  • 40 個字節的TCP 可選信息, 比方 timestamps, SACKs

MTU通用的大小爲1500 bytes,  那麼在IPv4中 TLS record 大小就是1420 (1500- IP 20 - TCP 20 - TCP Option 40), 而對於IPv6,這個大小爲1400.   爲了兼容將來。 因此最佳的值爲1400.

但咱們在server的應用層上是不能配置 TLS  record 的值。

而是需要經過server級別的配置,詳細方法,需要查看server系統文檔。



假設你的server需要處理大量的TLS 鏈接,則需要爲每個鏈接分配最小的內存使用。

OpenSSL 通常會爲每個鏈接分配50KB 的內存, 但正如調整record 大小同樣,不妨查看OpenSSL 的文檔。 Google的server能常將OpenSSL的值設置爲5KB.

TLS 壓縮

TLS 內部經過 record協議。 支持對傳輸的數據進行無損壓縮: 壓縮的算法是經過握手協議。兩方協商好的。 壓縮會發生在對每條record 加密以前。

但一般,你要禁止server的壓TLS 壓縮功能, 有下面幾個緣由:

  • 在2012年。 黑客利用過TLS 壓縮得到加密認證的cookie,  這就贊成黑客運行會劫持, 這樣的功能方法叫做"CRIME"
  • 傳輸級別上的TLS 不知道要壓縮的內容是什麼,可能會壓縮已經壓縮過的數據,比方,圖片,視頻

兩次的壓縮,會浪費server和client的CPU,  而且致使很是嚴重的安全問題, 儘管很是多的瀏覽器禁用了TLS 壓縮。但爲了更好的保護你的客戶。 你需要明白的禁止server壓縮.

認證鏈長度

瀏覽器驗證證書的過程是: 從站點的證書開始, 在遍歷父證書。 直到信任的根文件夾( 證書是分級的,全球。 國家, 省份).  所以。第一條優化的原則是,在server上配置所有的中級證書。 假設忘記了, 那麼不少瀏覽器依舊可以工做,但是它會暫停。 等待, 並向中間證書的server。 獲取中間證書。 而後繼續驗證。直至根文件夾信任的證書。 這過程當中會有新的DNS 查詢, TCP鏈接。 和 HTTP GET請求。 會有數百毫秒的握手延遲。

可是瀏覽器怎麼知道怎樣獲取中間證書的呢? 每一個子證書一般都包括了父證書的URL

相反的, 你必須在你的信任鏈裏不會包括不是必需的證書, 或者通俗點說, 你應該下降信任鏈的大小。

回顧一下。 server在TLS 握手期間。 會向client發送證書, 很是有可能證書的發送是在發生在新TCP鏈接的slow-start 階段。

假設證書鏈的大小超過了TCP 初始 cwnd 的大小, 則僅僅能先發送一部份(TCP cwnd大小)。 等待client的 ACK後,在發送剩下的部分, 這就會致使多個RTT時間。

如圖 4-11

圖4-11 WireShack 軟件截圖 TLS 證書鏈的大小爲 5, 323-byte

圖4-11中, 證書鏈超過了5KB的大小,它超過了一些的老的server的擁塞窗體的大小。這就在握手階段引入了其餘RTT的大小。

有一個解決方式是添加初始的擁塞窗體的大小。 可以查看 "Increasing TCP's Initial Congestion Window "  原書 26頁。

另外。 你也可以下降證書的大小:

  • 減少認證的層級, 理想的是僅僅包括你本身的證書和中間人證書,第三個證書就是根文件夾證書(瀏覽器已經信任, 不需要在發送)
  • 不要發送root 證書, 假設你的瀏覽器連root證書都沒有,那麼你發了,它也會不信任它
  • 將證書鏈的大小減少到  2 KB 或 者3KB, 儘管爲瀏覽器提供所有必要的證書,可以避免瀏覽器本身發起新的鏈接,獲取中間代理人證書。從而引起沒必要要的RTT.  但這可能也就發生一次,而過大的證書會致使每一次新的TLS鏈接,有會有額外的RTT, 這樣的性能損失更大

OCSP 裝訂

針對OCSP的優化, 每一個新的TLS鏈接都需要瀏覽器檢測認證鏈。但有一個步聚咱們不能忘記, 那就是瀏覽器還需要檢測證書是否被呆銷,在這裏,瀏覽器有兩個方法,一個是下載CRL文件並且緩存。 另外一個就是經過OCSP進行實時的檢測, 從認證中心的server獲取響應。 並使用認證中心的公開對響應進行加密。

以證明證書是否吊銷。因此咱們可以在server 發送一個請求到認證中心的響應,並且把它包括(裝訂)到認識鏈中(部分瀏覽器可以識別)。 這樣咱們本身的server就可以緩存被簽名過的OCSP響應。可以節省多個client的額外請求。 但這裏也需要注意一些問題:

  • OCSP的大小從400到 4000不等。 裝訂到你的認證鏈中, 可能會超過你TCP擁塞窗體的大小
  • 僅僅能裝訂一個OCSP響應。 那麼對於中間(發證中心)的證書,瀏覽器仍是會發送OCSP請求。

近期。你需要在配置server。贊成有OCSP裝訂的功能。 好的消息是,主流的server。 比方Nginx, Apache, IIS是有這個功能的。 你可以查看這些server的文檔說明。


HTTP Strict Transport Security (HSTS)

HTTP Strict Transport Security  是一個安全策略機制, 它贊成server經過簡單的HTTP 頭, 比方 Strict-Transport-Security: max-age = 3153600. 向順從的瀏覽器(知道這類http頭的瀏覽器) 聲明訪問規則。

這條規則表示,client必須強制運行下面規則:

  • 所有到初始請求,都必須使用HTTPS
  • 所有不安全的鏈接 和client請求,在請求發送以前。 應該本身主動轉化爲 HTTPS
  • 假設發生認識錯誤, 顯示錯誤信息, 並且不一樣意繞過吃警告
  • max-age 代表 HSTS規則的有效期, 單位爲秒

HSTS 不只可以將原始鏈接轉變爲 HTTPS,  還可以保護應程序。 在性能上, 可以減少從 HTTP-to-HTTS的跳轉(301 或者302)。

 在2013年時。 支持HSTS的瀏覽器有 Firefox 4+, Chrome 4+, Opera 12+  以及Android 版的Chrome 和 Firefox. 最新的瞭解可以查看 caniuse.com/stricttransportsecurity.

TLS 性能檢測清單

  • 優化TCP, 可以查看 "Optimizing for TCP" 在原書第32
  • 升級TLS 庫到最新的版本號
  • 贊成並配置 TLS session 的緩存 和 無狀態重用
  • 監測你的TLS session 緩存命中率, 並調整對應的配置
  • 使用CDN。 在client近期的寺方, 提早終止 TLS  sesion, 減小往返致使的延遲
  • 配置TLS record 的大小。以適應單個TCP段的大小, 1400 bytes
  • 確保你的認證不會超過初始化擁塞窗體的大小, 低於 2 or 3KB
  • 從認證鏈中刪除不是必需的證書, 減少認證鏈的深度
  • 禁用server的TLS 壓縮
  • 配置你的server,以支持SNI,  域名識別
  • 配置OCSP 裝訂功能
  • 加入  HTTP Strict Transport Security header

測試和檢驗

最後, 檢驗和測試你的配置。 你可以使用在線的服務, 比方 Qualys SSL Server Test 掃描你公開的server的通用配置 和安全缺陷。  另外,你也可以使用 openssl 命令, 它將幫助你檢驗整個握手過程和本地的server配置

$> openssl s_client -state -CAfile startssl.ca.crt -connect igvita.com:443
CONNECTED(00000003)
SSL_connect:before/connect initialization
SSL_connect:SSLv2/v3 write client hello A
SSL_connect:SSLv3 read server hello A
depth=2 /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing
/CN=StartCom Certification Authority
verify return:1
depth=1 /C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing
/CN=StartCom Class 1 Primary Intermediate Server CA
verify return:1
depth=0 /description=ABjQuqt3nPv7ebEG/C=US
/CN=www.igvita.com/emailAddress=ilya@igvita.com
verify return:1
SSL_connect:SSLv3 read server certificate A
SSL_connect:SSLv3 read server done A
SSL_connect:SSLv3 write client key exchange A
SSL_connect:SSLv3 write change cipher spec A
SSL_connect:SSLv3 write finished A
SSL_connect:SSLv3 flush data
SSL_connect:SSLv3 read finished A
---
Certificate chain
0 s:/description=ABjQuqt3nPv7ebEG/C=US
/CN=www.igvita.com/emailAddress=ilya@igvita.com
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing
/CN=StartCom Class 1 Primary Intermediate Server CA
1 s:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing
/CN=StartCom Class 1 Primary Intermediate Server CA
i:/C=IL/O=StartCom Ltd./OU=Secure Digital Certificate Signing
/CN=StartCom Certification Authority
---
Server certificate
-----BEGIN CERTIFICATE-----
... snip ...
---
No client certificate CA names sent
---
SSL handshake has read 3571 bytes and written 444 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : RC4-SHA
Session-ID: 269349C84A4702EFA7 ...
Session-ID-ctx:
Master-Key: 1F5F5F33D50BE6228A ...
Key-Arg : None
Start Time: 1354037095
Timeout : 300 (sec)
Verify return code: 0 (ok)

  1.  client完畢 認證鏈的驗證
  2.  接收到認證鏈(兩個證書)
  3. 接收到的認證鏈的大小
  4.  有狀態的TLS session 標識符

在此之樣例中, 咱們經過TLS的默認port(443) 鏈接到 igvita.com , 並運行TLS 握手。 由於 s_client 不清楚root證書,咱們需要手動將 StartSSL Certifiecate Authority 導入到根文件夾(很重要的一步) , 不然 s_client 會看到一個校驗失敗的錯誤日誌。

檢測證書鏈的過程當中,咱們看到server發送了兩個證書。 總的大小爲3,571 bytes, 這是進軍 3 至 4 分割 (TCP 老server初始擁塞窗口的大小 4 分割) 。終於, 咱們檢測磋商 SSL 變量 - 最新的協議。 加密演算法 , 對稱密鑰 - 咱們也能夠看到server發送一斤session 馬克。

相關文章
相關標籤/搜索