HTTPS之SNI介紹與Nginx多網域名稱支援

2021-10-05 00:14:56 字數 1802 閱讀 9174

一、介紹

早期的sslv2根據經典的公鑰基礎設施pki(public key infrastructure)設計,它預設認為:一台伺服器(或者說乙個ip)只會提供乙個服務,所以在ssl握手時,伺服器端可以確信客戶端申請的是哪張證書。

但是讓人萬萬沒有想到的是,虛擬主機大力發展起來了,這就造成了乙個ip會對應多個網域名稱的情況。解決辦法有一些,例如申請泛網域名稱證書,對所有*.yourdomain.com的網域名稱都可以認證,但如果你還有乙個yourdomain.net的網域名稱,那就不行了。

在http協議中,請求的網域名稱作為主機頭(host)放在http header中,所以伺服器端知道應該把請求引向哪個網域名稱,但是早期的ssl做不到這一點,因為在ssl握手的過程中,根本不會有host的資訊,所以伺服器端通常返回的是配置中的第乙個可用證書。因而一些較老的環境,可能會產生多網域名稱分別配好了證書,但返回的始終是同乙個。

既然問題的原因是在ssl握手時缺少主機頭資訊,那麼補上就是了。

sni(server name indication)定義在rfc 4366,是一項用於改善ssl/tls的技術,在sslv3/tlsv1中被啟用。它允許客戶端在發起ssl握手請求時(具體說來,是客戶端發出ssl請求中的clienthello階段),就提交請求的host資訊,使得伺服器能夠切換到正確的域並返回相應的證書。

要使用sni,需要客戶端和伺服器端同時滿足條件,幸好對於現代瀏覽器來說,大部分都支援sslv3/tlsv1,所以都可以享受sni帶來的便利。

二、例項

公司網域名稱更變,同時又要新舊網域名稱同時執行。 那麼對於https的網域名稱在同乙個ip上如何同時存在多個虛擬主機呢?檢視了下nginx手冊,有這麼一段內容,如下:

如果在同乙個ip上配置多個https主機,會出現乙個很普遍的問題:

server 

server

server 

server

那麼,在同乙個ip上,如何配置多個https主機呢?

nginx支援tls協議的sni擴充套件(server name indication,簡單地說這個擴充套件使得在同乙個ip上可以以不同的證書serv不同的網域名稱)。不過,sni擴充套件還必須有客戶端的支援,另外本地的openssl必須支援它。

如果啟用了ssl支援,nginx便會自動識別openssl並啟用sni。是否啟用sni支援,是在編譯時由當時的 ssl.h 決定的(ssl_ctrl_set_tl***t_hostname),如果編譯時使用的openssl庫支援sni,則目標系統的openssl庫只要支援它就可以正常使用sni了。

如果nginx的tls sni support 是disabled。

啟用方法如下:

需要重新編譯nginx並啟用tls。步驟如下:

檢視是否啟用:

# /usr/local/nginx/sbin/nginx -v

tls sni support enabled

這樣就可以在 同乙個ip上配置多個https主機了。

例項如下:

server  

server

這樣訪問每個虛擬主機都正常。

HTTPS與SNI擴充套件,乙個IP多個證書

在搭建支援https的前端 伺服器時候,通常會遇到讓人頭痛的證書問題。根據https的工作原理,瀏覽器在訪問乙個https站點時,先與伺服器建立ssl連線,建立連線的第一步就是請求伺服器的證書。而伺服器在傳送證書的時候,是不知道瀏覽器訪問的是哪個網域名稱的,所以不能根據不同網域名稱傳送不同的證書。用...

php之curl實現http與https請求的方法

常規curl請求 url curl curl init curl setopt curl,curlopt url,url curl setopt curl,curlopt header,1 curl setopt curl,curlopt returntransfer,1 data curl exe...

php之curl實現http與https請求的方法

通常來說,php的curl函式組可以幫助我們把機器偽裝 的行為來抓取 下面來分享兩個例子,乙個是訪問http網頁,乙個訪問https網頁,一起來看一下。每次要使用curl的時候,總要查一堆資料。現在將常用的幾句儲存下來,省的每次都去谷歌。常規curl請求 url c ur l cu rlin it ...