當我剛接觸 AWS 時,我在執行對文件進行數位簽章的任務時遇到了一個有趣的挑戰,該任務需要客戶的 IP 作為電子簽章的一部分。最初,當第一次實現似乎完美運行時,我感到很興奮。然而,我的興奮是短暫的。在測試過程中,我注意到即使我從不同的機器存取應用程序,也會返回相同的 IP 位址。就在那時,我意識到我收到的 IP 位址不是實際的客戶端 IP,而是負載平衡器的 IP。
這個發現帶領我走上了一條調查和學習的道路。我必須更深入地了解發生了什麼以及如何檢索真實的客戶端 IP。在這篇部落格中,我將分享我的經驗,並提供有關如何使用 AWS Lambda 和 Python 實現此目標的全面指南,確保您在使用應用程式負載平衡器 (ALB) 時能夠準確捕獲客戶端的 IP 位址。
當客戶端透過 ALB 向您的應用程式發出請求時,負載平衡器充當中介。因此,您的應用程式看到的 IP 位址是 ALB 的 IP 位址,而不是客戶端的 IP 位址。為了解決這個問題,ALB 在 X-Forwarded-For HTTP 標頭中包含客戶端的 IP。如果請求通過多個代理,此標頭可以包含多個 IP 位址。
這是我們需要處理的:
擷取客戶端IP:擷取並解析X-Forwarded-For標頭。
處理多個IP:即使涉及多個代理,也確保我們獲得正確的客戶端IP。
由於潛在的安全風險,應謹慎使用 X-Forwarded-For 標頭。只有由網路內受到適當保護的系統所添加的條目才被認為是可信的。這確保了客戶端IP不被篡改且可靠。
AWS Lambda 是一種無伺服器運算服務,讓您無需預置或管理伺服器即可執行程式碼。 Python 以其簡單性和可讀性,是在 Lambda 函數中處理此任務的絕佳選擇。
AWS Lambda Function:處理傳入請求的核心函數。
Application Load Balancer (ALB):將請求轉送至 Lambda 函數的負載平衡器。
首先,請確保您的 Lambda 函數已設定並與 ALB 整合。如果需要,請遵循 AWS 的官方指南:使用 Lambda 函數作為應用程式負載平衡器的目標。
讓我們深入研究 Lambda 函數的 Python 程式碼。此函數將從 X-Forwarded-For 標頭中提取客戶端的 IP 位址。
import json def lambda_handler(event, context): # Extract the 'X-Forwarded-For' header x_forwarded_for = event['headers'].get('x-forwarded-for') if x_forwarded_for: # The first IP in the list is the client's IP client_ip = x_forwarded_for.split(',')[0] else: # Fallback if header is not present client_ip = event['requestContext']['identity']['sourceIp'] # Log the client IP print(f"Client IP: {client_ip}") # Respond with the client IP return { 'statusCode': 200, 'body': json.dumps({'client_ip': client_ip}) }
提取標頭:從傳入請求中擷取 X-Forwarded-For 標頭。
解析Header:取第一個IP,代表客戶端的原始IP。
回退機制:如果標頭不存在,則使用請求上下文中的來源 IP。
記錄與回應:記錄並傳回客戶端的IP以進行驗證。
要求:
{ "headers": { "x-forwarded-for": "203.0.113.195, 70.41.3.18, 150.172.238.178" }, "requestContext": { "identity": { "sourceIp": "70.41.3.18" } } }
回覆:
{ "client_ip": "203.0.113.195" }
識別 ALB 後面的 AWS Lambda 函數中的實際客戶端 IP 需要仔細處理 X-Forwarded-For 標頭。這種方法可確保準確的 IP 日誌記錄並增強應用程式個人化和保護使用者互動的能力。
AWS ALB 文件:
AWS Lambda 中的 Python:
HTTP 標頭解釋
免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。
Copyright© 2022 湘ICP备2022001581号-3