解決alitomcat中無法獲得https協議的問題
事件:
客戶反饋,為什麼配置https請求,使用request.getScheme()、request.getServerPort(),後台獲取訪問協議和端口的時候還是獲取的http和80。。
用戶架構: CDN+SLB+EDAS應用
其中
CDN使用443端口回源
SLB配置安全證書使用HTTPS公網IP訪問
EDAS使用Alitomcat,server.xml配置
< Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="x-forwarded-for"
remoteIpProxiesHeader="x-forwarded-by"
protocolHeader="x-forwarded-proto"/>
通過用戶溝通已經需求已經比較清晰。
用戶希望在後端ECS處,可以拿到客戶端真實請求的來源IP(x-forwarded-for)和協議(X-Forwarded-Proto),但目前情況是在自建服務器的tomcat上使用正常,換成阿裏服務器後有問題,獲得的仍然是http和80。
排查過程:
- 首先用分離的方式將CDN去除。可將域名解析改為SLB公網IP
- 判斷SLB是否轉發正常。SLB的機製,是將公網入口請求轉化為內網請求傳給ECS,公網入口走https,內網出口走http,X-Forwarded-Proto屬性在SLB中需要單獨開啟“SLB監聽協議”屬性,通過X-Forwarded-Proto頭字段獲取SLB的監聽協議進行轉發給後端。
- 開啟該協議後,驗證ECS是否收到了對應的屬性。可通過在ECS上抓包的方式來識別。
通過tcpdump抓包,看到在訪問SLB的https協議時,X-Forwarded-Proto確實為https
- 那麼為什麼alitomcat上沒有得到對應的https值呢。通過上網查詢。由於internalProxies匹配的內網IP不包含SLB的100段的IP,需要配置internalProxies="100.\d{1,3}.\d{1,3}.\d{1,3}"來識別轉發IP。
如果沒有配置,則默認IP地址為
Regular expression (using java.util.regex) that a proxy's IP address must match to be considered an internal proxy. Internal proxies that appear in the remoteIpHeader will be trusted and will not appear in the proxiesHeader value. If not specified the default value of 10\.\d{1,3}\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3}|169\.254\.\d{1,3}\.\d{1,3}|127\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.1[6-9]{1}\.\d{1,3}\.\d{1,3}|172\.2[0-9]{1}\.\d{1,3}\.\d{1,3}|172\.3[0-1]{1}\.\d{1,3}\.\d{1,3} will be used.
詳細內容可以訪問
https://tomcat.apache.org/tomcat-6.0-doc/api/org/apache/catalina/valves/RemoteIpValve.html
重啟應用後,用SLB訪問Https測試可得:
驗證生效,結果正確。
最後更新:2017-10-17 17:34:35