[php] 100,000+ व्यक्तिगत आईपी पते को कैसे अवरुद्ध करें



4 Answers

एक और निष्पक्ष

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

सिद्धांत

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

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

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

  2^32 = 4 Giga Bits 

अंतरिक्ष को संबोधित करने और वह ले जाएगा

 4Gb/8 = 512 Mega Bytes

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

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

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

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

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

सबसे पहले वह वर्चुअल 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 देखती है, तो यह वही गणना करता है और थोड़ा सा दिखता है, और यदि यह सेट है, तो पता ब्लॉक करें।

अब कहानी का नैतिक क्या है? खैर हम इस लिलीपूटियन संरचना का उपयोग कर सकते हैं।

अभ्यास

रियल वर्ल्ड केस

हम 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 है

स्क्रिप्ट BASE तालिका तक पहुंचता है और मानचित्र प्राप्त करता है।

यह उच्च क्रम आईपी ​​संख्या 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 देखता है।

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

यदि बिट सेट किया गया है तो स्क्रिप्ट ब्लॉक्स तालिका तक पहुंच जाती है।

उच्च ऑर्डर आईपी नंबर 56.28 थे जो 14364 देता है, इसलिए स्क्रिप्ट इंडेक्स 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 के साथ ब्लॉक्स पूछ सकते हैं।

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

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

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

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

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

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

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

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

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

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

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 के) संस्करण की ब्लॉक जांच के लिए PHP उदाहरण कोड यहां दिया गया है:

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

<?
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 को subnets को अवरुद्ध करने की कोशिश कर रहा हूं
  • मैं ऐसे आईपी को अवरुद्ध करने से पहले पीएचपी में आने से बचने की कोशिश कर रहा हूं
  • 100000+ 1.5 एमबी से अधिक है और यह बहुत कुछ है अगर सूचना हर समय htaccess में लोड हो रही है
  • आईपी ​​का डाटाबेस अभी भी बढ़ रहा है ... और वे गतिशील रूप से अधिक मूल्य जोड़ने के लिए नींद लेंगे
  • 100000+ के लिए iptables में प्रतिबंध सेट करने के लिए बस हास्यास्पद है (गलत हो सकता है)

बेवकूफ विचार

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

सवाल

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

आखिरकार

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

कृपया इसका DOS हमले के साथ कुछ भी आसान नहीं है ... get lost response

अद्यतन करें

  • फ़ायरवॉल: सिस्को पिक्स 515UR



मुझे एक रास्ता पता है
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 को एक्सेस करना क्यों नहीं चाहते हैं और क्योंकि सभी पृष्ठों में फ़ंक्शन को कॉल करना इतना मुश्किल है? यदि php तक पहुंचने से कुछ आईपी से बचने का एकमात्र कारण सामग्री देखने के लिए थीम पर जा रहा है।
तो मुझे एक विचार मिला और मैं आपको इस तरह सुझाव देता हूं।
एक प्रवेश बिंदु का उपयोग कर।

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

पहले एक सरल htaccess के साथ आप प्रवेश बिंदु नामक एक पृष्ठ पर सभी अनुरोध भेजते हैं। (index.php की तरह)
एक सरल पुनर्लेखन नियम के साथ मैं इसे आपको दूंगा। तो जब उपयोगकर्ता अनुरोध करता है

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

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

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

इसलिए प्रत्येक अनुरोध अलग-अलग $ _GET ['r'] पैरा के साथ एक अनुरोध बन गया। तो evey अनुरोध के लिए हम 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'];

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




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

http://ipset.netfilter.org/




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

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

पहले ipset बनाएं:

ipset create ip_blacklist hash:ip

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

ipset add ip_blacklist xxx.xxx.xxx.xxx

अपने iptables में ipset मिलान नियम जोड़ें (सभी पैकेट को 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 की शक्ति होना चाहिए)

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




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






Related