前景提要:
目前越來越多的產品開始采用HTTPS,而采用HTTPS就需要SSL證書,所以需要在nginx中使用ssl模塊配置HTTPS的支持。本文就是nginx配置ssl模塊中一個踩坑與過坑的案例。
HTTPS科普:
首先來科普下什么是HTTPS?HTTPS (基於安全套接字層的超文本傳輸協議 或者是 HTTP over SSL) 是一個 Netscape 開發的 Web 協議。可以這么認為:HTTPS = HTTP + SSL。
超文本傳輸協議 (HTTP) 是一個用來通過互聯網傳輸和接收信息的協議。HTTP 使用請求/響應的過程,因此信息可在服務器間快速、輕松而且精確的進行傳輸,當我們在訪問web頁面時,采用的是不安全的HTTP協議。所以Netscape推出了HTTPS,也就是基於安全套接字層的 HTTP 協議
大多數情況下,HTTP 和 HTTPS 是相同的,因為都是采用同一個基礎的協議,作為 HTTP 或 HTTPS 客戶端——瀏覽器,設立一個連接到 Web 服務器指定的端口。當服務器接收到請求,它會返回一個狀態碼以及消息,這個回應可能是請求信息、或者指示某個錯誤發送的錯誤信息。系統使用統一資源定位器 URI 模式,因此資源可以被唯一指定。而 HTTPS 和 HTTP 唯一不同的只是一個協議頭(https)的說明,其他都是一樣的。下文列舉一下HTTP 和 HTTPS 的不同之處:
HTTP 的 URL 以 http:// 開頭,而 HTTPS 的 URL 以 https:// 開頭
HTTP 是不安全的,而 HTTPS 是安全的
HTTP 標准端口是 80 ,而 HTTPS 的標准端口是 443
在 OSI 網絡模型中,HTTP 工作於應用層,而 HTTPS 工作在傳輸層
HTTP 無需加密,而 HTTPS 對傳輸的數據進行加密
HTTP 無需證書,而 HTTPS 需要認證證書
簡而言之,在使用HTTPS連接時,服務器要求有公鑰和簽名的證書。當使用 https 連接,服務器響應初始連接,並提供它所支持的加密方法。作為回應,客戶端選擇一個連接方法,並且客戶端和服務器端交換證書驗證彼此身份。完成之后,在確保使用相同密鑰的情況下傳輸加密信息,然后關閉連接。為了提供 https 連接支持,服務器必須有一個公鑰證書,該證書包含經過證書機構認證的密鑰信息,大部分證書都是通過第三方機構授權的,以保證證書是安全的。上文提到HTTPS = HTTP + SSL,那HTTP和SSL分別需要做的工作是這樣的:
HTTP 包含如下動作:
瀏覽器打開一個 TCP 連接
瀏覽器發送 HTTP 請求到服務器端
服務器發送 HTTP 回應信息到瀏覽器
TCP 連接關閉
SSL 包含如下動作:
驗證服務器端
允許客戶端和服務器端選擇加密算法和密碼,確保雙方都支持
驗證客戶端(可選)
使用公鑰加密技術來生成共享加密數據
創建一個加密的 SSL 連接
基於該 SSL 連接傳遞 HTTP 請求
nginx配置:
當然,前面的都是鋪墊,本文的重點終於來了。就是如何生成SSL證書並配置nginx。這部分通常都是PE或者SA進行操作的,但是如果想在測試環境自己玩一玩的話,那么攻略來了。
1. 生成證書
可以通過以下步驟生成一個簡單的證書:
首先,進入你想創建證書和私鑰的目錄,例如:
$ cd /home/appuser/nginx-1.4.7/conf
創建服務器私鑰,命令會讓你輸入一個口令:
$ openssl genrsa -des3 -out cookie.key 1024
創建簽名請求的證書(CSR):
$ openssl req -new -key cookie.key -out cookie.csr
在加載SSL支持的Nginx並使用上述私鑰時除去必須的口令:
$ cp cookie.key cookie.key.org
$ openssl rsa -in cookie.key.org -out cookie.key
2. 配置nginx
最后標記證書使用上述私鑰和CSR:
$ openssl x509 -req -days 365 -in cookie.csr -signkey cookie.key -out cookie.crt
修改Nginx配置文件,讓其包含新標記的證書和私鑰:
server {
server_name YOUR_DOMAINNAME_HERE;
listen 443;
ssl on;
ssl_certificate /usr/local/nginx/conf/server.crt;
ssl_certificate_key /usr/local/nginx/conf/server.key;
}
重啟nginx
踩坑與過坑:
本來以為這樣就可以萬事大吉了,但是在壓力提高以后,就會出現一些錯誤。去查看nginx的錯誤日志以及dmesg的報錯如下:
nginx報錯:
2016/12/26 19:37:48 [alert] 27592#0: worker process 27593 exited on signal 11
2016/12/26 19:37:48 [alert] 27592#0: worker process 27596 exited on signal 11
2016/12/26 19:37:49 [alert] 27592#0: worker process 27594 exited on signal 11
dmesg報錯:
[51059663.024824] nginx[32061]: segfault at 0 ip 00000000004248db sp 00007fffffba9b70 error 4 in nginx[400000+92000]
[51059668.968624] show_signal_msg: 54 callbacks suppressed
[51059668.968628] nginx[32115]: segfault at 0 ip 00000000004248db sp 00007fffffba9b30 error 4 in nginx[400000+92000]
[51059669.036477] nginx[32184]: segfault at 0 ip 00000000004248db sp 00007fffffba9b30 error
bit2:值為1時表示 是用戶態程序內存訪問越界,值為0時表示 是內核態程序內存訪問越界
bit1:值為1時表示 是寫操作導致內存訪問越界,值為0時表示 是讀操作導致內存訪問越界
bit0:值為1表示沒有足夠的權限訪問非法地址的內容,值為0時表示訪問的非法地址根本沒有對應的頁面,也就是無效地址。
ssl_session_cache shared:SSL:1024m;
ssl_session_timeout 10m;
重啟nginx,完美過坑。
本文來自網易實踐者社區,經作者齊紅方授權發布。