NGINX 配置 SSL 雙向認證

對於 NGINX 的 HTTPS 配置,一般狀況下咱們只須要實現服務端認證就行,由於瀏覽器內置了一些受信任的證書頒發機構(CA),服務器端只須要拿到這些機構頒發的證書並配置好,瀏覽器會本身校驗證書的可用性並經過 SSL 進行通信加密。css

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

CA 與自簽名

CA 是權威機構才能作的,而且若是該機構達不到安全標準就會被瀏覽器廠商「封殺」,前不久的沃通、StartSSL 就被 Mozilla、Chrome 封殺了。不過這並不影響咱們進行雙向認證配置,由於咱們是自建 CA 的..nginx

爲了方便,咱們就在 NGINX 的目錄下進行證書相關製做:瀏覽器

cd /etc/nginx mkdir ssl cd ssl 

製做 CA 私鑰安全

openssl genrsa -out ca.key 2048 

製做 CA 根證書(公鑰)bash

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

注意:服務器

  1. Common Name 能夠隨意填寫
  2. 其餘須要填寫的信息爲了不有誤,都填寫 .

服務器端證書

製做服務端私鑰curl

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

生成簽發請求ui

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

注意:加密

  1. Common Name 得填寫爲訪問服務時的域名,這裏咱們用 usb.dev 下面 NGINX 配置會用到
  2. 其餘須要填寫的信息爲了不有誤,都填寫 . 吧(爲了和 CA 根證書匹配)

用 CA 簽發

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

客戶端證書

和服務端證書相似:

注意:

  1. Common Name能夠隨意填寫
  2. 其餘須要填寫的信息爲了不有誤,都填寫 . 吧(爲了和 CA 根證書匹配)

至此須要的證書都弄好了,咱們能夠開始配置 NGINX 了。

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; } } 

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

配置好後就就從新加載 NGINX 吧:

service nginx reload 

好了,下面咱們能夠開始驗證了。

請求驗證

驗證過程能夠選擇在其餘機器或是本機,爲了可以解析 usb.dev,還須要配置一下 /etc/hosts

127.0.0.1 usb.dev 

若是用瀏覽器驗證,須要把客戶端證書導出成 p12 格式的,這裏略過。咱們重點是經過 curl 進行驗證:

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

其中 --insecure 是忽略自建 CA 的非權威性。若是你驗證正常那說明你運氣好,由於這裏有個 深坑:某些版本的 curl 會報錯:

<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> 

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

相關文章
相關標籤/搜索