1. 程式人生 > >windows下搭建Nginx+Tomcat+Https

windows下搭建Nginx+Tomcat+Https

最近專案需要使用https,架構上使用了 Nginx +tomcat 叢集,找了網上一些別人的方法,經過多次失敗,終於搭建成功。特記錄一下,供以後再次使用及他人使用參考。

由於我是在本地做測試,所以通過Openssl自己生成證書,正式專案使用需要向管理機構申請正式的證書。首先我們安裝生成證書的Openssl軟體。

步驟:

1. 安裝Openssl

  下載完成後,進行安裝,我安裝在了 C:\wnmp\OpenSSL-Win64資料夾中。

2. 安裝ActivePerl (此軟體目的為了解析pl檔案,部分系統不安裝也可以實現本教程的功能,安裝該軟體目的為了學習perl。)。

3. 配置環境變數

  在環境變數中新增環境變數

    變數名: OPENSSL_HOME            變數值:C:\wnmp\OpenSSL-Win64\bin;        (變數值為openssl安裝位置)

    在path變數結尾新增如下 : %OPENSSL_HOME%;

4. 生成證書   

  (1) 首先在 nginx安裝目錄中建立ssl資料夾用於存放證書。比如我的檔案目錄為 C:\wnmp\nginx\ssl

     以管理員身份進入命令列模式,進入ssl資料夾。 命令為: cd  c:/wnmp/nginx/ssl

  (2) 建立私鑰

     在命令列中執行命令: openssl genrsa -des3 -out lee.key 1024     

(lee檔名可以自定義),如下圖所示:

      

      輸入密碼後,再次重複輸入確認密碼。記住此密碼,後面會用到。

  (3)建立csr證書

     在命令列中執行命令:  openssl req -new -key lee.key -out lee.csr    (key檔案為剛才生成的檔案,lee為自定義檔名)

      

       如上圖所示,執行上述命令後,需要輸入資訊。輸入的資訊中最重要的為 Common Name,這裡輸入的域名即為我們要使用https訪問的域名。

       以上步驟完成後,ssl資料夾內出現兩個檔案:

  (4)去除密碼。

     在載入SSL支援的Nginx並使用上述私鑰時除去必須的口令,否則會在啟動nginx的時候需要輸入密碼。


     複製lee.key並重命名為lee.key.org 

     可以使用此命令列,也可以使用滑鼠操作     copy lee.key lee.key.org

     去除口令,在命令列中執行此命令:  openssl rsa -in lee.key.org -out lee.key  (lee為自定義檔名)

     如下圖所示,此命令需要輸入剛才設定的密碼。

      

   (5)生成crt證書

     在命令列中執行此命令: openssl x509 -req -days 365 -in lee.csr -signkey lee.key -out lee.crt  (lee為自定義檔名)

      

      證書生成完畢,ssl資料夾中一共生成如下4個檔案,我們需要使用到的是lee.crt和lee.key。

      

5. 修改位於nginx安裝目錄下的conf目錄的nginx.conf檔案

# HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;


    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;


    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;


    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;


    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

修改為:

    upstream www.test.com{
		server www.test.com:8080;
		server www.test.com:8088;
	}
	
    server {
	listen       80;
        server_name  www.test.com;
		
		 #為一個server{......}開啟ssl支援  
		ssl                  on;  


        ssl_certificate      ../ssl/lee.crt;
        ssl_certificate_key  ../ssl/lee.key;

        #ssl_session_cache    shared:SSL:1m;
        #ssl_session_timeout  5m;
	#ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
        #ssl_ciphers ECDH:AESGCM:HIGH:!RC4:!DH:!MD5:!3DES:!aNULL:!eNULL;
        #ssl_prefer_server_ciphers  on;


	#讓http請求重定向到https請求   
        #error_page 497  https://$host$uri?$args; 


        location / {
            root   html;
            index  index.html index.htm;
			
	    proxy_pass http://www.test.com;   
			
	    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_set_header X-Forwarded-Proto  $scheme;
			
	    proxy_connect_timeout       1;
	    proxy_read_timeout          1;
	    proxy_send_timeout          1;
        }
    }

由於此處在本地做實驗,我在C:\Windows\System32\drivers\etc的hosts.ics檔案添加了對映:127.0.0.1 www.jyfeng.com,將www.jyfeng.com當做域名。也可直接使用localhost,而不需在hosts檔案新增對映。但如果是伺服器正式使用,那麼需配置伺服器申請的域名。

6. 修改tomcat的conf目錄下的server.xml檔案

<Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
      </Host>
</Engine>
修改為
<Engine name="Catalina" defaultHost="localhost">
      <Realm className="org.apache.catalina.realm.LockOutRealm">
        <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
               resourceName="UserDatabase"/>
      </Realm>

      <Host name="localhost"  appBase="webapps"
            unpackWARs="true" autoDeploy="true">
        <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
               prefix="localhost_access_log." suffix=".txt"
               pattern="%h %l %u %t "%r" %s %b" />
	<Valve className="org.apache.catalina.valves.RemoteIpValve"  
		remoteIpHeader="X-Forwarded-For"  
		protocolHeader="X-Forwarded-Proto"  
		protocolHeaderHttpsValue="https"/>  
      </Host>
</Engine>

解析:

https配置:在server標籤裡配置以下資訊

listen       80;
server_name  www.test.com;
		
 #為一個server{......}開啟ssl支援  
ssl                  on;  

ssl_certificate      ../ssl/lee.crt;
ssl_certificate_key  ../ssl/lee.key;

這裡我將lee.crt和lee.key放在nginx安裝目錄下,也可放其它位置並使用絕對路徑訪問。

負載均衡配置:在http標籤裡配置以下資訊

upstream www.test.com{
    server www.test.com:8080;
    server www.test.com:8088;
}

本地配置了埠分別為8080、8088的兩個tomcat,以上配置會讓nginx將www.test.com的請求輪詢轉發到兩臺tomcat上。注意,upstream後邊的www.test.com要跟proxy_pass的http:www.test.com一致。假如proxy_pass為http:localhost,那麼upstream為localhost。

如果tomcat 和nginx 雙方沒有配置X-Forwarded-Proto tomcat就不能正確區分實際使用者是http 還是https,導致tomcat 裡配置的靜態資源被認為是http而被瀏覽器攔截,request.getScheme()總是 http,而不是實際的http或https。所以需要給nginx跟tomcat分別做一下配置:

nginx配置:在location標籤裡配置以下資訊

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_set_header X-Forwarded-Proto  $scheme;

tomcat配置:配置server.xml的Engine模組下host標籤新增一個value

<Valve className="org.apache.catalina.valves.RemoteIpValve" 
remoteIpHeader="X-Forwarded-For" 
protocolHeader="X-Forwarded-Proto" 
protocolHeaderHttpsValue="https"/> 

在測試中發現一個問題,如果有一臺tomcat關閉了,那麼nginx仍然在轉發請求時,有部分請求會失敗。原因是nginx部分請求轉發到這個tomcat,但沒有響應,而nginx預設等待響應時間為60秒,過了等待響應時間沒有收到響應,才轉發給另一臺。所以這裡需要在nginx的conf檔案的location做如下配置:

proxy_connect_timeout       1;
proxy_read_timeout          1;
proxy_send_timeout          1;

這樣如果超過一秒未響應,會轉發給另一臺tomcat。但這樣假設一臺伺服器掛了,會有部分請求的響應時間增加一秒,體驗上有些不好。但目前能找到的解決辦法只有這個,不知為什麼nginx不會直接剔除這個tomcat,目前還沒找到原因,可能還需要其它配置,如有知道的道友,望不吝賜教。

參考:

https搭建: https://www.cnblogs.com/vincent-li666/p/5851463.html

Nginx SSL+tomcat叢集: http://blog.csdn.net/vfush/article/details/51086274