標籤:ssl nginx https配置 tomcat https配置 https雙向驗證 nginx雙向驗證配置
1. 安裝 nginx1.1 nginx 包及其依賴包下載出於模組的依賴性,Nginx 依賴以下三個包:
- gzip 模組需要 zlib 庫(http://www.zlib.net/);
- rewrite 模組需要 pcre 庫(http://www.pcre.org/);
- ssl 功能需要 openssl 庫(http://www.openssl.org/);
分別下載它們的最新穩定版(截至本文最新穩定版分別是 zlib-1.2.8.tar.gz、pcre-8.36.tar.gz、openssl-fips-2.0.9.tar.gz),最後下載 Nginx 最新(http://nginx.org/en/download.html)穩定版(截至本文最新穩定版是 nginx-1.7.10.tar.gz)。
依賴包安裝次序為:openssl、zlib、pcre,最後安裝 Nginx 包。
1.2 nginx 包及其依賴包安裝1.2.1 安裝 openssl
$ tar -zxvf openssl-fips-2.0.9.tar.gz
$ cd openssl-fips-2.0.9
$ ./config
$ make
$ sudo make install
1.2.2 安裝 zlib
$ tar -zxvf zlib-1.2.8.tar.gz
$ cd zlib-1.2.8
$ ./configure
$ make
$ sudo make install
1.2.3 安裝 pcre
$ tar -zxvf pcre-8.36.tar.gz
$ cd pcre-8.36
$ ./configure
$ make
$ sudo make install
1.2.4 安裝 nginx
$ tar -zxvf nginx-1.7.10.tar.gz
$ cd nginx-1.7.10
$ ./configure --with-pcre=../pcre-8.36 --with-zlib=../zlib-1.2.8 --with-openssl=../openssl-fips-2.0.9
$ make
$ sudo make install
nginx 被預設安裝在 /usr/local/nginx 目錄。
1.3 驗證 Nginx 是否安裝成功
$ sudo /usr/local/nginx/sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
證明 Nginx 安裝成功。
2. SSL 伺服器 / 用戶端雙向驗證認證的產生2.1 建立一個新的 CA 根憑證在 nginx 安裝目錄下建立 ca 檔案夾,進入 ca,建立幾個子檔案夾:
$ sudo mkdir ca
$ cd ca
$ sudo mkdir newcerts private conf server
newcerts 子目錄將用於存放 CA 簽署過的數位憑證(認證備份目錄);private 用於存放 CA 的私密金鑰;conf 目錄用於存放一些簡化參數用的設定檔;server 存放伺服器憑證檔案。
2.1.1 conf 目錄建立 openssl.conf 檔案編輯其內容如下:
[ ca ]default_ca = foo # The default ca section [ foo ]dir = /usr/local/nginx/ca # top dirdatabase = /usr/local/nginx/ca/index.txt # index file.new_certs_dir = /usr/local/nginx/ca/newcerts # new certs dir certificate = /usr/local/nginx/ca/private/ca.crt # The CA certserial = /usr/local/nginx/ca/serial # serial no fileprivate_key = /usr/local/nginx/ca/private/ca.key # CA private keyRANDFILE = /usr/local/nginx/ca/private/.rand # random number file default_days = 365 # how long to certify fordefault_crl_days= 30 # how long before next CRLdefault_md = md5 # message digest method to useunique_subject = no # Set to ‘no‘ to allow creation of # several ctificates with same subject.policy = policy_any # default policy [ policy_any ]countryName = matchstateOrProvinceName = matchorganizationName = matchorganizationalUnitName = matchlocalityName = optionalcommonName = suppliedemailAddress = optional
2.1.2 產生私密金鑰 key 檔案
$ cd /usr/local/nginx/ca
$ sudo openssl genrsa -out private/ca.key
輸出
Generating RSA private key, 512 bit long modulus
..++++++++++++
.++++++++++++
e is 65537 (0x10001)
private 目錄下有 ca.key 檔案產生。
2.1.3 產生認證請求 csr 檔案
$ sudo openssl req -new -key private/ca.key -out private/ca.csr
提示輸入 Country Name,輸入 CN 並斷行符號後:
提示輸入 State or Province Name (full name),輸入 Shanghai 並斷行符號後:
提示輸入 Locality Name,輸入 Shanghai 並斷行符號後:
提示輸入 Organization Name,輸入 Defonds 並斷行符號後:
提示輸入 Organizational Unit Name,輸入 Dev 並斷行符號後:
提示輸入 Common Name,如果沒有網域名稱的話,輸入 localhost 並斷行符號後:
提示輸入 Email Address,輸入 [email protected] 並斷行符號後:
提示輸入 A challenge password,輸入 defonds 並斷行符號後:
提示輸入 An optional company name,輸入 df 並斷行符號。private 目錄下有 ca.csr 檔案產生。
2.1.4 產生憑證 crt 檔案
$ sudo openssl x509 -req -days 365 -in private/ca.csr -signkey private/ca.key -out private/ca.crt
控制台輸出
Signature ok
subject=/C=CN/ST=Shanghai/L=Shanghai/O=Defonds/OU=Dev/CN=localhost/[email protected]
Getting Private key
private 目錄下有 ca.crt 檔案產生。
2.1.5 為我們的 key 設定起始序號
$ sudo echo FACE > serial
可以是任意四個字元
2.1.6 建立 CA 鍵庫
$ sudo touch index.txt
2.1.7 為 "使用者認證" 的移除建立一個認證撤銷列表
$ sudo openssl ca -gencrl -out /usr/local/nginx/ca/private/ca.crl -crldays 7 -config "/usr/local/nginx/ca/conf/openssl.conf"
輸出
Using configuration from /usr/local/nginx/ca/conf/openssl.conf
private 目錄下有 ca.crl 檔案產生。
2.2 伺服器憑證的產生2.2.1 建立一個 key
$ sudo openssl genrsa -out server/server.key
輸出
Generating RSA private key, 512 bit long modulus
...........................++++++++++++
.................++++++++++++
e is 65537 (0x10001)
server 目錄下有 server.key 檔案產生。
2.2.2 為我們的 key 建立一個認證簽章要求 csr 檔案
$ sudo openssl req -new -key server/server.key -out server/server.csr
這時會要求你輸入和 2.1.2.2 步一樣的那些問題。輸入需要和那一步一致:
server 目錄下有 server.csr 檔案產生。
2.2.3 使用我們私人的 CA key 為剛才的 key 簽名
$ sudo openssl ca -in server/server.csr -cert private/ca.crt -keyfile private/ca.key -out server/server.crt -config "/usr/local/nginx/ca/conf/openssl.conf"
輸出
兩次都輸入 y,server 目錄下有 server.crt 檔案產生。
2.3 用戶端認證的產生2.3.1 建立存放 key 的目錄 users
$ sudo mkdir users
位置 /usr/local/nginx/ca/users。
2.3.2 為使用者建立一個 key
$ sudo openssl genrsa -des3 -out /usr/local/nginx/ca/users/client.key 1024
要求輸入 pass phrase。兩次輸入同一個密碼(比如我這裡輸入 defonds),users 目錄下有 client.key 檔案產生。
2.3.3 為 key 建立一個認證簽章要求 csr 檔案
$ sudo openssl req -new -key /usr/local/nginx/ca/users/client.key -out /usr/local/nginx/ca/users/client.csr
提示輸入 pass phrase,將 2.3.2 步儲存的 pass phrase 輸入後並斷行符號:
要求你輸入和 2.1.2.2 步一樣的那些問題。輸入需要和那一步一致:
這時要求你輸入認證密碼,可以與伺服器憑證一致,比如 defonds,users 目錄下有 client.csr 檔案產生。
2.3.4 使用我們私人的 CA key 為剛才的 key 簽名
$ sudo openssl ca -in /usr/local/nginx/ca/users/client.csr -cert /usr/local/nginx/ca/private/ca.crt -keyfile /usr/local/nginx/ca/private/ca.key -out /usr/local/nginx/ca/users/client.crt -config "/usr/local/nginx/ca/conf/openssl.conf"
輸出
Using configuration from /usr/local/nginx/ca/conf/openssl.conf
Check that the request matches the signature
Signature ok
The Subject‘s Distinguished Name is as follows
countryName :PRINTABLE:‘CN‘
stateOrProvinceName :PRINTABLE:‘Shanghai‘
localityName :PRINTABLE:‘Shanghai‘
organizationName :PRINTABLE:‘Defonds‘
organizationalUnitName:PRINTABLE:‘Dev‘
commonName :PRINTABLE:‘localhost‘
emailAddress :IA5STRING:‘[email protected]‘
Certificate is to be certified until Mar 16 11:47:48 2016 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
兩次都輸入 y,users 目錄下有 client.crt 檔案產生。
2.3.5 將認證轉換為大多數瀏覽器都能識別的 PKCS12 檔案$ sudo openssl pkcs12 -export -clcerts -in /usr/local/nginx/ca/users/client.crt -inkey /usr/local/nginx/ca/users/client.key -out /usr/local/nginx/ca/users/client.p12
要求輸入 client.key 的 pass phrase,輸入 2.3.2 步輸入的 pass phrase 並斷行符號後:
要求輸入 Export Password,這個是用戶端認證的保護密碼,在用戶端安裝認證的時候需要輸入這個密碼。我還是輸入 defonds。users 目錄下有 client.p12 檔案產生。
3. Nginx 配置SSL 的目的是為了保證網路通訊的安全以及資料完整性。所以,如果 tomcat 前面有了 nginx 作為反向 Proxy,那就沒有理由再在 nginx 和 tomcat 之間進行加密傳輸,畢竟二者處於同一內網。
如所示,用戶端通過 SSL 請求過來的訪問被反向 Proxy nginx 接收,nginx 結束了 SSL 並將請求以純 HTTP 提交 tomcat。nginx 配置 nginx.conf 如下:
worker_processes 1;error_log logs/error.log;#error_log logs/error.log notice;#error_log logs/error.log info;#pid logs/nginx.pid;events { worker_connections 1024;}http { include mime.types; default_type application/octet-stream; log_format main ‘[$time_local] $remote_addr - "$request" ‘ ‘$status "$http_user_agent" ‘ ‘"$args"‘; access_log logs/access.log main; sendfile on; #tcp_nopush on; #keepalive_timeout 0; keepalive_timeout 120; client_max_body_size 120m; client_body_buffer_size 128k; server_names_hash_bucket_size 128; large_client_header_buffers 4 4k; open_file_cache max=8192 inactive=20s; open_file_cache_min_uses 1; open_file_cache_valid 30s;upstream tomcat_server {# Tomcat is listening on default 8080 port server 192.168.1.177:8080 fail_timeout=0; } server { listen 443; server_name localhost; ssi on; ssi_silent_errors on; ssi_types text/shtml; ssl on; ssl_certificate /usr/local/nginx/ca/server/server.crt; ssl_certificate_key /usr/local/nginx/ca/server/server.key; ssl_client_certificate /usr/local/nginx/ca/private/ca.crt; ssl_session_timeout 5m; ssl_verify_client on; #開戶用戶端認證驗證 ssl_protocols SSLv2 SSLv3 TLSv1; ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP; ssl_prefer_server_ciphers on; charset utf-8;access_log logs/host.access.log main;#error_page 404 /404.html;# redirect server error pages to the static page /50x.html#error_page 500 502 503 504 /50x.html;location = /50x.html {root html;}location = /favicon.ico {log_not_found off;access_log off;expires 90d;}location /swifton/ {proxy_pass http://tomcat_server;include proxy.conf;} }}
其中,tomcat(本例中和 nginx 部署同台機器) 是 nginx 同一區域網路段的,swifton 是測試 tomcat 項目。proxy.conf 內容:
proxy_redirect off;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_connect_timeout 60;proxy_read_timeout 600;proxy_set_header X-Forwarded-Proto $scheme;
4. Tomcat 配置與 HTTP 代理不同的是,這裡需要通過更改 tomcat 的設定檔來告訴它前面的代理。將 %tomcat%/conf/ 以下部分:
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
修改為
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" scheme="https" proxyName="localhost" proxyPort="443" />
5. 配置驗證5.1 Tomcat 重啟驗證重啟 tomcat,後台日誌沒問題,也可以看到小貓介面。
5.2 Nginx 重啟驗證先關閉運行中的 nginx,如果你已經開啟了的話。
$ sudo ./nginx -t
輸出
nginx: [emerg] unknown directive "ssl" in /usr/local/nginx/conf/nginx.conf:50
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
ssl 模組沒有編譯進來。
切換到步驟 1.2.4 裡的 nginx 安裝目錄 nginx-1.7.10,
$ ./configure --with-pcre=../pcre-8.36 --with-zlib=../zlib-1.2.8 --with-http_ssl_module
$ sudo make
$ sudo make install
Nginx 重裝成功。再次
$ sudo ./nginx -t
提示測試成功。
啟動 nginx。
5.3 客戶訪問 ssl 驗證Google瀏覽器使用 https 訪問原有項目 https://192.168.1.177/swifton,177 是 Nginx 所在伺服器,提示 400 Bad Request(No required SSL certificate was sent):
這是因為 https 雙向驗證需要用戶端安裝認證。windows os 下拿到步驟 2.3.5 產生的認證 client.p12,直接雙擊它,進入 "認證匯入嚮導":
點擊 "下一步":
"要匯入的檔案" 已經為我們選好了,點擊 "下一步":
"私密金鑰保護" 對話方塊輸入 2.3.5 步的 Export Password,點擊 "下一步":
"憑證存放區" 對話方塊,我們使用 Windows 自動儲存,點擊 "下一步":
直接點擊 "完成" 按鈕完成認證匯入。
重啟Google瀏覽器,再次訪問 https://192.168.1.177/swifton,瀏覽器要求我們選擇認證:
選中剛才安裝好的那個認證(localhost(localhost)),點擊 "確定",提示 "隱私權設定錯誤":
這是因為我們伺服器用的是自己簽發的認證。選擇繼續訪問,守得雲開見月明,終於看到久違了的項目登入頁面,成功了:
可以點擊瀏覽器輸入框左側的小鎖表徵圖查看我們匯入的用戶端認證相關資訊:
CentOS 下對 Nginx + Tomcat 配置 SSL 實現伺服器 / 用戶端雙向認證,至此結束。本文樣本所涉及安裝包 openssl-fips-2.0.9.tar.gz、pcre-8.36.tar.gz、zlib-1.2.8.tar.gz、nginx-1.7.10.tar.gz,Nginx 設定檔 nginx.conf、proxy.conf,以及 Tomcat 設定檔 server.xml 都已打包作為部落格附件上傳到 CSDN 資源,有興趣的朋友可以去下載下來參考,:http://download.csdn.net/detail/defonds/8512071。
參考資料
- http://webapp.org.ua/sysadmin/setting-up-nginx-ssl-reverse-proxy-for-tomcat/
- http://serverfault.com/questions/172542/configuring-nginx-for-use-with-tomcat-and-ssl
圖文:CentOS 下對 Nginx + Tomcat 配置 SSL 實現伺服器 / 用戶端雙向認證