Apache SSL + SNI 一個IP,多個SSL證書

Apache SSL + SNI 一個IP,多個SSL證書

OpenSSL_logo

這是一周血和淚換來的心得分享..
工作背景:CentOS、Apache2(自編及內建都測試過)
OpenSSL is not built with support for TLS extensions

普通的Apache+mod_ssl+openssl 即可完成網站的SSL加密作業。
但如果主機內有虛擬主機,安裝第二張SSL證書時,會發現怎樣裝都是錯的,主機無法識別第二張以後的證書!
這是因為OpenSSL預設的認證方式是IP-BASE,一個IP就一個證書。

想要解決這個方式為有更新OpenSSL 到0.9.8J 以後的版本,有支援SNI模式(Server Name Indication) 白話文就是用網址來識別証書。

介紹
早期的 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 帶來的便利。

重點
簡單的介紹完畢,這邊我直接白話文講。
Q1.如何讓Apache進行HTTPS加密作業?
A1:安裝openssl並且啟用mod_ssl (網路上教學一堆)
Q2.主機內有很多虛擬網站,每個網站都想要有SSL認證,但怎麼裝都失敗,點解?
A2.因為你主機沒有啟用openssl的SNI功能

好啦,看到這邊就是知道,只裝完openssl和mod_ssl是不夠的,還要啟用SNI的功能才可以讓主機支援多個SSL!
一般CentOS5.X內建的openssl版本大概在0.9.8e,但很抱歉,最少要到0.9.8J 以後的版本才有SNI。

所以步驟如下
1.更新Openssl至0.9.8j以後或最新
2.啟用SSL虛擬網站,在httpd-ssl.conf 設定NameVirtualHost
3.在httpd-ssl.conf SSLStrictSNIVHostCheck off ←這段要自己加

基本上這樣就完工前置作業了,剩下比照一般SSL網站新增即可!

慢著… 有這麼簡單的話,我還需要一周的血和淚測試嗎?當然沒有,因為你八成會遇到下列一個問題!
Q3.yum update openssl 只到0.9.8e 如何手動更新到最新?
Q4.就算openssl更新到最新了,apache也設定完了,重新啟動apache時出現「OpenSSL is not built with support for TLS extensions」 一樣GG?

這兩個問題是相對關係的,openssl沒有更新到最新的話,設定完apache會出現Q4的問題,就算更新到最新如果依然出現Q4的問題就表示opensll更新不確實。
若是自編的Apache則請在更新完OPENSSL後再重新編譯一次Apache

手動更新OpenSSL教學 (這邊是精華,一周換來心得,你看到這邊文章真的賺到,網路上無解)
0.先用yum 安裝內建的openssl
1.去openssl官網下載最新的壓縮檔然後解壓縮,進入該目錄
2.執行「./config –prefix=/usr –openssldir=/usr/local/openssl enable-tlsext shared」 請一字不漏包含符號的執行
3.接著就 make install
4.完成安裝查看opensll版本 openssl version 這時應該就出現最新版的版本號了!

好啦,如果你是用內建的apache,到這邊已經完工,電腦重開後應該就OK,但如果你是自編的apache,這時在編譯apache時需要增加額外參數,參考如下
–enable-ssl –with-ssl=/usr/local/openssl
然後PHP也要重新編譯讓他支援openssl,編譯參數如下「 –with-openssl」
到這邊才算正式完工!

最後記得防火牆打開443啊!!
藍色部分就是我試了一周後試出來的心得,非常珍貴………
為了紀念我那一周的大腦細胞,決定寫下這篇文章
—————————————————————

This week in exchange for the blood and tears of experience to share ..
Working Background: CentOS, Apache2 (built-in self and are tested)
OpenSSL is not built with support for TLS extensions

Common Apache + mod_ssl + openssl to complete the job site SSL encryption.
But if there is a host on a virtual host, when you install the second SSL certificate, you will find what is wrong means, the host does not recognize the second or subsequent certificate!
This is because the OpenSSL default authentication method is IP-BASE, a IP on a certificate.

Want to solve this way has updated OpenSSL to 0.9.8J later, there is support SNI mode (Server Name Indication) vernacular is to use the URL to identify the certificate.

Introduction
According to the classical early SSLv2 Public Key Infrastructure PKI (Public Key Infrastructure) design, it defaults to that: a server (or an IP) will only provide a service, so the SSL handshake, the server can be sure that the client application which certificates.
But people never imagined that web hosting vigorously developed, which resulted in a situation corresponding to a plurality of IP will domain names. Some solutions, such as pan-domain certificate application, all * .yourdomain.com domain can be authenticated, but if you have a yourdomain.net domain, it is not.
In the HTTP protocol, the request of the domain name as the host header (Host) on the HTTP Header, so the server knows which domain should be directed to the request, but early SSL can not do this, because the SSL handshake process, Host will not have the information, so the server-side configuration is usually returned in the first available certificate. Thus some older environment, may produce multi-domain certificates are a good job, but the return is always the same.
Since the cause of the problem is the lack of host header information when SSL handshake, then fill it wants.
SNI (Server Name Indication, meaning “Server Name Indication”) is defined in RFC 4366, is an improvement for SSL / TLS technology is enabled in SSLv3 / TLSv1 in. It allows a client to initiate SSL handshake request (specifically, the client sends SSL requests ClientHello stage), Host submitted the requested information so that the server can switch to the correct field and returns the corresponding certificates.
To use the SNI, requires the client and the server at the same time to meet the conditions, but fortunately for modern browsers, most support SSLv3 / TLSv1, so you can enjoy the convenience brought by SNI.

Emphasis
Simple introductions, here I speak directly to the vernacular.
Q1. How to make Apache for HTTPS encryption work?
A1: openssl installed and enabled mod_ssl (teaching a bunch on the web)
Q2. There are many virtual hosts sites, each would like to have an SSL certificate, but how loaded fail, Why?
A2. Because you have not enabled the openssl SNI host function

Well, see here is to know, only Bahrain openssl and mod_ssl is not enough, but also to enable SNI functions can allow the host to support multiple SSL!
General CentOS5.X probably built openssl version 0.9.8e, but unfortunately, at least to have a later version to 0.9.8J SNI.

Therefore, the following steps
1. Update Openssl to 0.9.8j or later date
2. Enable SSL virtual website, httpd-ssl.conf set NameVirtualHost
3. httpd-ssl.conf SSLStrictSNIVHostCheck off ← This add it myself

This basically completed the pre-work, and the rest can be added cf. general SSL site!

Wait … there are so simple, I still need a week to test blood and tears? Of course not, because you’ll probably experience one problem!
Q3.yum update openssl 0.9.8e only how to update to the latest manual?
Q4. Even if the latest update to the openssl, apache also set finished, there ‘OpenSSL is not built with support for TLS extensions “as GG when you restart apache?

These two issues are relatively relations, openssl is not updated to the latest case, the set will be complete apache Q4 problems, even if the latest update to the problems still arise Q4, says opensll update untrue.
If the self-made Apache please recompile Apache again after the update finished OPENSSL

Manually update the OpenSSL teaching (here is the essence of a week in exchange for experience, here you see the article really earn, no solution on the web)
0. The first use yum install built-openssl
1. go openssl official website to download the latest zip file and unzip into the directory
2. Run “./config -prefix = / usr -openssldir = / usr / local / openssl enable-tlsext shared” Please execute verbatim contain symbols
3. then make install
4. Complete the installation view opensll version openssl version should then appear on the latest version of the version number!

Well, if you are using the built-in apache, to the side has been completed, the computer should be re-opened after it OK, but if you are self-compiled apache, then compile apache needed additional parameters, refer to the following
“-enable-Ssl -with-ssl = / usr / local / openssl”
Then recompile PHP should let him support openssl, compiled the following parameters “-with-openssl”
To be considered formally completed here!

Finally, remember to turn on the firewall 443 ah !!
Blue part is I tried out a week after the trial experience, very precious ………
To commemorate the week of brain cells I decided to write this article