怎麼獲取乙個客戶端ip ? 我想這個問題,在網上遍地都是答案!
而且多半是像下面這樣:
我也沒說要去研究這玩意,我只是不想重複造輪子,然後找到了**倉庫裡有這麼一段**,所以,我就用來去獲取ip了!
測試環境一切ok。然後稀拉拉地,上線了!
嘿,一上線之後,發現了資料庫ip欄位竟然有兩個ip: 10.11.0.6, 202.116.0.83 。
好嘛,一看就知道是怎麼回事了,這個使用者的請求是通過**進來的,而**只是一種很正常的**行為,所以必須處理這種情況!
由於原來我設定的ip欄位大小為varchar(32), 所以裝下這兩個ip,是松的事! 大概查了下日誌,並沒有發現什麼異常!
我想著吧,一般的使用者也就是一級**下,就差不多了。所以應該不會有什麼問題,這個問題留給下個版本修復吧!
我就這麼想著,玩去了。
然後,就被郵件報警了!資料庫插入失敗!
媽蛋,該來的始終要來!我還是太年輕了。
有一句叫: 如果你發現有個問題可能會發生,那麼它就一定會發生!
不要僥倖,沒人能跑得掉!
修復辦法自然簡單到沒朋友,擷取第乙個',' 前的ip就行了!
//多級**問題修復
if (ip.indexof(',') > 0)
return
ip; }
好了,問題解決了,警告咱們要有敬畏之心。
下面,咱們來看看多級**的ip是怎麼回事?
在 nginx 中,咱們可以這麼設定:
location /api這樣的話,後續服務端就可以通過獲取 x-forwarded-for 來進行獲取所有的**ip位址鏈了!
格式為: x-forwarded-for:10.11.247.1, 10.11.38.131, 10.11.255.1 ...
也就是說 x-forwarded-for 是呈疊加的方式的,所以,我們應該只需要取到 第乙個ip 就可以了!
事實上,x-forwarded-for 是可以偽造的。
比如: curl -h "x-forwarded-for:11.11.22.22"
可以看到,確實很容易就進行偽造了。而按照後端**伺服器的設定,其只會往該header裡新增自己的值,所以,如果此時咱們按照獲取第乙個值為ip,也就判斷失誤了。不過這種失誤,一般我們還是可以接受的。不過有的場景就不適用了,比如我們通過ip來做許可權管理時!所以,在做ip白名單時,還要考慮實際情況而行了!
好了,看得出通過**標識獲取ip是不可靠的,那麼,有沒有一種可靠的獲取ip的方式呢?
其實是乙個值是不可以改的:remote_addr. 這個字段源於 tcp/udp 請求中,就會帶有源位址,目標位址!
remote_addr 是你的客戶端跟你的伺服器「握手」時候的ip。但是如果你使用了「匿名**」,remote_addr將顯示**伺服器的ip。
所以,remote_addr 雖然是不可改的,但是它卻只能代表一級伺服器ip,而面對現在複雜的網路環境,那是太無能為力了!
所以,沒辦法,還得通過約定的變數來,而這個變數又要依賴於使用的**設定了。如上!雖然可以偽造,但是至少絕大部分是對的!
最後,給乙個 tcp 傳送資料樣例( src -> dst):
獲取客戶端ip
1.統計訪問者ip位址 2.設定黑名單,黑名單的使用者不可以訪問聊天室。內容提要 這種情況下同樣透露了客戶端是使用了 伺服器 但編造了乙個虛假的隨機ip 220.4.251.159 代替客戶端的真實 ip來欺騙它 獲取客戶端 ip其實不是個簡單的活兒 因為存在 ip欺騙 和 問題 所以獲取客戶端的 ...
獲取客戶端IP位址
title generating test data author wufeng4552 date 2009 09 23 10 34 02 功能 獲客戶 ip位址 if object id getclientip isnot null drop proc getclientip go create ...
客戶端獲取IP位址
string ip request.getheader x forwarded for string regex 2 0 4 d 25 0 5 01 d d?2 0 4 d 25 0 5 01 d d?if ip null ip.length 0 ip.equalsignorecase locali...