繼上一篇《如何打造一個全滿分網站》以後,這一次咱們來談談如何打造一個在安全方面也能打滿分的網站。由於對於一個網站來說,僅有功能是不夠的,還須要考慮性能,僅有性能也不夠,還須要考慮安全。html
因爲網站安全方面涉及因素不少,例如如何防止跨域攻擊
,如何防止SQL注入
等等軟件開發方面的安全考慮,若是真想作到全面防禦的話,還須要有更專業的機構進行漏洞檢測,咱們這裏談的只是最基本的在傳輸層面的https
安全。nginx
跟上次的思路同樣,開始動手以前,咱們仍是先來熟悉一下評測工具,此次介紹的主要是3個網站,前2個網站相似,基本上你若是在一個網站上拿不到高分,在另外一個網站也是同樣;第3個網站略有不一樣。git
又拍雲
爲了推廣本身的HTTPS
服務,提供了一個免費檢測工具。就拿咱們熟悉的segmentfault
來講吧:github
很不幸,在安全方面徹底不合格。又拍雲
提供的方案有兩個:算法
又拍雲HTTPS
服務;若是本身優化的話,其實最關鍵的核心問題是一點:服務器易受到CVE-2016-2107漏洞攻擊,降級爲F
。只要解決了這個問題,評分就能上升不少。segmentfault
另一個工具是Qualys SSL Lab提供的免費服務,和又拍雲
相似,可是不推銷產品。仍是拿segmentfault.com
來作一下實驗:跨域
一樣是F
,不合格。根本緣由仍是在這個CVE-2016-2107
。瀏覽器
這個網站主要是用來檢測網站的response header是否安全的,咱們仍是拿segmentfault.com來測試一下:安全
得分也不高,有不少問題。服務器
那麼,到底什麼是CVE-2016-2107
呢?Cloudflare
給出了詳細解釋,不過若是你不是安全方面的專家,基本上如讀天書不知所云。
粗略地來說,CVE-2016-2107
是OpenSSL 1.0
的一個漏洞,是2016
年剛剛發現的編號爲2107
號漏洞。安全系統的漏洞就像人的衣服破了一個洞同樣,對付漏洞的手段無非就是兩個:要否則打個補丁接着穿,要否則換件新的。OpenSSL
官方給出的解決方案是把OpenSSL
升級到1.0.2h
就好了。可是怎麼升級是一個問題,若是你用yum update
升的話根本也升不上去,何況就算升上去了,也於事無補,由於你的nginx
軟件包裏用的繼續仍是舊版本的OpenSSL
,只有用正確的參數從新編譯nginx
才能解決這個問題。關於如何編譯nginx
,能夠參考個人《免費給你的網站加上藍色小閃電》的後半部分。
但據個人實際測試發現,即便把OpenSSL
升級到1.0.2h
也沒法解決此問題,爲此直接把OpenSSL
升級到了最新的1.1.0g
,但形成的問題是nginx
又不兼容了,爲此還須要把nginx
也升級到最新版本1.13.6
。通過這樣的升級後,你的網站穿上了新衣服,這個漏洞就算堵住了。
nginx
的相關編譯參數以下:
--prefix=/usr/local/nginx --with-http_ssl_module --with-openssl=/root/src/openssl-1.1.0g --user=nginx --group=nginx --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_geoip_module=dynamic --with-threads --with-stream --with-stream_ssl_module --with-http_slice_module --with-mail --with-mail_ssl_module --with-file-aio --with-http_v2_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic'
按照這個方法,還順帶解決了http/2
的傳輸問題,詳見《免費給你的網站加上藍色小閃電》一文。
解決完了CVE-2016-2107
漏洞,咱們來看一看證書,彷佛和別人的不太同樣:
那麼什麼是RSA
,什麼又是橢圓曲線
呢?簡單來講,RSA
是利用大數因數分解的困難性來增長黑客破解的難度。好比你問小明:15
等於幾乘以幾?他能夠很快答出3x5
,若是你問他:51
等於幾乘以幾?他可能就要掏出計算器來算一算,才能告訴你等於17x3
。若是再問:10,497,479
等於幾乘以幾?恐怕他拿着計算器也算不出來,正確答案是3229x3251
,而實際上咱們真正用於RSA
的兩個質數還要遠大於這個數字,因此因數分解的困難性是保證RSA
安全的重要前提。
然而,2015
年的時候,號稱有一種算法已經能夠破譯RSA,因而安全專家們又提出了ECC(Elliptic Curve Cryptography)
,中文叫做「橢圓曲線加密
」算法。橢圓
咱們都知道,但橢圓曲線
是個什麼東西呢?
這是一個橢圓
:
下面這兩個都是橢圓曲線
:
長的根本就不像好吧,那爲何又要叫橢圓曲線
呢?簡單來講,橢圓曲線這個名稱的來源只是和橢圓周長的計算有關,從圖形上看它們沒有任何關係。
那好吧,這麼一條曲線怎麼加密呢?
加密的公式很簡單,就如上圖所示:P+Q=R
,假設R
就是咱們的公鑰,若是隻給你一個R
,讓你反推出P
和Q
來,就像給你一個大數,讓你對它進行因數分解同樣困難,這就構成了ECC
加密算法的安全保障。
聽上去好高大上,那麼我該如何得到一張橢圓曲線加密算法
的證書呢?
花錢能辦了的事那都不是事,重要的是咱們能夠免費得到!你要知道,之前一張RSA
證書一年的費用是5000
元,每一年還要續費,這構成了不少商業公司盈利的重要來源,其中包括Symantec
賽門鐵克。
當你吃飯吃的很舒服的時候,市場就會出來攪局者。感謝開源軟件精神,Letsencrypt
砸掉了不少安全公司的飯碗。我在《letsencrypt在nginx下的配置》一文中曾經講過如何配置Letsencrypt
,後來又寫過《CentOS 6.5下利用Docker使用Letsencrypt》,可是如今有更好的方法:acme.sh,你只須要安裝好acme.sh
:
curl https://get.acme.sh | sh
而後執行:
cd .acme.sh ./acme.sh --issue -w /home/wwwroot/example.com -d example.com --keylength ec-256
就能夠獲得一張免費的橢圓曲線安全證書
了。注意上面命令結尾這個ec-256
,ec
是否是讓你想起了什麼呢?對的,這就是咱們提到的橢圓曲線
(elliptic curve
)。
免費的證書有了,安裝到你的nginx
裏看一下吧,證書籤名算法瞬間變成了橢圓曲線
!是否是馬上變得高大上了呢?重要的是還免費哦!
升級完了橢圓曲線還不夠,接下來咱們再來看看CAA(Certification Authority Authorization)
,中文翻譯爲受權機構認證
。什麼是受權
?什麼是機構
?什麼又是認證
?
簡單來講,你作了一個網站,爲了安全起見,爲了須要向別人證實你就是你,你須要一張網站的身份證,那麼誰有權頒發這個證件呢?在中國,只有公安局有權發身份證,那麼這個有權發證件,而且獲得全部人承認的機構,就叫受權機構
。可是互聯網的世界比較亂,受權機構不少,萬一要是有一個你不知道的機構,也給別人發了一張你的名字的身份證怎麼辦?因此爲了杜絕這個隱患,你做爲網站的全部者,你能夠規定:只有這個受權機構頒發的證書,纔是有效的證書,其它機構頒發的證書一概無效,這個就叫「受權機構認證
」,如下簡稱CAA
。
CAA
是須要運行在DNS
服務器之上的,可是目前國內的幾乎全部DNS
服務提供商沒有一家提供這個服務,CarterLi兄的這篇文章《給你的站點添加 DNS CAA 保護》裏提到了如何給本身的網站添加CAA
,能夠考慮把你的DNS
搬家到能提供CAA
服務的廠家去作一下。
HSTS(HTTP Strict Transport Security)
,中文翻譯爲HTTP嚴格傳輸安全
,就是讓瀏覽器強制使用HTTPS
與網站進行通訊,以減小會話劫持風險,給你的網站安全再加一道鎖。
給網站添加HSTS
相對比較容易,只要在header
里加一句
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload";
就好了。
比TLS 1.2
再上一個臺階,但目前還處於測試階段,OpenSSL 1.1.1
會支持,但目前尚未正式發表,因此暫時能夠先不添加。你要想裝也能夠,這裏提供詳細的安裝步驟。
Content Security Policy的主要做用是讓你的網站只執行限定範圍內的Javascript腳本,CSS以及圖片,因此咱們能夠在nginx裏做以下限制:
add_header Content-Security-Policy "script-src 'self'";
更多的關於如何設置CSP的內容能夠參考阮一峯的《Content Security Policy入門教程》
X-Frame-Options的做用是禁止別的網站iframe你的網站,在nginx裏添加如下配置:
add_header X-Frame-Options "SAMEORIGIN";
X-XSS-Protection的做用是防止跨站腳本攻擊,在nginx裏添加如下配置:
add_header X-XSS-Protection "1; mode=block";
X-Content-Type-Options的做用是禁止瀏覽器對你的網頁內容進行MIME類型嗅探,而必須以你規定的方式解析網頁,在nginx裏添加如下配置:
add_header X-Content-Type-Options "nosniff";
以上全部方案都實施以後,咱們再來看一下網站安全評分:
Certificate
拿到了滿分,下面幾項沒有拿到滿分,在Protocol Support
這一項裏,主要是因爲沒有對一些老版本的瀏覽器例如IE8
,Java 6
以及Android 2
作兼容,這個問題不大,咱們就先不解決了,其它兩項Key Exchange
和Cipher Strength
應該是和咱們使用的Letsencrypt
有關,目前還不清楚具體緣由,能夠再研究。
不管如何,咱們把一個安全得分只有F
的網站,經過各類方法優化到了得分爲A+
,是否是小有成就感呢?你也來試一試吧!