您好,登錄后才能下訂單哦!
怎么進行Server Name Indication的理論分析,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
SNI (Server Name Indication)是用來改善服務器與客戶端 SSL (Secure Socket Layer)和 TLS (Transport Layer Security) 的一個擴展。主要解決一臺服務器只能使用一個證書(一個域名)的缺點,隨著服務器對虛擬主機的支持,一個服務器上可以為多個域名提供服務,因此SNI必須得到支持才能滿足需求。
SSL以及TLS(SSL的升級版)為客戶端與服務器端進行安全連接提供了條件。但是,由于當時技術限制,SSL初期的設計順應經典的公鑰基礎設施 PKI(Public Key Infrastructure)設計,PKI 認為一個服務器只為一個域名提供服務,從而一個服務器上也就只能使用一個證書。這樣客戶端在發送請求的時候,利用DNS域名解析,只要向解析到的IP地址(服務器地址)發送請求,然后服務器將自身唯一的證書返回回來,交給客戶端驗證,驗證通過,則繼續進行后續通信。然后通過協商好的加密通道,獲得所需要的內容。這意味著服務器可以在 SSL 的啟動動階段發送或提交證書,因為它知道它在為哪個特定的域名服務。
隨著HTTP 服務器開啟虛擬主機支持后,每個服務器通過相同的IP地址可以為很多域名提供服務。這種為虛擬主機提供通信安全的簡單途徑,卻經常導致使用了錯誤的數字證書,因為服務器端無法知道客戶端到底請求的是哪個域名下的服務,從而導致瀏覽器對用戶發出警告。
不幸的是,當設置了 SSL加密,服務器在讀取HTTP請求里面的域名之前已經向客戶端提交了證書,也就是已經為默認域提供了服務。但是,一個服務器可能為上千個域名提供服務,不可能將所有證書都發送給客戶端,讓客戶端一一驗證,找到與請求域名對應的證書。SNI的設計目的是為了讓服務器根據請求來決定為哪個域服務,這個信息通常從HTTP請求頭獲得。
熟悉SSL/TLS握手過程的都知道,主要經過以下幾個過程:
基于RSA握手和密鑰交換的客戶端驗證服務器為示例詳解TLS/SSL握手過程。
客戶端發起請求,以明文傳輸請求信息,包含版本信息,加密套件候選列表,壓縮算法候選列表,隨機數,擴展字段等信息。
SSL/STL版本支持的最高TSL協議版本version,從低到高依次 SSLv2 SSLv3 TLSv1 TLSv1.1 TLSv1.2,當前基本不再使用低于 TLSv1 的版本;
客戶端支持的加密套件 cipher suites 列表, 每個加密套件對應前面 TLS 原理中的四個功能的組合:認證算法 Au (身份驗證)、密鑰交換算法 KeyExchange(密鑰協商)、對稱加密算法 Enc (信息加密)和信息摘要 Mac(完整性校驗);
支持的壓縮算法 compression methods 列表,用于后續的信息壓縮傳輸;
隨機數 random_C,用于后續的密鑰的生成;
擴展字段 extensions,支持協議與算法的相關參數以及其它輔助信息等,常見的 SNI 就屬于擴展字段,后續單獨討論該字段作用。
server_hello, 服務端返回協商的信息結果,包括選擇使用的協議版本 version,選擇的加密套件 cipher suite,選擇的壓縮算法 compression method、隨機數 random_S 等,其中隨機數用于后續的密鑰協商;
server_certificates, 服務器端配置對應的證書鏈,用于身份驗證與密鑰交換;
server_hello_done,通知客戶端 server_hello 信息發送結束;
客戶端驗證證書的合法性,如果驗證通過才會進行后續通信,否則根據錯誤情況不同做出提示和操作,合法性驗證包括如下:
證書鏈的可信性 trusted certificate path,方法如前文所述;
證書是否吊銷 revocation,有兩類方式離線 CRL 與在線 OCSP,不同的客戶端行為會不同;
有效期 expiry date,證書是否在有效時間范圍;
域名 domain,核查證書域名是否與當前的訪問域名匹配,匹配規則后續分析;
client_key_exchange,合法性驗證通過之后,客戶端計算產生隨機數字 Pre-master,并用證書公鑰加密,發送給服務器;
此時客戶端已經獲取全部的計算協商密鑰需要的信息:兩個明文隨機數 random_C 和 random_S 與自己計算產生的 Pre-master,計算得到協商密鑰;
enc_key=Fuc(random_C, random_S, Pre-Master)
change_cipher_spec,客戶端通知服務器后續的通信都采用協商的通信密鑰和加密算法進行加密通信;
encrypted_handshake_message,結合之前所有通信參數的 hash 值與其它相關信息生成一段數據,采用協商密鑰 session secret 與算法進行加密,然后發送給服務器用于數據與握手驗證;
服務器用私鑰解密加密的 Pre-master 數據,基于之前交換的兩個明文隨機數 random_C 和 random_S,計算得到協商密鑰:enc_key=Fuc(random_C, random_S, Pre-Master);
計算之前所有接收信息的 hash 值,然后解密客戶端發送的 encrypted_handshake_message,驗證數據和密鑰正確性;
change_cipher_spec, 驗證通過之后,服務器同樣發送 change_cipher_spec 以告知客戶端后續的通信都采用協商的密鑰與算法進行加密通信;
encrypted_handshake_message, 服務器也結合所有當前的通信參數信息生成一段數據并采用協商密鑰 session secret 與算法加密并發送到客戶端;
客戶端計算所有接收信息的 hash 值,并采用協商密鑰解密 encrypted_handshake_message,驗證服務器發送的數據和密鑰,驗證通過則握手完成;
開始使用協商密鑰與算法進行加密通信。
由以上過程可以知道,沒有SNI的情況下,服務器無法預知客戶端到底請求的是哪一個域名的服務。
SNI的TLS擴展通過發送虛擬域的名字做為TSL協商的一部分修正了這個問題,在Client Hello階段,通過SNI擴展,將域名信息提前告訴服務器,服務器根據域名取得對應的證書返回給客戶端已完成校驗過程。
Linux中主要的網絡交互工具,curl 7.18.1+ & openssl 0.9.8j+ 可以支持SNI,CentOS6.5及以下都是curl 7.15 不支持SNI,curl 7.21.3 又支持了–resolve 參數,可以直接定位到IP地址進行訪問,對于一個域名有多個部署節點的服務來說,這個參數可以定向的訪問某個設備。基本語法為:
Example:
curl -k -I --resolve www.example.com:80:192.0.2.1 https://www.example.com/index.html
使用curl7.15 (不支持SNI)抓包結果:
可以看到,使用curl7.15抓包得到的數據無SNI擴展,而是用curl7.43抓包得到的數據,包含SNI擴展,其中包含host信息。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。