Request.UserHostAddress記錄IP地址問題(內(nèi)網(wǎng)IP)
今天遷移至阿里云后,出現(xiàn)了一個問題,有些站點記錄的訪問者IP全是阿里云的兩個內(nèi)網(wǎng)IP,在程序中是通過Request.UserHostAddress讀取IP地址的,之前從沒遇到過這個問題,很是奇怪。經(jīng)過分析比較發(fā)現(xiàn),出現(xiàn)這些問題的站點都是跑在使用了負(fù)載均衡的Web服務(wù)器上(使用負(fù)載均衡,也是這次遷移在性能上的一處提升),這個問題應(yīng)該與負(fù)載均衡有關(guān)。
今天遷移至阿里云后,出現(xiàn)了一個問題,有些站點記錄的訪問者IP全是阿里云的兩個內(nèi)網(wǎng)IP,而程序中是通過Request.UserHostAddress讀取IP地址的,之前從沒遇到過這個問題,很是奇怪。經(jīng)過分析比較發(fā)現(xiàn),出現(xiàn)這些問題的站點都是跑在使用了負(fù)載均衡的Web服務(wù)器上(使用負(fù)載均衡,也是這次遷移在性能上的一處提升),這個問題應(yīng)該與負(fù)載均衡有關(guān)。
于是,上阿里云網(wǎng)站的管理控制臺查看了一下負(fù)載均衡的相應(yīng)設(shè)置,發(fā)現(xiàn)了線索,見下圖:
原來負(fù)載均衡器在向Web服務(wù)器轉(zhuǎn)發(fā)請求時,將真實IP存儲在服務(wù)器變量X-Forwarded-For中,而Web服務(wù)器中執(zhí)行的Request.UserHostAddress實際是從服務(wù)器變量REMOTE_ADDR中獲取IP地址的值,由于收到的請求是負(fù)載均衡器轉(zhuǎn)發(fā)過來的,所以REMOTE_ADDR中存儲的是負(fù)載均衡器的IP。要解決這個問題,需要改為通過Request.ServerVariables["HTTP_X_FORWARDED_FOR"]讀取。當(dāng)知道這個原因時,條件反射地就想馬上動手——將代碼中的Request.UserHostAddress改為Request.ServerVariables["HTTP_X_FORWARDED_FOR"]。但是,準(zhǔn)備動手時,有些猶豫了,要改的地方不少。。。開始是沖動占上風(fēng),這時懶惰開始向沖動發(fā)起進(jìn)攻。
最終懶惰戰(zhàn)勝了沖動,冷靜下來思考有沒有更好的解決方法。很快就想到了,這個場景正是HTTP Module可以用武的地方,只要在HTTP Module中把ServerVariables["REMOTE_ADDR"]的值改為ServerVariables["HTTP_X_FORWARDED_FOR"]的值,不用改一行代碼,Request.UserHostAddress就能獲取到正確的IP。的確是一個更好的解決方法,于是問題變成了怎么寫這樣的HTTP Module?
懶惰繼續(xù)占著上風(fēng),去網(wǎng)上找找有沒有現(xiàn)成的HTTP Module,還真有(X-Forwarded-For HTTP Module For IIS7),而且是鼎鼎大名的F5負(fù)載均衡器的生產(chǎn)廠商 F5 Networks, Inc. 的開發(fā)人員開發(fā)的,名叫F5XFFHttpModule,2009年發(fā)布的,基于ISAPI(非托管的)。原以為通過它就能解決問題,而殘酷的現(xiàn)實是這個HTTP Module在我們的IIS上怎么也加載不了,而且會引起整個站點無法正常訪問。又繼續(xù)找,網(wǎng)上多數(shù)提到的還是這個HTTP Module,沒找到更好的。
找現(xiàn)成的HTTP Module的懶惰想法沒能成行,但懶惰依然癡心不改,冒出了一個更加懶惰的想法——是不是可以不用另外安裝專門的HTTP Module,用現(xiàn)有的Url Rewrite Module來解決這個問題呢(Web服務(wù)器已經(jīng)安裝有這個Module)?借助Url Rewrite Module修改ServerVariables["REMOTE_ADDR"]的值。根據(jù)這個懶惰的想法竟然很快在網(wǎng)上找到一篇博文——如何讓在Reverse Proxy 之後的網(wǎng)站正常運(yùn)行(URL Rewrite),根據(jù)這篇博文成功地以懶惰的方式解決了問題。
下面是具體的操作步驟:
1. 如果IIS上沒有安裝Url Rewrite Module,安裝它(下載地址);
2. 在IIS根節(jié)點或某個站點中打開Url Rewrite Module;
3. 在右側(cè)的Actions中點擊View Server Variables...
4. 點擊Add,添加名為REMOTE_ADDR的服務(wù)器變量
5. Back to Rules,添加一條下圖所示的規(guī)則
這條規(guī)則的作用就是將每個請求中ServerVariables["REMOTE_ADDR"]的值替換為ServerVariables["HTTP_X_FORWARDED_FOR"] 的值。
applicationHost.config中的對應(yīng)配置如下:
<rewrite> <allowedServerVariables> <add name="REMOTE_ADDR" /> </allowedServerVariables> <globalRules> <rule name="HTTP_X_Forwarded_For-to-REMOTE_ADDR" enabled="true"> <match url=".*" /> <serverVariables> <set name="REMOTE_ADDR" value="{HTTP_X_Forwarded_For}" /> </serverVariables> <action type="None" /> <conditions> <add input="{HTTP_X_Forwarded_For}" pattern="^$" negate="true" /> </conditions> </rule> </globalRules> </rewrite>
移花接木,借花獻(xiàn)佛,這就是我們找到的解決這個問題的最簡單的方法。
【注意事項】
添加該URL重寫規(guī)則會造成IIS內(nèi)核模式緩存不工作,詳見微軟的坑:Url重寫竟然會引起IIS內(nèi)核模式緩存不工作。
相關(guān)文章
Window Server2016 AD域的創(chuàng)建的方法步驟
本文主要介紹了Window Server2016 AD域的創(chuàng)建的方法步驟,文中通過圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01服務(wù)器網(wǎng)站分離 給每個IIS站點建立一個用戶
服務(wù)器網(wǎng)站分離 給每個IIS站點建立一個用戶...2007-11-11IIS7 配置大全(ASP.NET 2.0, WCF, ASP.NET MVC,php)
IIS7.0版本出來之后,確實功能上比以前的版本功能要強(qiáng)大一些,兼容性也比較好,但是配置起來卻有一點麻煩,本文就是為大家介紹一下如何在iis7.0中配置ASP、PHP環(huán)境和win2008的共享配置2013-06-06Windows?Server?2012?基于iis的流媒體服務(wù)器的搭建圖文方法
IIS?Live?Smooth?Streaming(實時平滑流式處理)是微軟下一代流媒體解決方案。該技術(shù)是在IIS?web中集成媒體傳輸平臺IIS?media?services,實現(xiàn)利用標(biāo)準(zhǔn)?HTTP?Web?技術(shù)以及高級?Silverlight?功能,確保在互聯(lián)上傳輸質(zhì)量最佳、播放流暢音視頻節(jié)目2023-06-06kangle web服務(wù)+easypanel主機(jī)控制面板快速搭建網(wǎng)站和數(shù)據(jù)庫以及管理空間詳細(xì)教程
這篇文章主要介紹了kangle web服務(wù)+easypanel主機(jī)控制面板快速搭建網(wǎng)站和數(shù)據(jù)庫以及管理空間詳細(xì)教程,需要的朋友可以參考下2014-11-11