2013-02-27 43 views
16

Chúng tôi có một số máy chủ PHP trên EC2 sau ELB. Chúng tôi muốn xác định miền địa phương/khu vực theo địa chỉ IP của khách hàng kết nối với máy chủ của chúng tôi. Vấn đề là các máy chủ PHP chỉ thấy địa chỉ IP của ELB. Chúng tôi muốn xem địa chỉ IP của khách hàng được chuyển qua ELB.Xác định địa chỉ IP của khách hàng Đằng sau Amazon ELB

Trả lời

20

Theo AWS docs, các ELB nên được thiết lập 'X-Forwarded-For' HTTP header mà bảo tồn bản gốc địa chỉ khách hàng ip:

Yêu cầu tiêu đề X-Forwarded-For giúp bạn xác định Địa chỉ IP của một khách hàng. Bởi vì cân bằng tải chặn lưu lượng giữa máy khách và máy chủ, nhật ký truy cập máy chủ của bạn chỉ chứa địa chỉ IP của trình cân bằng tải. Để xem địa chỉ IP của máy khách, hãy sử dụng tiêu đề yêu cầu X-Forwarded-For.

Bạn có thể truy cập nó bằng cách sử dụng mã PHP sau (giả sử apache):

$http_headers = apache_request_headers(); 
$original_ip = $http_headers["X-Forwarded-For"]; 
+4

Nếu bạn quan tâm đến bảo mật, bạn nên ngăn các kết nối đến máy chủ web của mình từ bất kỳ thứ gì ngoài ELB. Nếu không, kẻ tấn công có thể giả vờ là một ELB, đặt tiêu đề này và nói dối bạn về địa chỉ IP từ xa thực sự. http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-elb-security-groups.html –

+2

Lưu ý rằng tiêu đề X-Forwarded-For có thể chứa danh sách địa chỉ IP được phân cách bằng dấu phẩy nếu có nhiều người giao nhận. Cái đầu tiên là IP của máy khách gốc. http://en.wikipedia.org/wiki/X-Forwarded-For#Format – mmindenhall

+4

Trong trường hợp khách hàng cung cấp X-Forwarded-For của riêng mình, nó sẽ là người đầu tiên trong danh sách IP được phân tách bằng dấu phẩy được cung cấp cho bạn ứng dụng. IP thực sự luôn luôn là mục cuối cùng, rõ ràng. –

-2

bạn có thể yêu cầu khách hàng báo cáo địa chỉ IP của mình một cách rõ ràng không? Kiểm tra điều này post.

+0

Không thực sự. Trong một số trường hợp, khách hàng có thể nhấp vào liên kết trong email. Khi lần truy cập đầu tiên vào máy chủ của chúng tôi, chúng tôi cần xác định nội dung nào sẽ hiển thị dựa trên khu vực của họ. – BillR

2

Đây là một vấn đề lớn, vì vậy hãy thử này: D

<?php 
     if (!empty($_SERVER["HTTP_X_FORWARDED_FOR"])) { 
      $real_client_ip = $_SERVER["HTTP_X_FORWARDED_FOR"]; 
     } else { 
      $real_client_ip = $_SERVER["REMOTE_ADDR"]; 
     } 
+0

Điều này giả định rằng bạn tin tưởng khách hàng cung cấp X-Forwarded-For (tức là, vì khách hàng là một cân bằng tải). Mã này thực sự nên kiểm tra REMOTE_ADDR đối với danh sách trắng các IP được chấp nhận hoặc nó mở mã của bạn đến mức dễ bị tổn thương. – ZiggyTheHamster

8

Nếu bạn sử dụng Apache, hãy xem mô-đun mod_remoteip. Nó được bao gồm trong Apache 2.4 và mới hơn, nhưng cũng có thể tìm thấy backports cho 2.2.

Mô-đun ghi đè địa chỉ IP của khách hàng để kết nối với địa chỉ IP người dùng được báo cáo trong tiêu đề yêu cầu được định cấu hình với chỉ thị RemoteIPHeader.

Sau khi được thay thế theo hướng dẫn, địa chỉ IP người dùng được ghi đè này sau đó được sử dụng cho tính năng yêu cầu mod_authz_host Yêu cầu ip, được báo cáo bởi mod_status và được ghi bởi mod_log_config% a và core% a string định dạng. IP khách hàng cơ bản của kết nối có sẵn trong chuỗi định dạng% {c}.

Nói cách khác, bạn có thể đặt tiêu đề để sử dụng (ví dụ: Chuyển tiếp X-For) và IP nào được tin cậy (ví dụ: trình cân bằng tải của bạn). Các IP đáng tin cậy được loại bỏ khỏi tiêu đề và IP không đáng tin cậy đầu tiên được sử dụng làm ứng dụng khách gốc. IP này sau đó được Apache sử dụng nội bộ trong các mô-đun khác, chẳng hạn như để ghi nhật ký, xác thực máy chủ, v.v.

Điều này làm cho nó hữu ích hơn là chỉ xử lý tiêu đề XFF trong PHP, vì mod_remoteip quản lý toàn bộ ngăn xếp, đảm bảo nhật ký truy cập của bạn là chính xác, v.v.

Lưu ý: Ngoài ra còn có mô-đun mod_rpaf là tiền thân của mô-đun này. Nó còn hạn chế hơn nhiều. Ví dụ, nó không thể xử lý các phạm vi ip tin cậy. Bạn cần điều này vì bạn không biết IP của ELB trước đó. Nó cũng không thể xử lý nhiều bước nhảy, chẳng hạn như ELB trước Varnish, trước Apache. Tôi muốn đề nghị bỏ qua các module rpaf và sử dụng remoteip để thay thế.

0

giải pháp tối ưu cho PHP ứng dụng đằng sau AWS ELB:

if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { 
    $commaPos = strrchr($_SERVER['HTTP_X_FORWARDED_FOR'], ','); 
    if ($commaPos === FALSE) $remote_addr = $_SERVER['HTTP_X_FORWARDED_FOR']; 
    else $remote_addr = trim(substr($_SERVER['HTTP_X_FORWARDED_FOR'], $commaPos + 1)); 
} else { 
    $remote_addr = $_SERVER['REMOTE_ADDR']; 
} 

Ghi chú: X-Forwarded-For có thể là một dấu phẩy không gian tách ra danh sách các proxy, với cuối cùng trong danh sách được kết nối với ELB của AWS, và do đó người duy nhất chúng ta có thể tin tưởng là không bị giả mạo.

Các vấn đề liên quan