本文向你們展示如何在nginx的web服務器上設置更強的SSL。我們是通過使SSL無效來減弱CRIME攻擊的這種方法實現。不使用在協議中易受攻擊的SSLv3以及以下版本並且我們會設置一個更強的密碼套件為了在可能的情況下能夠實現Forward Secrecy,同時我們還啟用HSTS和HPKP。這樣我們就有了一個更強、不過時的SSL配置並且我們在Qually Labs SSL 測試中得到了A等級。
TL:DR:Copy-pastable strong cipherssuites for NGINX, Apache and Lighttpd: https://cipherli.st
這個說明是在Digital Ocean VPS是測試過的。如果你喜歡這個說明指到並且支持我的網站,通過下面的鏈接預定一個Digital Ocean VPS。
https://www.digitalocean.com/
這個說明是在21世紀2014年的1月份下頒布的更嚴格的要求(早就是這樣了,如果你你按照這個標准,就能得到A等級)下工作的。
This tutorial is also available for Apache
This tutorial is also available for Lighttpd
This tutorial is also available for FreeBSD, NetBSD and OpenBSD over at the BSD Now podcast: http://www.bsdnow.tv/tutorials/nginx
通過下面鏈接你能獲得有關主題更多信息:
BEAST Attack
CRIME Attack
FREAK Attack
Heartbleed
Perfect Forward Secrecy
Dealing with RC4 and BEAST
我們在nginx的設置文檔中如下編輯
/etc/nginx/sited-enabled/yoursite.com (On Ubuntu/Debian)或者在
/etc/nginx/conf.d/nginx.conf (On RHEL/CentOS).
對於整個說明文檔,你需要編輯服務器配置的服務器那塊和443端口(SSL配置)。在說明文檔的最後,你會發現實現了樣例的配置。
確保在編輯之前做了備份!
新版本的浏覽器客戶端可以緩解BEASE攻擊。建議禁用所有的TLS 1.0密碼並且只是用RC4。然而,[RC4有一個不斷增加的列表來防止攻擊],(http://www.isg.rhul.ac.uk/tls/)其中的很多都將理論和現實交叉在一起。而且,這就是為什麼NSA已經破解了RC4,他們所謂的“重大的突破”。
禁用RC4有幾個結果。一、使用差勁兒浏覽器的用戶將使用3DES來代替。3-DES比RC4更安全。但是就意味著更加昂貴。你的服務器會因為這樣 的用戶開銷更大。二、RC4可以緩解BEAST攻擊。因此,禁用RC4使TLS 1用戶容易受到攻擊,通過移動他們AES-CBC(通常的服務器端的BEAST“修復”是優先考慮高於一切的RC4)。我很確信,在BEAST上RC4上 的缺陷明顯大於風險。確實,客戶端的緩解(chrome和火狐都提供)BEAST已不再是個問題。但對於增長RC4的風險:隨著時間的推移更多的密碼分析 將很表面化。
FREAK是在密碼專家小組在INRIA, Microsoft Research and IMDEA所發現的一種中間人攻擊。FREAK就是“Factoring RSA-EXPORT Keys .”。這種攻擊可以追溯到90世紀90年代,也就是在美國政府禁止出售加密軟件到海外的時候,除非輸出的密碼套件中加密密鑰的長度不超過512位。
被證明是一些先進的TLS客戶端-包括蘋果的SecureTransport和OpenSSL-有一個Bug在裡面。這個Bug造成了它們接受了RSA密鑰的輸出等級甚至當客戶端都不要求RSA的密鑰輸出等級。這個Bug造成的影響還是相當嚴重的:假如客戶端是易受攻擊的並且服務器支持輸出RSA,它允許第三人通過一個活躍的攻擊者來減弱連接的質量進行攻擊。
這裡是兩部分服務器必須接受的“RSA輸出等級”攻擊。
MITM攻擊過成如下:
在客戶端的Hello消息中,它請求一個標准的“RSA”密碼套件。
MITM攻擊者改變這個消息為了得到“RSA的輸出”.
服務器返回一個512位的RSA輸出密鑰,並用它的永久密鑰簽名。
由於OpenSSL和SecureTransport存有bug,客戶端就接受了這個弱密鑰。
攻擊者分析RSA模塊為了恢復正在通信時RSA的解密密鑰。
當客戶端把加密的“預備主密鑰”發送給服務器時,攻擊者現在可以解密它從而得到TLS的“主密鑰”。
從現在起,攻擊者就可以看到明文了,並且可以注入任何他想的東西。
Hearbleed是一個在2014年四月OpenSSL密碼庫裡被發現的安全漏洞,它被廣泛用在運輸層(TLS)協議的實施中。Heartbleed可 能被使用不管是否使用了一個易受攻擊的OpenSSL,比如說在一個服務器或者客戶端使用。它是在DTLS心跳擴展(RFC6520)由不合適的輸入確認 (因為沒有邊界檢查)所造成,因此這個漏洞的名字為“心跳”.這個漏洞被劃為一個重讀的緩沖區,更多超出允許的數據被讀出。
哪些版本的OpenSSL被Heartbleed影響?
不同版本的情況:
OpenSSL 1.0.1 到 1.0.1f (包括) 受攻擊。
OpenSSL 1.0.1g不受攻擊。
OpenSSL 1.0.0的分支不受攻擊。
OpenSSL 0.9.8 的分支不受攻擊。
OpenSSL在2011年12月發現這個漏洞而且在2012年3月14日發布OpenSSL1.0.1之前一直沒有采取措施。2014年4月7號發布的OpenSSL1.0.1g修復了這個漏洞。
通過更新OpenSSL就可以免受這個漏洞帶來的攻擊。
通常來說,犯罪攻擊使用 SSL 壓縮來施展它的魔法。SSL 壓縮在 nginx1.1.6+/1.0.9+ 中默認是關閉的(如果使用 openssl 1.0.0+).
如果你正在使用 nginx 或者 OpenSSL 其他早期版本,並且你的發行版並沒有回遷此選項,那麼你需要重新編譯不支持 ZLIB 的 OpenSSL。這將禁止使用DEFLATE壓縮方法來使用 OpenSSL。如果你這樣做,那麼你仍然可以使用常規的HTML DEFLATE壓縮。
SSL v2 並不安全,因此我們需要禁用它。我們也可以禁用 SSL v3,當 TLS 1.0 遭受一個降級攻擊時,可以允許一個攻擊者強迫使用 SSL v3 來連接,因此禁用“向前保密”。
再次編輯此配置文件:
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
SSLv3允許利用“貴賓犬 POODLE”漏洞,這是禁用它的一個主要原因。Google已經提議一種叫TLSFALLBACKSCSV的SSL/TLS的拓展,旨在防止強制SSL降級。以下是升級後自動啟用的OpenSSL版本:
OpenSSL 1.0.1 有 TLSFALLBACKSCSV 在 1.0.1j 及更高的版本.
OpenSSL 1.0.0 有 TLSFALLBACKSCSV 在 1.0.0o 及更高的版本.
OpenSSL 0.9.8 有 TLSFALLBACKSCSV 在 0.9.8zc 及更高的版本.
更多的信息請參閱NGINX文檔
這意味著當私有密鑰被洩露不能用來解密SSL流量記錄。
密碼套件提供 Perfect Forward Secrecy 暫時使用 Diffie-Hellman 密鑰交換的形式。他們的缺點是開銷大,這可以通過使用橢圓曲線的變異的改進.
我建議以下兩個密碼套件,後者來自 Mozilla 基金會。
推薦的密碼套件:
ssl_ciphers 'AES128+EECDH:AES128+EDH';
推薦的密碼套件向後兼容(IE6 / WinXP):如果您的 OpenSSL 是舊版本,不可用密碼將被自動丟棄。總是使用完整的密碼套件,讓OpenSSL選它所支持的。
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4";
密碼套件的順序非常重要,因為它決定在優先級算法將被選中。上面的建議重視算法提供完美的向前保密。
老版本的 OpenSSL 可能不會返回算法的完整列表。AES-GCM 和一些 ECDHE 相當近,而不是出現在大多數版本的 Ubuntu OpenSSL 附帶或 RHEL。
優先級邏輯
首先選擇 ECDHE + AESGCM 密碼。這些都是 TLS 1.2 密碼並沒有受到廣泛支持。這些密碼目前沒有已知的攻擊目標。
PFS 密碼套件是首選,ECDHE 第一,然後 DHE。
AES 128 更勝 AES 256。有討論是否 AES256 額外的安全是值得的成本,結果遠不明顯。目前,AES128 是首選的,因為它提供了良好的安全,似乎真的是快,更耐時機攻擊。
向後兼容的密碼套件,AES 優先 3DES。暴力攻擊 AES 在 TLS1.1 及以上,減輕和 TLS1.0 中難以實現。向後不兼容的密碼套件,3DES 不存在.
RC4 被完全移除. 3DES 用於向後兼容。 查看討論 #RC4_weaknesses
強制性的丟棄
aNULL 包含未驗證 diffie - hellman 密鑰交換,受到中間人這個攻擊
eNULL 包含未加密密碼(明文)
EXPORT 被美國法律標記為遺留弱密碼
RC4 包含了密碼,使用廢棄ARCFOUR算法
DES 包含了密碼,使用棄用數據加密標准
SSLv2 包含所有密碼,在舊版本中定義SSL的標准,現在棄用
MD5 包含所有的密碼,使用過時的消息摘要5作為散列算法
ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m;
在SSLv3或這是TLSv1握手時選擇一個密碼,通常是使用客戶端的偏好。如果這個指令是啟用的,那麼服務器反而是使用服務器的偏好。
更多關於SSL preferserver密碼的信息
更多關於SSL密碼的信息
向前保密的概念很簡單:客戶端和服務器協商一個可靠的密鑰,並在會話結束後銷毀。服務器中的RSA私鑰用來簽名客戶端和服務器之間交換的Diffie- Hellman密鑰。副主密鑰從Diffie-Hellman握手中得到,並用於加密。由於副主密鑰在客戶端和服務器之間的連接中是明確具體的,並用於有 限的時間,因此被叫作Ephemeral(短暫的)。
由於有Forward Secrecy,即使攻擊者持有服務器的私鑰,也不能夠解密過去的會話。私鑰僅僅用來簽名DH(Diffie-Hellman)的握手,它並沒有洩漏副主 密鑰。Diffie-Hellman確保了副主密鑰不會離開客戶端和服務器,也不會被中間人截獲。
1.4.4所有的nginx版本在往Diffiel-Hellman輸入參數時依賴OpenSSL。不幸的時,這就意味著Ephemeral Diffiel-Hellman(DHE)會使用OpenSSL的這一缺陷,包括一個1024位的交換密鑰。由於我們正在使用一個2048位的證 書,DHE客戶端比非ephemeral客戶端將使用一個更弱的密鑰交換。
我們需要產生一個更強的DHE參數:
cd /etc/ssl/certs openssl dhparam -out dhparam.pem 4096
然後告訴nginx在DHE密鑰交換的時候使用它:
ssl_dhparam /etc/ssl/certs/dhparam.pem;
OCSP是更輕量級的,因為它一次只獲取一條記錄。但是副作用是,當連接到服務器的時候,OCSP請求必須發送到第三方響應者,這增加了延遲,以及失敗的 可能。實際上,OCSP響應者由CA操控,由於它常常不可靠,導致浏覽器由於收不到適時的響應而失敗。這減少了安全性,因為它允許攻擊者對OCSP響應者 進行DoS攻擊來取消驗證。
解決方案是在TLS握手期間,允許服務器發送緩存的OCSP記錄,這樣來繞過OCSP響應者。這個技術節省了在客戶端和OCSP響應者之間的一個來回,稱為OCSP閉合(OCSP Stapling)。
服務器只在客戶端請求的時候,發送一個緩存的OCSP響應,通過對CLIENT HELLO的status_request TLS拓展來聲明支持。
大多數服務器都會緩存OCSP響應到48小時。在常規間隔,服務器會連接到CA的OCSP響應者來獲取最新的OCSP記錄。OCSP響應者的位置是從簽名證書的Authority Information Access 字段來獲取。
請參閱我的關於在NGINX上增加OCSP閉合(OCSP stapling)的教程
如果可能,你應該開啟 HTTP Strict Transport Security (HSTS),它指示浏覽器只通過HTTPS來訪問你的站點。
請參閱我的文章關於如何配置HTST
你同樣應該開啟 HTTP Public Key Pinning Extension。
Public Key Pinning 意味著證書鏈必須包含處於白名單之中的公鑰。它確保只在白名單中的CA可以對*.example.com進行簽名,而不是浏覽器中保存的任何一個CA。
我已經寫了關於它的一篇文章,包含背景理論和配置實例,針對 Apache, Lighttpd 以及 NGINX:https://raymii.org/s/articles/HTTPPublicKeyPinningExtension_HPKP.html
server { listen [::]:443 default_server; ssl on; ssl_certificate_key /etc/ssl/cert/raymii_org.pem; ssl_certificate /etc/ssl/cert/ca-bundle.pem; ssl_ciphers 'AES128+EECDH:AES128+EDH:!aNULL'; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_session_cache shared:SSL:10m; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.4.4 8.8.8.8 valid=300s; resolver_timeout 10s; ssl_prefer_server_ciphers on; ssl_dhparam /etc/ssl/certs/dhparam.pem; add_header Strict-Transport-Security max-age=63072000; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; root /var/www/; index index.html index.htm; server_name raymii.org; }
如果你應用了上面的配置文件,你需要重啟nginx:
# Check the config first: /etc/init.d/nginx configtest # Then restart: /etc/init.d/nginx restart
現在使用 SSL 實驗室測試(SSL Labs tes)看看你是否得到一個漂亮的A。同時,當然,擁有一個安全的,牢靠的,作為未來樣例的SSL配置。
譯文:http://www.oschina.net/translate/strong_ssl_security_on_nginx