Nginx 不受CDN 服務影響獲取訪客真實IP
獲取和記錄站點訪客的真實IP 對於站點日誌的分析和安全策略的指定很有幫助,Nginx 默認的日誌記錄獲取到的IP 地址如果站點啟用了CDN 服務,那麼這裡的IP 地址都是CDN 服務器節點的IP 地址了,並不是用戶訪客的IP 地址(如圖1),這時候分析Nginx 日誌看到的數據就不是很真實了,影響判斷呀!今天就給大家分享一個Nginx 不受CDN 服務影響獲取訪客真實IP 的方法。
這個方法是完全基於Nginx的,主要表現在Nginx的日誌記錄裡的,WordPress、Typecho博客平台下獲取訪客真實IP可以參考『總是忘了CDN後評論用戶的真實IP地址獲取問題』一文的方法,這段代碼是通用的好像,只要是PHP就可以使用的。
圖 1
從圖1裡可以看到Nginx日誌裡記錄的183.131.214.25、59.56.78.45等等這些IP地址基本上都是CDN服務的節點IP,這樣的統計結果很明顯混亂不堪毫無分析價值了都。好在以前折騰“Nginx限制單個IP的並發連接數/速度”的時候知道通過map指令繞過CDN獲取訪客真實IP(可參考哦『Nginx限制單個IP的並發連接數改進適配開啟CDN站點』一文),由此讓Nginx日誌記錄訪客真實IP不受CDN服務影響的方法也就出來了,只需要在你的Nginx的配置文件nginx.conf裡添加如下配置代碼獲取訪客真實IP並賦值到一個變量:
- #獲取用戶真實IP,並賦值給變量$clientRealIP
- map $http_x_forwarded_for $clientRealIp {
- “” $remote_addr ;
- ~^(?P<firstAddr>[0-9\.]+),?.*$ $firstAddr ;
- }
然後在指定Nginx日誌格式的log_format裡替換$remote_addr為上面的$clientRealIP的變量即可,修改後如下:
- #日誌中記錄真實IP 地址,替換$remote_addr 為上面的$clientRealIP.
- log_format main ‘ $clientRealIP – $remote_user [ $time_local ] “$request” ‘
- ‘ $status $body_bytes_sent $brotli_ratio “$http_referer” ‘
- ‘ “$http_user_agent” ‘;
最後為了讓這個Nginx 日誌格式配置生效,在站點日誌配置文件裡採用這個日誌格式生成日誌即可,配置代碼如下:
- access_log /home/wwwlogs/www.xxxxxxxx.com.log main;
注意access_log 這段最後的main 哦,這裡要跟上面的日誌格式對應的才能生效哦,記得要修改XXXXX 為你的站點域名或者站點日誌文件名稱哦。
重啟一下Nginx 生效配置,這時候查看Nginx 日誌文件是不是訪客IP 都是真實IP 了,不再是CDN 節點IP 了。要驗證日誌實時輸出才可以看到確切效果,如下截圖:
可以看到,日誌記錄的訪客IP 已經都是訪客IP 了,不再是千篇一律的CDN 節點IP 了,大功告成!以後分析日誌原始數據就準確了,再也不會發生屏蔽某個IP 後造成誤傷CDN 節點的事兒了,同時對於那些惡意掃描、注入的請求的IP 也可以有的放矢來應對了。
這個方法最大的優點就是幾乎不會增加任何性能負載,也不依賴任何第三方模塊,完全是採用Nginx 內置命令來解決的,已經用這個方法多次獲取到惡意請求、惡意注入、惡意攻擊者的真實IP 採取了相應的防禦策略,總之效果還是非常不錯的,使用本地日誌分析軟件的時候統計結果也更加的精準了許多