[Php] 100,000+ अलग-अलग IP पते कैसे ब्लॉक करें


Answers

एक और परिचित

नमस्ते। आप जांच सकते हैं कि एक पते को अवरुद्ध कर दिया गया है या नहीं, दो बाइट्स में दो डेटा चुने हुए प्रत्येक 8KB लंबे तक पहुंच के माध्यम से। हां, मैं गंभीर हूं ... कृपया धैर्य रखें क्योंकि इसे समझने में थोड़ी देर लगती है।

सिद्धांत

एक आईपी पता एक पता है, वास्तव में एक 4 बाइट संख्या है।

सवाल यह है, क्या होगा अगर हम इसे बिट पदों को संबोधित करते हैं?

जवाब: ठीक है, ठीक है, हमारे पास होगा

  2^32 = 4 Giga Bits 

स्थान को संबोधित करने और इसे ले जाएगा

 4Gb/8 = 512 Mega Bytes

आवंटन का आउच! लेकिन चिंता न करें, हम सब कुछ ipverse में नहीं रोकेंगे और 512 एमबी एक अतिशयोक्ति है।

यह हमें समाधान के लिए एक रास्ता खोल सकता है।

लिलिपुटियन केस

एक लिलिपुटियन दुनिया के बारे में सोचो जो केवल आईपी पते 0 से 65535 तक मौजूद हैं। तो पते 255.255 तक 0.1 या 42.42 के समान हैं।

अब इस दुनिया का राजा कई एल-आईपी (लिलिपुत आईपी) पते को ब्लॉक करना चाहता है।

सबसे पहले वह एक आभासी 2 डी बिट मानचित्र बनाता है जो 256 * 256 बिट लंबा होता है:

 64 K Bits = 8 K Bytes.

वह उस गंदी "क्रांति" साइट को अवरुद्ध करने का फैसला करता है जिसे वह नफरत करता है क्योंकि वह राजा है, उदाहरण के लिए पता 56.28 है।

Address     = (56 * 256) + 28  = 14364.(bit position in whole map)
Byte in map = floor(14364 / 8) =  1795.
Bit position= 14364 % 8        =     4.(modulus)

वह नक्शा फाइल खोलता है, 17 9 5 वें बाइट तक पहुंचता है और बिट 4 (एक | 16) के द्वारा सेट करता है, तो उस साइट को अवरोधित के रूप में चिह्नित करने के लिए इसे वापस लिखता है

जब उसकी स्क्रिप्ट देखती है 56.28, यह एक ही गणना करता है और थोड़ा सा दिखता है, और यदि यह सेट है, तो पते को अवरुद्ध करता है।

अब कहानी का नैतिक क्या है? अच्छी तरह से हम इस lilliputian संरचना का उपयोग कर सकते हैं

अभ्यास

असली दुनिया मामला

हम 512 एमबी फ़ाइल आवंटित करने के बाद से "जब आपको ज़रूरत होती है" का इस्तेमाल करते हैं, तो वह लिलिपुटियन मामले को वास्तविक दुनिया में लागू कर सकता है, यह एक अच्छा विकल्प नहीं है।

ब्लॉकों नामक एक डेटाबेस तालिका के बारे में उस तरह की प्रविष्टियों के बारे में सोचें:

IpHead(key): unsigned 16 bit integer,
Map        : 8KB BLOB(fixed size),
EntryCount : unsigned 16 bit integer.

और नामित नीचे संरचना के साथ सिर्फ एक प्रविष्टि के साथ एक अन्य तालिका BASE

Map        : 8KB BLOB(fixed size).

अब बताता है कि आपका आने वाला पता 56.28.10.2 है

स्क्रिप्ट एक्सेस टेबल का उपयोग करता है और मानचित्र प्राप्त करता है।

यह उच्च आदेश आईपी ​​नंबर 56.28 को देखता है:

Address     = (56 * 256) + 28  = 14364.(bit position in whole map)
Byte in map = floor(14364 / 8) =  1795.
Bit position= 14364 % 8        =     4.(modulus)

नक्शे में बाइट 1795 बिट 4 में दिखता है

यदि बिट सेट नहीं किया जाता है तो आगे कोई ऑपरेशन आवश्यक नहीं है जिसका अर्थ है कि सीमा 56.28.0.0 - 56.28.255.255 में कोई अवरुद्ध आईपी पता नहीं है।

यदि बिट सेट है तो स्क्रिप्ट BLOCKS तालिका तक पहुंचता है

उच्च आदेश आईपी संख्या 56.28 थी, जो 14364 देता है ताकि स्क्रिप्ट BLOCKS तालिका को इंडेक्स IpHead = 14364 के साथ पूछता है। रिकॉर्ड प्राप्त करता है रिकॉर्ड मौजूद होना चाहिए क्योंकि यह आधार पर चिह्नित है।

स्क्रिप्ट निम्न क्रम आईपी ​​पते के लिए गणना करता है

Address     = (10 * 256) + 2   = 2562.(bit position in whole map)
Byte in map = floor(2562 / 8) =   320.
Bit position= 2562 % 8        =     2.(modulus)

फिर यह जांचता है कि पता क्षेत्र ब्लॉक के बाइट 320 के बिट 2 को देखकर ब्लॉक किया गया है।

काम हो गया!

प्रश्न 1: हम आधार आधार का उपयोग क्यों करते हैं, हम सीधे 14364 के साथ BLOCKS क्वेरी कर सकते हैं।

ए 1: हां, लेकिन हम बेस मैप्स लुकअप तेजी से हो सकते हैं फिर किसी भी डेटाबेस सर्वर की बीटीआरई खोजें।

प्रश्न 2: ब्लॉकेज़ तालिका में EntryCount फ़ील्ड क्या है?

ए 2: यह एक ही रिकॉर्ड पर मैप फ़ील्ड में अवरुद्ध आईपी पते की गिनती है। इसलिए अगर हम आईपी के अनब्लॉक और एंट्रीकाउंट 0 तक पहुंचते हैं तो ब्लॉक्स रिकॉर्ड अनावश्यक हो जाता है इसे मिटाया जा सकता है और BASE मानचित्र पर संबंधित बिट को अनसेट किया जाएगा।

आईएमएचओ इस दृष्टिकोण से तेज बिजली होगी इसके अलावा ब्लॉब आवंटन के लिए प्रति रिकॉर्ड 8K है चूंकि डीबी सर्वर अलग-अलग फाइलों में ब्लॉब्स रखते हैं, 4K, 8 के साथ फाइल सिस्टम या 4K पेजिंग के गुणक तेज गति से प्रतिक्रिया देंगे

यदि अवरुद्ध पते बहुत फैल गए हैं

खैर यह एक चिंता का विषय है, जो डेटाबेस ब्लॉक्सकेस को अनावश्यक रूप से विकसित करने के लिए तालिका बना देगा।

लेकिन ऐसे मामलों में वैकल्पिक 256 * 256 * 256 बिट क्यूब का उपयोग करना है जो कि 16777216 बिट लंबा है, 20 9 7152 बाइट्स = 2 एमबी के बराबर है

हमारे पिछले उदाहरण के लिए उच्च आईपी समाधान है:

(56 * 65536)+(28 * 256)+10      

तो आधार एक डीबी तालिका रिकॉर्ड के बजाय एक 2 एमबी फाइल बन जाएगा, जो खोला जाएगा (एफओपीएन आदि) और बिट की मांग के माध्यम से संबोधित किया जाएगा (जैसे कि, पूरी तरह से फाइल सामग्री को पढ़ने के लिए, अनावश्यक), फिर नीचे की संरचना के साथ ब्लॉकों तालिका का उपयोग करें :

IpHead(key): unsigned 32 bit integer, (only 24 bit is used)
Map        : 32 unsigned 8 bit integers(char maybe),(256 bit fixed)
EntryCount : unsigned 8 bit integer. 

बिटप्लेन-बिटप्लेन (8 के 8 के) संस्करण की ब्लॉक जांच के लिए यहां पीएचपी उदाहरण कोड दिया गया है:

साइड नोट: इस स्क्रिप्ट को कई कॉल्स आदि के उन्मूलन के जरिए अनुकूलित किया जा सकता है। लेकिन इसे समझना आसान रखने के लिए इस तरह लिखा गया है।

<?
define('BLOCK_ON_ERROR', true); // WARNING if true errors block everyone

$shost = 'hosturl';
$suser = 'username';
$spass = 'password';
$sdbip = 'database';
$slink = null;

$slink = mysqli_connect($shost, $suser, $spass, $sdbip);
if (! $slink) {
    $blocked = BLOCK_ON_ERROR;
} else {
    $blocked = isBlocked();
    mysqli_close($slink); // clean, tidy...
}

if ($blocked) {
    // do what ever you want when blocked
} else {
    // do what ever you want when not blocked
}
exit(0);

function getUserIp() {
    $st = array(
            'HTTP_CLIENT_IP',
            'REMOTE_ADDR',
            'HTTP_X_FORWARDED_FOR'
    );
    foreach ( $st as $v )
        if (! empty($_SERVER[$v]))
            return ($_SERVER[$v]);
    return ("");
}

function ipToArray($ip) {
    $ip = explode('.', $ip);
    foreach ( $ip as $k => $v )
        $ip[$k] = intval($v);
    return ($ip);
}

function calculateBitPos($IpH, $IpL) {
    $BitAdr = ($IpH * 256) + $IpL;
    $BytAdr = floor($BitAdr / 8);
    $BitOfs = $BitAdr % 8;
    $BitMask = 1;
    $BitMask = $BitMask << $BitOfs;
    return (array(
            'bytePos' => $BytAdr,
            'bitMask' => $BitMask
    ));
}

function getBaseMap($link) {
    $q = 'SELECT * FROM BASE WHERE id = 0';
    $r = mysqli_query($link, $q);
    if (! $r)
        return (null);
    $m = mysqli_fetch_assoc($r);
    mysqli_free_result($r);
    return ($m['map']);
}

function getBlocksMap($link, $IpHead) {
    $q = "SELECT * FROM BLOCKS WHERE IpHead = $IpHead";
    $r = mysqli_query($link, $q);
    if (! $r)
        return (null);
    $m = mysqli_fetch_assoc($r);
    mysqli_free_result($r);
    return ($m['map']);
}

function isBlocked() {
    global $slink;
    $ip = getUserIp();
    if($ip == "")
        return (BLOCK_ON_ERROR);
    $ip = ipToArray($ip);

    // here you can embed preliminary checks like ip[0] = 10 exit(0)
    // for unblocking or blocking address range 10 or 192 or 127 etc....

    // Look at base table base record.
    // map is a php string, which in fact is a good byte array
    $map = getBaseMap($slink); 
    if (! $map)
        return (BLOCK_ON_ERROR);
    $p = calculateBitPos($ip[0], $ip[1]);
    $c = ord($map[$p['bytePos']]);
    if (($c & $p['bitMask']) == 0)
        return (false); // No address blocked

    // Look at blocks table related record
    $map = getBlocksMap($slink, $p[0]);
    if (! $map)
        return (BLOCK_ON_ERROR);
    $p = calculateBitPos($ip[2], $ip[3]);
    $c = ord($map[$p['bytePos']]);
    return (($c & $p['bitMask']) != 0);
}

?> 

आशा है कि ये आपकी मदद करेगा।

यदि आपके पास विवरणों पर प्रश्न हैं, तो मुझे जवाब देने में खुशी होगी।

Question

परिचय

आप अपने वेब एप्लिकेशन / सर्वर से बड़ी संख्या में IP address कैसे ब्लॉक करते हैं जाहिर है कि यह आसानी से PHP या किसी भी प्रोग्रामिंग भाषा में किया जा सकता है

$ipList = []; // array list or from database
if (in_array(getIP(), $ipList)) {
    // Log IP & Access information
    header("https://www.google.com.ng/search?q=fool"); // redirect
    exit(); // exit
} 

या htaccess का उपयोग करना

order allow,deny
deny from 123.45.6.7
deny from 012.34.5.
# .... the list continues
allow from all

वाद विषय

  • पूरे 100k plus individual IPs को ब्लॉक करने की कोशिश कर रहा हूं
  • इस तरह के आईपी को अवरुद्ध करने से पहले उपयोगकर्ता PHP को प्राप्त करने से बचने की कोशिश कर रहा है I
  • 100000+ से अधिक 1.5 एमबी है और यह बहुत कुछ है, अगर सूचना हर समय एचटीएसीएस में लोड हो रही है
  • आईपी ​​का डेटाबेस अभी भी बढ़ रहा है ... और वे गतिशील रूप से अधिक मूल्यों को जोड़ना चाहते हैं
  • 100000+ के लिए iptables में प्रतिबंध सेट करने के लिए सिर्फ हास्यास्पद (गलत हो सकता है)

बेवकूफ आइडिया

order allow,deny
deny from database    <-------- Not sure if this is possible
allow from all

सवाल

  • क्या एचटीएसीएस के लिए डेटाबेस से सूची प्राप्त करना संभव है (रेडिस, कूंचबेस, मोंगो, मायएसक्यूएल या एसक्यूएलइट) ... कोई भी
  • क्या उत्पादन में इस तरह के मुद्दे को प्रबंधित करने के लिए कोई दृश्यमान समाधान है?
  • मुझे पता है कि सबसे अच्छा समाधान Block the IPs at the firewall level को व्यावहारिक रूप से जोड़ने / हटाने का कोई तरीका है

आखिरकार

मेरा दृष्टिकोण पूरी तरह से गलत हो सकता है ... मैं चाहता हूं कि एक दृश्य समाधान हो, क्योंकि स्पैमर और बोटनेट बढ़ रहे हैं ...

कृपया इसका कोई लेना देना नहीं है, DOS ने इसका सरलता पर हमला किया ... get lost response

अद्यतन करें

  • फ़ायरवाल: सिस्को पीआईएस 515UR



अपनी सूची में आईपी पर भौगोलिक-लुकअप करें। मेरा अपना अनुभव सबसे दुर्भावनापूर्ण (यानी स्पैम) कनेक्शन चीन से उत्पन्न हुआ है। यदि आपको ऐसा लगता है कि आपके लिए मामला है, और आपको चीन की सेवा करने की कोई ज़रूरत नहीं है, तो देखें कि क्या आप फ़ायरवॉल स्तर पर पूरे देश को कुशलतापूर्वक ब्लॉक कर सकते हैं।




Iptables और ipset का उपयोग कर www सर्वर तक पहुंचने से पहले यातायात को अवरुद्ध करें।

अपने वेब सर्वर को एक ही मशीन पर मानते हुए INPUT श्रृंखला की फ़िल्टर तालिका में ब्लैकलिस्ट आईपी ट्रैफ़िक को पकड़ें। यदि आप एक रूटर पर आईपी अवरुद्ध कर रहे हैं तो आप अग्रेषित श्रृंखला चाहते हैं।

सबसे पहले ipset बनाएँ:

ipset create ip_blacklist hash:ip

आईपी ​​के माध्यम से जोड़ा जा सकता है:

ipset add ip_blacklist xxx.xxx.xxx.xxx

Ipset मैच नियम को अपने iptables में जोड़ें (सभी पैकेट्स ipset से मेल खाते हैं):

iptables --table filter --insert INPUT --match set --match-set ip_blacklist src -j DROP

यह www सर्वर से पहले ब्लैकलिस्ट किए गए ट्रैफ़िक को रोक देगा।

संपादित करें: मेरे पास डिफ़ॉल्ट अधिकतम आकार देखने का मौका था और यह 65536 है ताकि आप इसे 100000+ प्रविष्टियों का समर्थन करने के लिए समायोजित करने की आवश्यकता होगी:

ipset create ip_blacklist hash:ip maxelem 120000

आप हैश का आकार भी बदल सकते हैं:

ipset create ip_blacklist hash:ip maxelem 120000 hashsize 16384 (2 की शक्ति होना चाहिए)

मेरा अनुभव है ipset लुकअप मेरे सिस्टम (~ 45000 प्रविष्टियों) पर नगण्य प्रभाव है। नेट पर परीक्षण के कई मामले हैं। सेट के लिए मेमोरी सीमित कारक है।




मुझे एक रास्ता पता है
इसकी php द्वारा जैसा कि आपने इस प्रश्न की शुरुआत में उल्लेख किया है

$ipList = []; // array list or from database
if (in_array(getIP(), $ipList)) {
    // Log IP & Access information
    header("https://www.google.com.ng/search?q=fool"); // redirect
    exit(); // exit
} 

मैंने आपके द्वारा लिखी बात पढ़ा है। लेकिन सिर्फ एक मिनट रुको।
आप ऐसा क्यों करना चाहते हैं। महत्वपूर्ण नहीं है। लेकिन इस स्थिति के कारण क्यों?
मेरा मतलब है कि आप PHP को अपनी गति के कारण या रोकने के कारण और सभी पृष्ठों में समारोह को कॉल करने के लिए इतनी मेहनत क्यों नहीं करना चाहते हैं? अगर कुछ आईपी से पीएचपी तक पहुंचने से बचने का एकमात्र कारण है। सामग्री देखने के लिए थीम को छोड़कर।
इसलिए मुझे एक विचार मिला और मैंने आपको इस तरह से सलाह दी।
एक प्रवेश बिंदु का उपयोग करना

मैंने इस समाधान के साथ काम किया है

पहले एक सरल एचटीएसीस के साथ आप सभी अनुरोध को एक पेज को एंट्री पॉइंट में भेजते हैं। (जैसे index.php)
एक साधारण पुनर्रचना नियम के साथ मैं इसे आपको दे दूँगा इसलिए जब उपयोगकर्ता अनुरोध करता है

mysite.com/some/path/page.php or anything

htaccess url को बदलने के बिना निम्नलिखित की तरह कुछ निष्पादित करेगा इसलिए उपयोगकर्ता कुछ भी महसूस नहीं करेगा।

mysite.com/index.php?r=some/path/page.php

इसलिए प्रत्येक अनुरोध एक अलग अनुरोध के साथ अलग-अलग $ _GET ['r'] पैरामीटर बन गया। इसलिए एवे के अनुरोध के लिए हमारे पास index.php निष्पादित होगा। और अब हम index.php में ऐसा कुछ कर सकते हैं

$ipList = []; // array list or from database
if (in_array(getIP(), $ipList)) {
    // Log IP & Access information
    header("https://www.google.com.ng/search?q=fool"); // redirect
    exit(); // exit
}
//if after this execute means the IP is not banned
//now we can include file that $_GET['r'] points to
include $_GET['r'];

इसकी इतनी सरल है.और इसके असली एक बहुत जटिल है। लेकिन मुख्य विचार एक ही है। तुम क्या सोचते हो?




उस प्रयुक्त ipset के लिए नेटफिल्टर वाला एक प्रोजेक्ट है ताकि आप आईपी को एक सूची में जोड़ या निकाल सकें और आपको इस सूची के विरुद्ध एक नियम बनाना होगा

http://ipset.netfilter.org/