2010-05-19 4 views
10

Tôi muốn, ví dụ: chặn mọi IP từ cơ sở 89.95 (89.95. .). Tôi không có các tệp .htaccess trên máy chủ của mình, vì vậy tôi sẽ phải làm điều đó với PHP.Chặn khối IP cụ thể khỏi trang web của tôi bằng PHP

if ($_SERVER['REMOTE_ADDR'] == "89.95.25.37") die(); 

Sẽ chặn IP cụ thể. Làm thế nào tôi có thể chặn toàn bộ khối IP?

Cảm ơn bạn rất nhiều.

Trả lời

12

Hãy thử strpos()

if(strpos($_SERVER['REMOTE_ADDR'], "89.95") === 0) 
{ 
    die(); 
} 

Nếu bạn nhận thấy, các nhà điều hành === đảm bảo rằng các 89.95 là tại khởi điểm của địa chỉ IP. Điều này có nghĩa là bạn có thể phân tách nhiều địa chỉ IP theo ý muốn, và nó sẽ chặn bất kể số nào đến sau nó.

Ví dụ, tất cả trong số này sẽ bị chặn:

89,95 ->89.95.12.34, 89.95.1234.1, 89.95.1.1
89.95.6 ->89.95.65.34, 89.95.61.1, 89.95.6987

(một số những không phải là địa chỉ IP hợp lệ)

+0

hehe, tôi ngạc nhiên rằng ' strpos' ở đây hoạt động nhanh hơn 'substr' – zerkms

+0

@zerkms nó không thực sự đáng ngạc nhiên -' strpos' có thể trở lại ngay lập tức nếu thử nghiệm thất bại, và không phải làm bất kỳ chuỗi sao chép hoặc phân bổ. Ngoài ra, tôi chỉ muốn lưu ý rằng hành vi thay đổi nếu bạn chuyển '===' thành '==', vì vậy đừng làm vậy. Sử dụng ba dấu bằng. – gnud

+0

@gnud: cho chuỗi dài strpos sẽ chậm hơn, chỉ vì nó nên lặp qua toàn bộ chuỗi để tìm kiếm kim. và tôi biết sự khác biệt của '===' và '==' là gì. – zerkms

1

Tạo chuỗi con :) Ví dụ để chặn 89.95.25. * Bạn tạo một chuỗi con của IP, cắt bỏ hai số cuối và so sánh nó với "89.95.25".

3

Chuyển đổi quad rải rác một số nguyên:

$ip = sprintf('%u', ip2long($_SERVER['REMOTE_ADDR'])); 

// only allow 10.0.0.0 – 10.255.255.255 
if (!($ip >= 167772160 && $ip <= 184549375)) { 
    die('Forbidden.'); 
} 
+0

lý do sử dụng số nguyên ở đây là gì? làm cho mã nhiều obfuscated? – zerkms

+0

Không phải điều này làm giảm tính hữu ích của câu trả lời này, nhưng Uỷ quyền cho phép nhiều hơn từ chọn tham gia, trong đó một nhóm người được chọn được ủy quyền. Trong trường hợp này, thay vì chỉ cho phép một vài người, anh ta không cho phép hoặc cấm một vài người. Như vậy, tôi nghĩ một từ tốt hơn sẽ là 'Cấm'. –

+0

@ Chacha102: Tôi đã chỉnh sửa. – webbiedave

4

Sử dụng ip2long() để chuyển đổi dấu chấm thập phân đến một địa chỉ IP thực. Sau đó, bạn có thể làm phạm vi dễ dàng.

Chỉ cần thực hiện ip2long() trên phạm vi cao và thấp để nhận giá trị, sau đó sử dụng các giá trị đó làm hằng số trong mã của bạn.

Nếu bạn đã quen thuộc với subnet mặt nạ, bạn có thể làm điều đó như thế này:

// Deny 10.12.*.* 
$network = ip2long("10.12.0.0"); 
$mask = ip2long("255.255.0.0"); 
$ip = ip2long($_SERVER['REMOTE_ADDR']); 
if (($network & $mask) == ($ip & $mask)) { 
    die("Unauthorized"); 
} 

Hoặc nếu bạn đã quen thuộc với định dạng này 10.12.0.0/16:

// Deny 10.12.*.* 
$network = ip2long("10.12.0.0"); 
$prefix = 16; 
$ip = ip2long($_SERVER['REMOTE_ADDR']); 
if ($network >> (32 - $prefix)) == ($ip >> (32 - $prefix)) { 
    die("Unauthorized"); 
} 

Bạn có thể bật những thành chức năng và có mã rất dễ quản lý, giúp dễ dàng thêm địa chỉ IP và tùy chỉnh phạm vi.

+0

Cảm ơn! Đây là cách chúng tôi đang thực hiện nó. – Ami

+0

Điều tra chỉ '$ _SERVER {'REMOTE_HOST'}' là đủ? Bởi vì có thể người dùng sử dụng proxy. Vì vậy, có một số tham số khác mà bạn phải kiểm tra, như 'REMOTE_ADDR' hoặc [những] này (http://stackoverflow.com/questions/15699101/get-the-client-ip-address-using-php#15699240). Tôi có đúng không? hoặc làm những gì tôi liên kết không hữu ích? – stack

+0

Có, chỉ cần sử dụng REMOTE_ADDR. –

1
$user_ip = $_SERVER['REMOTE_ADDR']; // get user ip 

$denyIPs = array("111.111.111", "222.222.222", "333.333.333"); 
if (in_array ($user_ip, $denyIPs)) { 
    // blocked ip 
} 
else { 
    // not blocked 
} 
+0

hi Tôi đã cố gắng sử dụng định dạng này 222.222.222.0/15 nhưng không hoạt động ... –

1

này đã luôn luôn làm việc rất tốt cho tôi: kiểm tra này cho các biến máy chủ thích hợp và so sánh nó với một danh sách các IP được biết đến .. và có, PHP không hiểu các kí hiệu, vì vậy sử dụng * trong IP với hỗ trợ chặn các dải IP.

// The blacklisted ips. 
$denied_ips = array(
'1.2.3.4', 
'2.3.*', 
); 

// The function to get the visitor's IP. 
function getUserIP(){ 
    //check ip from share internet 
    if (!empty($_SERVER['HTTP_CLIENT_IP'])){ 
     $ip=$_SERVER['HTTP_CLIENT_IP']; 
    } 
    //to check ip is pass from proxy 
    elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])){ 
     $ip=$_SERVER['HTTP_X_FORWARDED_FOR']; 
    } else { 
     $ip=$_SERVER['REMOTE_ADDR']; 
    } 
    return $ip; 
} 
//The user 
$visitorIp = getUserIP(); 

// Now let's search if this IP is blackliated 
$status = array_search($visitorIp, $denied_ips); 

// Let's check if $status has a true OR false value. 
if($status !== false){ 
    echo '<div class="error">Your IP has been banned! Stop spamming us!</div>'; 
    // header("Location: http://zombo.com"); 
    // exit; 
} 

Ngoài ra còn có một bài viết tuyệt vời tại Hư Press: http://perishablepress.com/how-to-block-ip-addresses-with-php/

+0

"và có, PHP hiểu các ký tự đại diện, vì vậy hãy sử dụng * trong IP với sự hỗ trợ trong việc chặn các dải IP." bạn có chắc chắn về điều đó không? phiên bản cụ thể của php có thể? – artfulhacker

+0

Mảng từ chối với chuyển hướng tiêu đề hoạt động tốt :) – PipBoy2000

0

sử dụng của phục hồi mã, sử dụng này để có được tìm kiếm ký tự đại diện làm việc

// Now let's search if this IP is blackliated 
$status = false; 
foreach($denied_ips as $val) 
{ 
    if (strpos($val,'*') !== false) 
    { 
     if(strpos($visitorIp, array_shift(explode("*", $val))) === 0) 
     { 
      $status = true; 
      break; 
     } 
    } 
    else 
    { 
     if(strcmp($visitorIp, $val) === 0) 
     { 
      $status = true; 
      break; 
     } 
    } 
} 
-2
$deny = array("111.111.111", "222.222.222", "333.333.333"); 

if (in_array($_SERVER['REMOTE_ADDR'], $deny)) { 
    header("location:http://www.google.com/"); 
    exit(); 
}