首頁  >  文章  >  php教程  >  NGINX 設定 SSL 雙向認證

NGINX 設定 SSL 雙向認證

高洛峰
高洛峰原創
2016-11-17 13:21:581888瀏覽

背景

對於NGINX 的HTTPS 配置,通常情況下我們只需要實現服務端認證就行,因為瀏覽器內置了一些受信任的證書頒發機構(CA),服務器端只需要拿到這些機構頒發的證書並配置好,瀏覽器會自行校驗證書的可用性並透過SSL 進行通訊加密。

但特殊情況下我們也需要對客戶端進行驗證,只有受信任的客戶端才能使用服務接口,此時我們就需要啟用雙向認證來達到這個目的,只有 當客戶端請求帶了可用的證書才能調通服務端介面 。

CA 與自簽名

CA 是權威機構才能做的,並且如果該機構達不到安全標準就會被瀏覽器廠商“封殺”,前不久的沃通、StartSSL 就被 Mozilla、Chrome 封殺了。不過這並不影響我們進行雙向認證配置,因為我們是自建CA 的..

為了方便,我們就在NGINX 的目錄下進行證書相關製作:

cd /etc/nginx
mkdir sslcd ssl

製作CA 私鑰

openssl genrsa -out ca.key 2048

製作CA 根憑證(公鑰)

openssl req -new -x509 -days 3650 -key ca.key -out ca.crt

注意:

Common Name 可以隨意填寫

其他需要填寫的資訊為了避免有誤,都填寫 . 吧

伺服器端憑證

生成請

openssl genrsa -out server.pem 1024
openssl rsa -in server.pem -out server.key

注意:

Common Name 得填寫為訪問服務時的域名,這裡我們用 usb.dev 下面NGINX 配置會用到

其他需要填寫的信息為了避免有誤,都填寫 . 吧(為了和CA 根憑證符合)

用CA 簽發

openssl x509 -req -sha256 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt -CAkey ca.key -CAcreateserial -days 3650 -out server.crt🜎

和服務端憑證類似:

注意:

Common Name可以隨意填寫

其他需要填寫的資訊為了避免有誤,都填寫 . 吧(為了和CA 根憑證相符)

至此所需的憑證都弄弄好了,我們可以開始設定NGINX 了。

NGINX

openssl req -new -key server.pem -out server.csr

其中 ssl_client_certificate /etc/nginx/ssl/ca.crt; 的意思是使用 CA 憑證來驗證請求帶的用戶端憑證是否是該 CA 所簽發的。

配置好後就重新載入 NGINX 吧:

server {
    listen       443 ssl;
    server_name  usb.dev;

    access_log off;

    ssl on;
    ssl_certificate /etc/nginx/ssl/server.crt;
    ssl_certificate_key /etc/nginx/ssl/server.key;
    ssl_client_certificate /etc/nginx/ssl/ca.crt;
    ssl_verify_client on;

    location / {
        proxy_pass http://backend$request_uri;
    }
}

好了,下面我們可以開始驗證了。

請求驗證

驗證程序可以選擇在其他機器或是本機,為了能夠解析 usb.dev,還需要設定 /etc/hosts:

service nginx reload

如果用瀏覽器驗證,需要把客戶端憑證成p12 格式的,這裡略過。我們重點是透過 curl 進行驗證:

127.0.0.1 usb.dev

其中 --insecure 是忽略自建 CA 的非權威性。如果你驗證正常那表示你運氣好,因為這裡有個 深坑:某些版本的curl 會報錯:

curl --insecure --key client.key --cert client.crt 'https://usb.dev'

這些報錯版本的curl 居然要嚴格要求 --cert 實參的路徑要完全正確,例如當前目錄下面要用 --cert ./client.crt,用 --cert client.crt 是錯誤的。爬坑過程是啟用了 -v 參數來觀察完整的過程,發現其中有一個警告:

<html>
<head><title>400 No required SSL certificate was sent</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<center>No required SSL certificate was sent</center>
<hr><center>nginx/1.11.0</center>
</body>
</html>

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn