Nginx多次代理后獲取真實的用戶IP訪問地址

需求:記錄用戶操作記錄,類似如下表格的這樣
PS: 注意無論你的服務是Http訪問還是Https 訪問的都是可以的,我們服務之前是客戶只給開放了一個端口,但是既要支持https又要支持http協議,nginx 是可以通過stream 模塊配置雙協議支持,但是stream塊是四層協議,無法獲取到真實的用戶IP地址,后來把http協議關閉了,才能繼續獲取IP地址,如果有類似的情況可以檢查是不是也有stream塊配置。

用戶名IP地址瀏覽器操作模塊
XXipChrome瀏覽【范洪月】 瀏覽xx功能
XXipChrome瀏覽【范洪月】 瀏覽xx功能

我們是從外網穿透到內網的,真實鏈路如下
外網Nginx

客戶端瀏覽器
外網Nginx
內網Nginx
服務網關

我在本地用Vmware模仿一下正式環境

客戶端瀏覽器192.168.10.43
外網Nginx192.168.10.207
內網Nginx192.168.10.208
服務網關192.168.10.211

開啟Nginx訪問日志 &格式化日志輸出

在這里插入圖片描述
把這兩段打開查看 /logs/access.log
在這里插入圖片描述

日志參數參數含義
$remote_addr遠程訪問IP地址
$remote_user遠程訪問用戶
$time_local日志時間(03/Nov/2020:14:38:06 +0800)
$time_iso8601日志時間(2020-11-03T14:42:53+08:00)
$request請求的URI和HTTP協議
$http_host客戶端請求中的Host請求頭字段的值
$statusHTTP請求狀態
$upstream_statusupstream狀態
$body_bytes_sent發送給客戶端文件內容大小
$http_refererurl跳轉來源
$http_user_agent用戶終端瀏覽器等信息
$ssl_protocolSSL協議版本
$ssl_cipher交換數據中的算法
$request_time整個請求的總時間
$upstream_response_time請求過程中,upstream響應時間
$upstream_response_time請求過程中,upstream響應時間
$http_x_forwarded_for在經過代理或負載均衡器時會逐級添加上每一級的代理服務器的IP地址

修改日志時間格式

雖然**$time_iso8601** 格式也能看時間,但是如果能修改成 yyyy-MM-dd HH:mm:ss 這樣就更合理了,在網上百度以后,

https://blog.csdn.net/shipfei_csdn/article/details/108440538

這個寫的很詳細。
在Server 塊中定義好時間變量

  # 自定義時間變量if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})") {set $year $1;set $month $2;set $day $3;set $hour $4;set $minutes $5;set $seconds $6;}

修改日志時間格式

    log_format  main  '$year$month$day $hour:$minutes:$seconds ' '[$status] ' '【$http_x_forwarded_for $remote_addr $http_host】''[$request_uri] ' ;

增加真實IP追蹤
Nginx01配置

   location /api/{proxy_set_header Host      $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass   http://192.168.10.208/api/;}

Nginx02配置

  location /api/ {proxy_set_header Host      $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass   http://192.168.10.211;}

Nginx03配置

  location /api/ {proxy_set_header Host      $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_pass   http://192.168.10.43:7001/gateway/serviceA/test;}

Nginx03 查看日志運行結果如下

20240229 01:22:45 [200] 【192.168.10.43, 192.168.10.207 192.168.10.208 192.168.10.207】[/gateway/serviceA/test] 

也就是x_forwarded_for 中第一個就是訪問我們客戶端訪問的IP地址了。

Java代碼獲取IP地址代碼

  1. Hutool 中的 UserAgentUtil 可以獲取瀏覽器的類型的
  2. 獲取x-forwarded-for 中的第一個即為原始的訪問IP地址,無論經過多少層代理
    public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();if (StringUtils.equals("127.0.0.1", ipAddress) || StringUtils.equals("0:0:0:0:0:0:0:1", ipAddress)) {InetAddress inet = null;try {inet = InetAddress.getLocalHost();} catch (UnknownHostException var4) {log.error(" 獲取客戶端IP異常 ", var4);}ipAddress = inet.getHostAddress();}}if (ipAddress != null && ipAddress.length() > 15 && ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}return ipAddress;}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/712635.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/712635.shtml
英文地址,請注明出處:http://en.pswp.cn/news/712635.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

2023中國PostgreSQL數據庫生態大會:洞察前沿趨勢,探索無限可能(附核心PPT資料下載)

隨著數字化浪潮的推進,數據庫技術已成為支撐各行各業數字化轉型的核心力量。2023中國PostgreSQL數據庫生態大會的召開,無疑為業界提供了一個深入交流、共同探索PostgreSQL數據庫技術未來發展趨勢的平臺。本文將帶您走進這場盛會,解析大會的亮…

k8s Pod基礎(概念,容器功能及分類,鏡像拉取和容器重啟策略)

目錄 pod概念 Kubernetes設計Pod概念和特殊組成結構的用意 Pod內部結構: 網絡共享: 存儲共享: pause容器主要功能 pod創建方式 pod使用方式 pod分類 pod的容器分類 基礎容器(infrastructure container)&…

加密和簽名的區別及應用場景

原文網址:加密和簽名的區別及應用場景_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹加密和簽名的區別及應用場景。 RSA是一種非對稱加密算法, 可生成一對密鑰(私鑰和公鑰)。(RSA可以同時支持加密和簽名)。 …

元宇宙3D虛擬場景制作深圳華銳視點免費試用

隨著元宇宙興起,3D線上展廳得到了越來越多的關注和應用。基于VR虛擬現實技術的元宇宙3D線上展廳在線編輯系統,更是為企業在展覽展示領域帶來了前所未有的輔助。 高效便捷: 元宇宙3D線上展廳在線編輯無需復雜的施工和搭建過程,只需…

報錯問題解決django.db.utils.OperationalError: (1049, “Unknown database ‘ mxshop‘“)

開發環境:ubuntu22.04 pycharm 功能:django連接使用mysql數據庫,各項配置看似正常 報錯: django.db.utils.OperationalError: (1049, "Unknown database mxshop") 分析檢查原因: Setting的配置文件內&…

gcd+線性dp,[藍橋杯 2018 國 B] 矩陣求和

一、題目 1、題目描述 經過重重筆試面試的考驗,小明成功進入 Macrohard 公司工作。 今天小明的任務是填滿這么一張表: 表有 �n 行 �n 列,行和列的編號都從 11 算起。 其中第 �i 行第 �j 個元素…

GRPC 錯誤碼表

code數描述OK0不是錯誤;成功返回。CANCELLED1操作通常由調用方取消。UNKNOWN2未知錯誤。例如,當從另一個地址空間接收的值屬于此地址空間中未知的錯誤空間時,可能會返回此錯誤。此外,未返回足夠錯誤信息的 API 引發的錯誤可能會轉換為此錯誤。…

ggplot去除背景

在ggplot2中去除背景,通常指的是去除圖表的灰色背景和網格線,使圖表背景變為透明或白色,以及去除或簡化坐標軸的背景。這可以通過調整主題(theme)來實現。ggplot2提供了多種主題設置,可以用來調整圖表的外觀…

Spring MVC 和 Spring Cloud Gateway不兼容性問題

當啟動SpringCloudGateway網關服務的時候,沒注意好依賴問題,出現了這個問題: Spring MVC found on classpath, which is incompatible with Spring Cloud Gateway. 解決辦法就是:刪除SpringMVC的依賴,即下列依賴。 &…

ChatGPT/GPT4科研應用與AI繪圖及論文高效寫作

原文:ChatGPT/GPT4科研應用與AI繪圖及論文高效寫作 第一:2024年AI領域最新技術 1.OpenAI新模型-GPT-5 2.谷歌新模型-Gemini Ultra 3.Meta新模型-LLama3 4.科大訊飛-星火認知 5.百度-文心一言 6.MoonshotAI-Kimi 7.智譜AI-GLM-4 第二:…

【C++從0到王者】第四十六站:圖的深度優先與廣度優先

文章目錄 一、圖的遍歷二、廣度優先遍歷1.思想2.算法實現3.六度好友 三、深度優先遍歷1.思想2.代碼實現 四、其他問題 一、圖的遍歷 對于圖而言,我們的遍歷一般是遍歷頂點,而不是邊,因為邊的遍歷是比較簡單的,就是鄰接矩陣或者鄰接…

《匯編語言》第3版 (王爽)檢測點3.1解析

第三章 檢測點3.1 (1).在Debug中,用“d 0:0 1f”查看內存,結果如下。 下面的程序執行前,AX 0,BX 0,寫出每條匯編指令執行完后相關寄存器中的值。 mov ax,1 ;將1放入AX寄存器中,…

GC如何判定對象已死

GC判定對象已死的2種方法 引用計數法 給對象中添加一個引用計數器,每當有一個地方引用它時,計數器值就加1;當引用失效時,計數器值就減1;Java語言中沒有選用引用計數算法來管理內存,其中最主要的原因是它很…

【零基礎SRC】成為漏洞賞金獵人的第一課:加入玲瓏安全漏洞挖掘班。

我們是誰 你是否對漏洞挖掘充滿好奇?零基礎或有基礎但想更進一步?想賺取可觀的漏洞賞金讓自己有更大的自由度? 那么,不妨了解下我們《玲瓏安全團隊》。 玲瓏安全團隊,擁有多名實力講師,均就職于互聯網頭…

一線互聯網大廠中高級Android面試真題收錄,記一次字節跳動Android社招面試

在開始回答前,先簡單概括性地說說Linux現有的所有進程間IPC方式: 1. **管道:**在創建時分配一個page大小的內存,緩存區大小比較有限; 2. 消息隊列:信息復制兩次,額外的CPU消耗;不合…

指針與malloc動態內存申請,堆和棧的差異

定義了兩個函數print_stack()和print_malloc(),分別演示了兩種不同的內存分配方式:棧內存和堆內存。然后在main()函數中調用這兩個函數,并將它們返回的指針打印出來。 由于print_stack()中的數組c是在棧上分配的,當函數返回后&…

【哈希表算法題記錄】242.有效的字母異位詞

題目鏈接 這題思路比較簡單,考慮到26個小寫字母的ASCII是連續的,那么我們可以設置一個size為26的哈希表record,然后記錄26個字母分別在string中出現的次數。例如,record[0]記錄的是字母‘a’出現的次數。于是我們主要就是要獲得每…

Python裝飾器的使用詳解

目錄 1、函數裝飾器 1.1、閉包函數 1.2、裝飾器語法 1.3、裝飾帶參數的函數 1.4、被裝飾函數的身份問題 1.4.1、解決被裝飾函數的身份問題 1.5、裝飾器本身攜帶/傳參數 1.6、嵌套多個裝飾器 2、類裝飾器 裝飾器顧名思義作為一個裝飾的作用,本身不改變被裝…

Acwing 周賽135 解題報告 | 珂學家 | 反悔堆貪心

前言 整體評價 VP了這場比賽, T3挺有意思的,反悔貪心其實蠻套路的。 A. 買蘋果 思路: 簽到 n, x list(map(int, input().split())) print (n // x)B. 牛群 思路: 分類討論 from collections import Counters input() cnt Counter(s)lists sorte…

WPF 【十月的寒流】學習筆記(2):MVVM中是怎么實現通知的

文章目錄 前言相關鏈接代碼倉庫項目配置代碼初始代碼ViewPersonViewModel 嘗試老辦法通知解決方案ObservableCollectionBindingListICollectionView 總結 前言 我們這次詳細了解一下列表通知的底層是怎么實現的 相關鏈接 十月的寒流 MVVM實戰技巧之:可被觀測的集合…