介紹
TLS或稱傳輸層安全性,及其前身SSL(代表安全套接字層)是用於將正常流量包裝在受保護的加密包裝中的Web協議。
使用這種技術,服務器可以在服務器和客戶端之間安全地發送流量,而不會被外部各方攔截。證書系統還可以幫助用戶驗證他們正在連接的站點的身份。
在本教程中,我們將向您展示如何設置自簽名SSL證書,以便與Ubuntu 16.04服務器上的Nginx Web服務器一起使用。
注意:自簽名證書將加密服務器與任何客戶端之間的通信。但是,由於Web瀏覽器不包含任何受信任的證書頒發機構的簽名,因此用戶無法使用該證書自動驗證服務器的身份。
如果您沒有與服務器關聯的域名以及加密Web界面不面向用戶的實例,則可能需要使用自簽名證書。
- 如果你有域名,保護你網站的最簡單方法是使用騰訊雲SSL證書服務,它提供免費的可信證書。騰訊雲SSL證書安裝操作指南進行設置。
- 如果你沒有域名,建議您先去這里注冊一個域名,如果你只是使用此配置進行測試或個人使用,則可以使用自簽名證書,不需要購買域名。自簽名證書提供了相同類型的加密,但沒有域名驗證公告。關於自簽名證書,你可以參考為Apache創建自簽名SSL證書和如何為Nginx創建自簽名SSL證書這兩篇文章。
准備
在開始之前,您應該為非root用戶配置sudo
權限。您可以按照Ubuntu 16.04的初始服務器設置了解如何設置此類用戶帳戶。沒有服務器的同學可以在這里購買,不過我個人更推薦您使用免費的騰訊雲開發者實驗室進行試驗,學會安裝后再購買服務器。
您還需要安裝Nginx Web服務器。如果您想在服務器上安裝整個LEMP(Linux,Nginx,MySQL,PHP)堆棧,可以按照我們在Ubuntu 16.04上設置LEMP的教程進行操作。
如果您只是想要Nginx Web服務器,您可以按照我們的指南在Ubuntu 16.04上安裝Nginx。
完成准備內容后,請繼續以下操作。
第一步:創建SSL證書
TLS / SSL通過使用公共證書和私鑰的組合來工作。SSL密鑰在服務器上保密。它用於加密發送給客戶端的內容。SSL證書與請求內容的任何人公開共享。它可用於解密由關聯的SSL密鑰簽名的內容。
我們可以在一個命令中使用OpenSSL創建自簽名密鑰和證書對:
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/nginx-selfsigned.key -out /etc/ssl/certs/nginx-selfsigned.crt
您將被問到一系列問題。在我們討論之前,讓我們看看我們發出的命令中發生了什么:
- openssl:這是用於創建和管理OpenSSL證書,密鑰和其他文件的基本命令行工具。
- req:此子命令指定我們要使用X.509證書簽名請求(CSR)管理。“X.509”是SSL和TLS為其密鑰和證書管理所遵循的公鑰基礎結構標准。我們想要創建一個新的X.509證書,所以我們使用這個子命令。
- -x509:通過告訴實用程序我們要創建自簽名證書而不是生成證書簽名請求(通常會發生)來進一步修改上一個子命令。
- -nodes:這告訴OpenSSL跳過用密碼保護我們的證書的選項。當服務器啟動時,我們需要Nginx能夠在沒有用戶干預的情況下讀取文件。密碼短語會阻止這種情況發生,因為我們必須在每次重啟后輸入密碼。
- -days 365:此選項設置證書被視為有效的時間長度。我們在這里設置了一年。
- -newkey rsa:2048:這指定我們要同時生成新證書和新密鑰。我們沒有創建在上一步中簽署證書所需的密鑰,因此我們需要將其與證書一起創建。該
rsa:2048
部分告訴它制作一個2048位長的RSA密鑰。 - -keyout:這一行告訴OpenSSL在哪里放置我們正在創建的生成的私鑰文件。
- -out:這告訴OpenSSL在哪里放置我們正在創建的證書。
如上所述,這些選項將創建密鑰文件和證書。我們將詢問有關我們服務器的一些問題,以便將信息正確地嵌入到證書中。
適當填寫提示。 最重要的一行是Common Name (e.g. server FQDN or YOUR name)那一行。您需要輸入與服務器關聯的域名,或者是您服務器的公共IP地址。
整個提示將如下所示:
OutputCountry Name (2 letter code) [AU]:US State or Province Name (full name) [Some-State]:New York Locality Name (eg, city) []:New York City Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bouncy Castles, Inc. Organizational Unit Name (eg, section) []:Ministry of Water Slides Common Name (e.g. server FQDN or YOUR name) []:server_IP_address Email Address []:admin@your_domain.com
您創建的兩個文件都將放在/etc/ssl
目錄的相應子目錄中。
在我們使用OpenSSL的同時,我們還應該創建一個強大的Diffie-Hellman組,用於與客戶協商Perfect Forward Secrecy。
我們可以通過輸入以下內容來執行:
sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
這可能需要幾分鍾,但一旦完成,您將擁有一個強大的DH組/etc/ssl/certs/dhparam.pem
,我們可以在我們的配置中使用。
第二步:配置Nginx以使用SSL
我們在/etc/ssl
目錄下創建了密鑰和證書文件。現在我們只需要修改我們的Nginx配置就可以利用它們。
我們將對配置進行一些調整。
- 我們將創建一個包含SSL密鑰和證書文件位置的配置代碼段。
- 我們將創建一個包含強SSL設置的配置代碼段,可以在將來與任何證書一起使用。
- 我們將調整我們的Nginx服務器塊來處理SSL請求並使用上面的兩個片段。
這種配置Nginx的方法將允許我們保持干凈的服務器塊並將常見配置段放入可重用模塊中。
創建指向SSL密鑰和證書的配置代碼段
首先,讓我們在/etc/nginx/snippets
目錄中創建一個新的Nginx配置代碼段。
為了正確區分此文件的目的,我們稱之為self-signed.conf
:
sudo nano /etc/nginx/snippets/self-signed.conf
在這個文件中,我們只需要將ssl_certificate
指令設置為我們的證書文件和ssl_certificate_key
相關的密鑰。在我們的教程中,是這樣設置的:
ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt; ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
添加這些行后,保存並關閉該文件。
使用強加密設置創建配置代碼段
接下來,我們將創建另一個片段,用於定義一些SSL設置。這將使Nginx具有強大的SSL密碼套件,並啟用一些有助於保證我們的服務器安全的高級功能。
我們將設置的參數可以在將來的Nginx配置中重用,因此我們將為該文件指定一個通用名稱:
sudo nano /etc/nginx/snippets/ssl-params.conf
鏈接到上述網站的建議設置提供了強大的安全性。有時,這是以更高的客戶端兼容性為代價的。如果您需要支持較舊的客戶端,可以通過單擊標記為“是的,給我一個與舊版/舊版軟件一起使用的密碼套件”的頁面上的鏈接來訪問該列表。該列表可以替換下面復制的項目。
您使用哪種配置的選擇在很大程度上取決於您需要支持的內容。它們都將提供很大的安全性。
出於我們的目的,我們可以完整地復制提供的設置。我們只需要進行一些小的修改。
首先,我們將為上游請求添加我們首選的DNS解析器。我們將使用Google。我們還將繼續將ssl_dhparam
設置為指向我們之前生成的Diffie-Hellman文件。
最后,您應花點時間閱讀HTTP嚴格傳輸安全性或HSTS,特別是有關“預加載”功能的信息。預加載HSTS可提高安全性,但如果意外啟用或啟用錯誤,可能會產生較大影響。在本教程中,我們不會預加載設置,但如果您確定了解其含義,則可以對其進行修改:
# from https://cipherli.st/ # and https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_prefer_server_ciphers on; ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH"; ssl_ecdh_curve secp384r1; ssl_session_cache shared:SSL:10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s; # Disable preloading HSTS for now. You can use the commented out header line that includes # the "preload" directive if you understand the implications. #add_header Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"; add_header Strict-Transport-Security "max-age=63072000; includeSubdomains"; add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; ssl_dhparam /etc/ssl/certs/dhparam.pem;
由於我們使用的是自簽名證書,因此不會使用SSL部署。Nginx只會輸出警告,為我們的自簽名證書禁用部署,並繼續正常運行。
完成后保存並關閉文件。
調整Nginx配置以使用SSL
現在我們已經有了我們的代碼片段,我們可以調整我們的Nginx配置來啟用SSL。
我們將在本教程中假設您正在使用目錄/etc/nginx/sites-available
中的default
服務器塊文件。如果您使用的是其他服務器塊文件,請在以下命令中替換它的名稱。
在我們繼續之前,讓我們備份當前的服務器塊文件:
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.bak
現在,打開服務器塊文件進行調整:
sudo nano /etc/nginx/sites-available/default
在里面,您的服務器塊可能像這樣:
server {
listen 80 default_server; listen [::]:80 default_server; # SSL configuration # listen 443 ssl default_server; # listen [::]:443 ssl default_server; . . .
我們將修改此配置,以便將未加密的HTTP請求自動重定向到加密的HTTPS中。這為我們的網站提供了最佳安全性。如果要同時允許HTTP和HTTPS流量,請使用后面的備用配置。
我們將把配置分成兩個獨立的塊。在第一個listen
指令之后,我們將添加一個server_name
指令,設置為服務器的域名,或者是IP地址。然后,我們將設置重定向到我們將要創建的第二個服務器塊中。之后,我們將關閉這個短塊:
注意:我們將使用302重定向,直到我們確認一切正常。接下來,我們可以將其更改為永久301重定向。
server {
listen 80 default_server; listen [::]:80 default_server; server_name server_domain_or_IP; return 302 https://$server_name$request_uri; } # SSL configuration # listen 443 ssl default_server; # listen [::]:443 ssl default_server; . . .
接下來,我們需要在下面直接啟動一個新的服務器塊以包含剩余的配置。我們可以取消注釋使用443端口的兩個listen
指令。我們可以添加http2
到這些行,以便在此塊中啟用HTTP / 2。接下來,我們只需要包含我們設置的兩個代碼段文件:
注意:您可能只有一個 listen
指令,其中包含每個IP版本和端口組合的default_server
修飾符。如果您為這些端口啟用了其他default_server
設置的服務器塊,則必須從其中一個塊中刪除修飾符。
server {
listen 80 default_server; listen [::]:80 default_server; server_name server_domain_or_IP; return 302 https://$server_name$request_uri; } server { # SSL configuration listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; include snippets/self-signed.conf; include snippets/ssl-params.conf; . . .
完成后保存並關閉文件。
(備用配置)允許HTTP和HTTPS流量
如果您想要或需要同時允許加密和未加密內容,則必須以不同方式配置Nginx。如果可以避免,通常不建議這樣做,但在某些情況下可能是必要的。基本上,我們只要將兩個單獨的服務器塊壓縮為一個塊並刪除重定向:
server {
listen 80 default_server; listen [::]:80 default_server; listen 443 ssl http2 default_server; listen [::]:443 ssl http2 default_server; server_name server_domain_or_IP; include snippets/self-signed.conf; include snippets/ssl-params.conf; . . .
完成后保存並關閉文件。
第三步:調整防火牆
如果ufw
啟用了防火牆,則必須按照本教程准備 中的建議,調整設置以允許SSL流量。幸運的是, ufw
在安裝時注冊了一些Nginx配置文件。
我們可以通過輸入以下內容來查看可用的配置文件
sudo ufw app list
您應該看到如下列表:
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
您可以輸入以下內容來查看當前設置:
sudo ufw status
它可能看起來像這樣,這意味着只允許HTTP流量進入Web服務器:
OutputStatus: active
To Action From
-- ------ ---- OpenSSH ALLOW Anywhere Nginx HTTP ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx HTTP (v6) ALLOW Anywhere (v6)
為了進一步允許HTTPS流量,我們可以允許“Nginx Full”配置文件,然后刪除冗余的“Nginx HTTP”配置文件限額:
sudo ufw allow 'Nginx Full'
sudo ufw delete allow 'Nginx HTTP'
您的狀態現在應該如下所示:
sudo ufw status
OutputStatus: active
To Action From
-- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)
第四步:啟用Nginx中的更改
現在我們已經進行了更改並調整了防火牆,我們可以重新啟動Nginx以實現我們的新更改。
首先,我們應該檢查以確保我們的文件中沒有語法錯誤。我們可以通過輸入以下內容來執行:
sudo nginx -t
如果一切順利,您將得到如下結果:
Outputnginx: [warn] "ssl_stapling" ignored, issuer certificate not found nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
注意開始前的警告。如前所述,由於我們的自簽名證書無法使用SSL裝訂,因此此特定設置會發出警告。這是預期的,我們的服務器仍然可以正確加密連接。
如果輸出與上述內容匹配,則配置文件沒有語法錯誤。我們可以安全地重啟Nginx以實現我們的更改:
sudo systemctl restart nginx
第五步:測試加密
現在,我們已准備好測試我們的SSL服務器。
打開Web瀏覽器,然后在地址欄輸入 https://
及服務器的域名或IP:
https://server_domain_or_IP
由於我們創建的證書未由您的某個瀏覽器的受信任證書頒發機構簽名,因此您可能會看到一個可怕的警告,如下所示:

這是預期和正常的。我們只對證書的加密方面感興趣,而不是對主機真實性的第三方驗證感興趣。單擊“高級”,然后提供鏈接以繼續進入您的主機:

你應該被帶到你的網站。如果你在瀏覽器地址欄中查看,你會看到一個帶有“x”的鎖。在這種情況下,這只意味着無法驗證證書。它仍在加密您的連接。
如果您使用兩個服務器塊配置Nginx,自動將HTTP內容重定向到HTTPS,您還可以檢查重定向是否正常運行:
http://server_domain_or_IP
如果這結果是相同的圖標,這意味着您的重定向工作正常。
第六步:更改為永久重定向
如果您的重定向工作正常並且您確定只想允許加密流量,則應修改Nginx配置以使重定向永久化。
再次打開服務器塊配置文件:
sudo nano /etc/nginx/sites-available/default
找到return 302
並將其更改為return 301
:
server {
listen 80 default_server; listen [::]:80 default_server; server_name server_domain_or_IP; return 301 https://$server_name$request_uri; } . . .
保存並關閉文件。
檢查配置是否存在語法錯誤:
sudo nginx -t
准備好后,重新啟動Nginx以使重定向永久化:
sudo systemctl restart nginx
https://cloud.tencent.com/developer/article/1346683