nginx配置https,反向代理給tomcat

nginx配置https反向代理給tomcat(tomcat無需配https)

最終結果:一臺機器中的nginx將所有https請求全部代理給tomcat,將80端口的http請求永久重定向到https路徑,實現全站的https。防火墻Firewall開放https和http服務,這樣用戶只能通過nginx訪問網站,無法直接訪問到tomcat,避免了用戶直接用http訪問tomcat。

  • 關于nginx的安裝和centos7的firewall防火墻的使用可以看我之前的文章

  • 使用openssl生成私鑰和證書,編譯nginx的https模塊時使用的就是openssl

openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

req是openssl證書請求的子命令
-newkey rsa:2048 -keyout private_key.pem 表示生成私鑰(PKCS8格式)
-nodes 表示私鑰不加密,若不帶參數將提示輸入密碼
-x509表示輸出證書
-days36500 為100年有效期,此后根據提示輸入證書擁有者信息
-keyout 代表私鑰全路徑
-out 代表證書全路徑
  • 編輯nginx的配置文件,參考的nginx官網中對https模塊配置的說明,將所有https的請求都通過http反向代理給tomcat,這里僅保留了最核心的功能配置,ssl的緩存優化設置刪掉了。如果不加其中的四個頭信息,在tomcat中無法獲知到底請求到底是從哪來的
server {
    listen              443 ssl;
    server_name         localhost;
    ssl_certificate     /usr/local/nginx-1.12.2/nginx1/ssl/nginx.crt;
    ssl_certificate_key /usr/local/nginx-1.12.2/nginx1/ssl/nginx.key;
    location / {
        proxy_pass   http://localhost:8080;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
server {
    listen       80;
    server_name  localhost;
    # 返回301狀態碼,永久重定向
    rewrite ^(.*)$  https://$host$1 permanent;
}
  • 這樣配置完之后其實已經實現了全站https,但是在tomcat中使用request.getRequestURL()時,顯示的是http開頭的路徑,因為tomcat接收到的都是nginx的http請求。需要配置tomcat的server.xml,在engine節點下加入:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
       remoteIpHeader="x-forwarded-for"
       protocolHeaderHttpsValue="https"
       protocolHeader="x-forwarded-proto" />
//源碼如下:  
if (protocolHeader != null) {  
    String protocolHeaderValue = request.getHeader(protocolHeader);  
    if (protocolHeaderValue == null) {  
        // don't modify the secure,scheme and serverPort attributes  
        // of the request  
    } else if (protocolHeaderHttpsValue.equalsIgnoreCase(protocolHeaderValue)) {  
        request.setSecure(true);  
        // use request.coyoteRequest.scheme instead of request.setScheme() because request.setScheme() is no-op in Tomcat 6.0  
        request.getCoyoteRequest().scheme().setString("https");  
          
        request.setServerPort(httpsServerPort);  
    } else {  
        request.setSecure(false);  
        // use request.coyoteRequest.scheme instead of request.setScheme() because request.setScheme() is no-op in Tomcat 6.0  
        request.getCoyoteRequest().scheme().setString("http");  
          
        request.setServerPort(httpServerPort);  
    }  
}  
  • 修改AccessLogValve,否則access日志中的ip都是nginx的ip,%{X-Real-IP}i中的i代表從input中取值,取請求頭中X-Real-IP的值
<!--
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
       prefix="localhost_access_log" suffix=".txt"
       pattern="%h %l %u %t &quot;%r&quot; %s %b" />
-->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
       prefix="localhost_access_log" suffix=".txt"
       pattern="%{X-Real-IP}i %l %u %t &quot;%r&quot; %s %b" />
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容