Nginx獲取真實使用者IP
宣告:本文參考http://www.ttlsa.com/nginx/nginx-get-user-real-ip/並做了一些補充講解,希望會更加清晰明瞭~
隨著nginx的迅速崛起,越來越多公司將apache更換成nginx. 同時也越來越多人使用nginx作為負載均衡, 並且代理前面可能還加上了CDN加速,但是隨之也遇到一個問題:nginx如何獲取使用者的真實IP地址,如果後端是apache,請跳轉到<apache獲取使用者真實IP地址>,如果是後端真實伺服器是nginx,那麼繼續往下看。
例項環境:
使用者IP 120.22.11.11
CDN前端 61.22.22.22
CDN中轉 121.207.33.33
公司NGINX前端代理 192.168.50.121(外網121.207.231.22)
1、使用CDN自定義IP頭來獲取
假如說你的CDN廠商使用nginx,那麼在nginx上將$remote_addr賦值給你指定的頭,方法如下:
//如上,後端將會收到remote_user_ip的http頭,有些人可能會挑錯了,說我設定的頭不是remote-user-ip嗎,怎麼寫成了remote_user_ip,是不是作者寫錯了.請參考文章:<nginx反向代理proxy_set_header自定義header頭無效>
訪問getRemoteUserIP.php,結果如下:
注:這裡$remote_addr是nginx的變數,一般情況是,是報文傳送方的IP地址,如果傳送方為proxy,那麼這裡就是proxy的ip,而非使用者的真實ip.
注意:這裡面會有一個問題,就是所謂的XFF欺騙,當用戶直接訪問後端的時候,並且他偽造了HTTP報頭REMOTE_USER_IP,那麼後端獲取到的,將是一個虛假的使用者IP,這個時候可能會產生一些安全問題。如果可以,建議的做法是:後端服務不允許對外部使用者訪問,最前端的代理,proxy_set_header xxxxx $remote_addr;這樣就能解決欺騙,因為$remote_addr獲取的是使用者IP資料包中的IP,而非偽造的HTTP報文首部。
2、通過HTTP_X_FORWARDED_FOR獲取IP地址
一般情況下CDN伺服器都會傳送HTTP_X_FORWARDED_FOR頭。而且會用proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
這裡,$proxy_add_x_forwarded_for是一個神奇的變數,假如接收到的報文已經含有X-FORWARDED-FOR首部,那麼nginx將在後面新增上$remote_addr(也就是傳送者的ip地址在最後),因此後端的真實伺服器獲取HTTP_X_FORWARDED_FOR頭,擷取字串第一個不為unkown的IP作為使用者真實IP地址, 例如:
120.22.11.11, 61.22.22.22, 121.207.33.33,192. 168.50.121(使用者IP,CDN前端IP,CDN中轉,公司NGINX代理)
getFor.php
訪問getFor.php結果如下:
如果你是php程式設計師,你獲取第一個不為unknow的ip地址,這邊就是120.22.11.11.
同理,為防止XFF欺騙,除了第一層代理,後面的多禁止普通使用者訪問,第一層代理,用$remote_addr來設定pass X-Forwarded-For即可。
3.使用nginx自帶模組realip獲取使用者IP地址
有些時候,中間或者後端的代理,都要能夠被普通使用者訪問,也或者在nginx日誌中,想讓$remote_adrr配置的格式,能顯示外界使用者的ip,這個時候,就要使用realip模組了。
安裝nginx之時加上realip模組,我的引數如下:
真實伺服器nginx配置