nginx配置ssl加密(單/雙向認證、部分https) – HTTPS SSL 教程
nginx配置ssl加密(單/雙向認證、部分https) – HTTPS SSL 教程
nginx下配置ssl本來是很簡單的,無論是去認證中心買SSL安全證照還是自簽署證照,但最近公司OA的一個需求,得以有個機會實際折騰一番。一開始採用的是全站加密,所有訪問http:80的請求強制轉換(rewrite)到https,後來自動化測試結果說響應速度太慢,https比http慢慢30倍,心想怎麼可能,鬼知道他們怎麼測的。所以就試了一下部分頁面https(不能只針對某類動態請求才加密)和雙向認證。下面分節介紹。
預設nginx是沒有安裝ssl模組的,需要編譯安裝nginx時加入
--with-http_ssl_module
選項。
提示:nignx到後端伺服器由於一般是內網,所以不加密。
1. 全站ssl
全站做ssl是最常見的一個使用場景,預設埠443,而且一般是單向認證。
server { listen 443; server_name example.com; root /apps/www; index index.html index.htm; ssl on; ssl_certificate ../SSL/ittest.pem; ssl_certificate_key ../SSL/ittest.key;# ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;# ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;# ssl_prefer_server_ciphers on;}
如果想把http的請求強制轉到https的話:
server { listen 80; server_name example.me; rewrite ^ 使用return的效率會更高 # return 301 }
ssl_certificate
證照其實是個公鑰,它會被髮送到連線伺服器的每個客戶端,
ssl_certificate_key
私鑰是用來解密的,所以它的許可權要得到保護但nginx的主程式能夠讀取。當然私鑰和證照可以放在一個證照檔案中,這種方式也只有公鑰證照才傳送到client。
ssl_protocols
指令用於啟動特定的加密協議,nginx在1.1.13和1.0.12版本後預設是
ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2
,TLSv1.1與TLSv1.2要確保OpenSSL >= 1.0.1 ,SSLv3 現在還有很多地方在用但有不少被攻擊的漏洞。
ssl_ciphers
選擇加密套件,不同的瀏覽器所支援的套件(和順序)可能會不同。這裡指定的是OpenSSL庫能夠識別的寫法,你可以透過
openssl -v cipher 'RC4:HIGH:!aNULL:!MD5'
(後面是你所指定的套件加密演算法) 來看所支援演算法。
ssl_prefer_server_ciphers on
設定協商加密演算法時,優先使用我們服務端的加密套件,而不是客戶端瀏覽器的加密套件。
https最佳化引數
-
ssl_session_cache shared:SSL:10m;
: 設定ssl/tls會話快取的型別和大小。如果設定了這個引數一般是shared
,buildin
可能會引數記憶體碎片,預設是none
,和off
差不多,停用快取。如shared:SSL:10m
表示我所有的nginx工作程式共享ssl會話快取,官網介紹說1M可以存放約4000個sessions。 詳細參考serverfault上的問答ssl_session_cache。 -
ssl_session_timeout
: 客戶端可以重用會話快取中ssl引數的過期時間,內網系統預設5分鐘太短了,可以設成30m
即30分鐘甚至4h
。
設定較長的
keepalive_timeout
也可以減少請求ssl會話協商的開銷,但同時得考慮執行緒的併發數了。
提示:在生成證照請求csr檔案時,如果輸入了密碼,nginx每次啟動時都會提示輸入這個密碼,可以使用私鑰來生成解密後的key來代替,效果是一樣的,達到免密碼重啟的效果:
openssl rsa -in ittest.key -out ittest_unsecure.key
匯入證照
如果你是找一個知名的 頒發機構如VeriSign、Wosign、StartSSL簽發的證照,瀏覽器已經內建並信任了這些根證照,如果你是自建C或獲得二級CA授權,都需要將CA證照新增到瀏覽器,這樣在訪問站點時才不會顯示不安全連線。各個瀏覽的新增方法不在本文探討範圍內。
2. 部分頁面ssl
一個站點並不是所有資訊都是非常機密的,如網上商城,一般的商品瀏覽可以不透過https,而使用者登入以及支付的時候就強制經過https傳輸,這樣使用者訪問速度和安全性都得到兼顧。
但是請注意不要理解錯了,是對頁面加密而不能針對某個請求加密,一個頁面或位址列的URL一般會發起許多請求的,包括css/png/js等靜態檔案和動態的java或php請求,所以要加密的內容包含頁面內的其它資原始檔,否則就會出現http與https內容混合的問題。在http頁面混有https內容時,頁面排版不會發生亂排現象;在https頁面中包含以http方式引入的圖片、js等資源時,瀏覽器為了安全起見會阻止載入。
下面是隻對
example.com/account/login
登入頁面進行加密的栗子:
root /apps/www;index index.html index.htm;server { listen 80; server_name example.com; location ^~ /account/login { rewrite ^ } location / { proxy_pass proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_redirect off; } }server { listen 443 ssl; server_name example.com; ssl on; ssl_certificate ../SSL/ittest.pem; ssl_certificate_key ../SSL/ittest.key; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; location ^~ /account/login { proxy_pass ### Most PHP, Python, Rails, Java App can use this header -> https ### proxy_set_header X-Forwarded-Proto $scheme; } location / { rewrite ^ } }
關於rewrite與location的寫法參考這裡。當瀏覽器訪問
時,被301到
,在這個ssl加密的虛擬主機裡也匹配到
/account/login
,反向代理到後端伺服器,後面的傳輸過程是沒有https的。這個login.xx頁面下的其它資源也是經過https請求nginx的,登入成功後跳轉到首頁時的連結使用http,這個可能需要開發程式碼裡面控制。
- 上面配置中使用了
proxy_set_header X-Forwarded-Proto $scheme
,在jsp頁面使用request.getScheme()
得到的是https 。如果不把請求的$scheme協議設定在header裡,後端jsp頁面會一直認為是http,將導致響應異常。 - ssl配置塊還有個與不加密的80埠類似的
location /
,它的作用是當使用者直接透過https訪問首頁時,自動跳轉到不加密埠,你可以去掉它允許使用者這樣做。
3. 實現雙向ssl認證
上面的兩種配置都是去認證被訪問的站點域名是否真實可信,並對傳輸過程加密,但伺服器端並沒有認證客戶端是否可信。(實際上除非特別重要的場景,也沒必要去認證訪問者,除非像銀行U盾這樣的情況)
要實現雙向認證HTTPS,nginx伺服器上必須匯入CA證照(根證照/中間級證照),因為現在是由伺服器端透過CA去驗證客戶端的資訊。還有必須在申請伺服器證照的同時,用同樣的方法生成客戶證照。取得客戶證照後,還要將它轉換成瀏覽器識別的格式(大部分瀏覽器都認識PKCS12格式):
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
然後把這個
client.p12
發給你相信的人,讓它匯入到瀏覽器中,訪問站點建立連線的時候nginx會要求客戶端把這個證照發給自己驗證,如果沒有這個證照就拒絕訪問。
同時別忘了在 nginx.conf 裡配置信任的CA:(如果是二級CA,請把根CA放在後面,形成CA證照鏈)
proxy_ignore_client_abort on; ssl on; ... ssl_verify_client on; ssl_verify_depth 2; ssl_client_certificate ../SSL/ca-chain.pem;#在雙向location下加入: proxy_set_header X-SSL-Client-Cert $ssl_client_cert;
擴充:使用geo模組
nginx預設安裝了一個
ngx_http_geo_module
,這個geo模組可以根據客戶端IP來建立變數的值,用在如來自172.29.73.0/24段的IP訪問login時使用雙向認證,其它段使用一般的單向認證。
geo $duplexing_user { default 1; include geo.conf; # 注意在0.6.7版本以後,include是相對於nginx.conf所在目錄而言的}
語法
geo [$address] $variable { … }
,位於http段,預設地址是
$reoute_addr
,假設
conf/geo.conf
內容:
127.0.0.1/32 LOCAL; # 本地172.29.73.23/32 SEAN; # 某個IP172.29.73.0/24 1; # IP段,可以按國家或地域定義後面的不同的值
需要配置另外一個虛擬主機server{ssl 445},裡面使用上面雙向認證的寫法,然後在80或443裡使用變數
$duplexing_user
去判斷,如果為1就rewrite到445,否則rewrite到443。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31483669/viewspace-2675833/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Nginx的SSL配置優化 – HTTPS SSL 教程Nginx優化HTTP
- Nginx使用SSL模組配置httpsNginxHTTP
- nginx docker容器配置https(ssl)NginxDockerHTTP
- SSL證書安裝指引教程 – HTTPS SSL 教程HTTP
- SSL證書格式轉換 – HTTPS SSL 教程HTTP
- SSL證書轉PEM格式 – HTTPS SSL 教程HTTP
- nginx配置SSL證書實現https服務NginxHTTP
- HTTPS的SSL證書配置HTTP
- https雙向認證HTTP
- phpStudy安裝ssl證照 – HTTPS SSL 教程PHPHTTP
- SSL證書申請問題 – HTTPS SSL 教程HTTP
- Tomcat 安裝SSL證書 – HTTPS SSL 教程TomcatHTTP
- nginx使用ssl模組配置HTTPS支援NginxHTTP
- 伺服器配置ssl證書支援蘋果ATS方法 – HTTPS SSL 教程伺服器蘋果HTTP
- 深入理解https進行SSL單向認證的全過程HTTP
- Vesta 安裝SSL – HTTPS SSL 教程HTTP
- Https雙向認證Android客戶端配置HTTPAndroid客戶端
- 在Nginx下部署SSL證書並重定向至HTTPS的教程NginxHTTP
- nginx配置ssl實現https訪問 小白文NginxHTTP
- 有關https的SSL加密方式HTTP加密
- 哪些IP SSL證書支援IP地址https加密呢?HTTP加密
- Keytool配置 Tomcat的HTTPS雙向認證TomcatHTTP
- 怎麼給網站配置SSL證書(https)網站HTTP
- iOS HTTPS雙向認證以及證書操作iOSHTTP
- SSL證書生成,完成HTTPS驗證HTTP
- 本地簽發ssl證書(https)HTTP
- [HTTPS]SSL/TLSHTTPTLS
- HTTPS計算機網路SSL加密HTTP計算機網路加密
- [python][nginx][https] Nginx 伺服器 SSL 證照安裝部署PythonNginxHTTP伺服器
- Nginx+Tomcat Https SSL部署方案NginxTomcatHTTP
- 教你如何給 Discuz! X3.1/3.2 開啟https(SSL)支援! – HTTPS SSL 教程HTTP
- 在Drupal上安裝SSL證書啟用HTTPS加密訪問的教程HTTP加密
- 詳解如何給Tomcat配置Https/ssl證書TomcatHTTP
- 亞馬遜雲伺服器aws配置ssl https證書亞馬遜伺服器HTTP
- 聊一聊HTTPS雙向認證的簡單應用HTTP
- 關於SSL證書雙向認證該怎麼操作
- NodeJS Https HSM雙向認證實現NodeJSHTTP
- 免費購買SSL證書,nginx無縫升級httpsNginxHTTP