2009-02-27 16 views
17

कुछ की तरहआईपी + सीआईडीआर के साथ आईपी से सीधे चयन क्वेरी से मिलान करने का कोई तरीका है?

SELECT COUNT(*) AS c FROM BANS WHERE typeid=6 AND (SELECT ipaddr,cidr FROM BANS) MATCH AGAINST 'this_ip';

तो तुम पहले डीबी से सभी रिकॉर्ड लाने नहीं है और फिर उन्हें एक एक से मेल खाते हैं।

यदि सी> 0 मिलान किया गया था।

प्रतिबंध तालिका:

id int auto incr PK 
typeid TINYINT (1=hostname, 4=ipv4, 6=ipv6) 
ipaddr BINARY(128) 
cidr INT 
host VARCHAR(255) 

डीबी: MySQL 5

आईपी और आइपीवी प्रकार (4 या 6) जब क्वेरी करने में जाना जाता है।

आईपी द्विपदीय प्रारूप में उदाहरण :: 1 के लिए है

प्रतिबंध लगा दिया आईपी उदाहरण :: 1/64

+0

raspi, मुझे पता है इस सवाल पुराना है, लेकिन ... शुद्ध नकाब में एक बिट की संख्या है, यह हमेशा है, तो IPv6 के लिए 64 अपने CIDR स्तंभ है और आईपीवी 4 के लिए यह 0 के बीच एक संख्या है और 32? हालांकि मुझे लगता है कि 0 सभी पते पर प्रतिबंध लगाएगा ... :) – ErikE

उत्तर

22

याद रखें कि आईपी एक टेक्स्ट का पता नहीं हैं, लेकिन एक अंकीय आईडी। मेरे पास एक समान स्थिति है (हम भू-आईपी लुकअप कर रहे हैं), और यदि आप अपने सभी आईपी पतों को पूर्णांक के रूप में स्टोर करते हैं (उदाहरण के लिए, मेरा आईपी पता 192.115.22.33 है तो इसे 3228767777 के रूप में संग्रहीत किया जाता है), तो आप आईपी देख सकते हैं सही शिफ्ट ऑपरेटरों का उपयोग करके आसानी से।

इन सभी प्रकार के लुकअप का नकारात्मक पक्ष यह है कि आप इंडेक्स से लाभ नहीं उठा सकते हैं और जब भी आप लुकअप करते हैं तो आपको एक पूर्ण टेबल स्कैन करना होगा। उपर्युक्त योजना को सीआईडीआर नेटवर्क (सीमा की शुरुआत) और प्रसारण पता (सीमा का अंत) दोनों के नेटवर्क आईपी पते को संग्रहीत करके बेहतर किया जा सकता है, उदाहरण के लिए 1 9 2.168.1.0/24 स्टोर करने के लिए आप दो स्टोर कर सकते हैं कॉलम:

network  broadcast 
3232235776, 3232236031 

और फिर आप कर सकते हैं इससे मिलते हुए आप बस

SELECT count(*) FROM bans WHERE 3232235876 >= network AND 3232235876 <= broadcast 

कर यह आपको डेटाबेस में सीआईडीआर नेटवर्क का संग्रहण करने दे और उनकी बराबरी के खिलाफ आईपी त्वरित का लाभ उठा कर जल्दी से और कुशलता के पते हैं संख्यात्मक सूचकांक। नीचे चर्चा से

नोट:

MySQL 5.0 एक लेकर क्वेरी अनुकूलन "index merge intersect" कहा जाता है जो इस तरह के प्रश्नों को गति (और पूर्ण तालिका स्कैन बचने के लिए) की अनुमति देता है, जब तक शामिल है के रूप में:

  • एक मल्टी-कॉलम इंडेक्स है जो क्रम में क्वेरी में बिल्कुल कॉलम से मेल खाता है। तो - उपर्युक्त क्वेरी उदाहरण के लिए, सूचकांक (network, broadcast) होना चाहिए।
  • सभी डेटा इंडेक्स से पुनर्प्राप्त किया जा सकता है। यह COUNT(*) के लिए सच है, लेकिन SELECT * ... LIMIT 1 के लिए यह सच नहीं है।

MySQL 5.6 में एमआरआर नामक एक अनुकूलन शामिल है जो पूर्ण पंक्ति पुनर्प्राप्ति को गति देगा, लेकिन यह इस उत्तर के दायरे से बाहर है।

+0

दुर्भाग्यवश, MySQL दो इंडेक्स को एक साथ जोड़ नहीं सकता है। यह निश्चित रूप से किसी भी नेटवर्क या प्रसारण पर इंडेक्स का उपयोग करने का प्रयास करेगा, लेकिन आईपी पते समान रूप से distibuted हैं, इस मामले में पूर्ण तालिका स्कैन अधिक कुशल होगा। – Quassnoi

+0

यह मिथक थोड़ी पुरानी है :-) MySQL 5.0 से शुरू हो रहा है, सर्वर एकाधिक अनुक्रमणिका (http://dev.mysql.com/doc/refman/5.1/en/index-merge-optimization.html) मर्ज कर सकता है । भले ही, मैं यह नहीं देख सकता कि एक इंडेक्स का उपयोग करके एक पूर्ण टेबल स्कैन बेहतर कैसे होता है, भले ही यह केवल 1 इंडेक्स हो। – Guss

+0

यदि आपका फ़िल्टर लगभग 10% या पंक्तियों से अधिक लौटाता है, तो पूर्ण तालिका स्कैन बेहतर होता है। इसे आज़माएं :) – Quassnoi

0

हममम के लिए है। आप सिडर मास्क की एक टेबल बना सकते हैं, इसमें शामिल हो सकते हैं, और फिर प्रतिबंध ब्लॉक आईपैड्रेस के साथ मास्क के साथ आईपी एंडेड (& MySQL में) की तुलना कर सकते हैं। क्या आप वह चाहते हैं जो आप चाहते हैं?

यदि आप मास्क टेबल बनाना नहीं चाहते हैं, तो आप मास्क को -1 << (x-cidr)x = 64 या 32 के साथ गणना कर सकते हैं।

3

IPv4 के लिए, आप उपयोग कर सकते हैं:

SET @length = 4; 

SELECT INET_NTOA(ipaddr), INET_NTOA(searchaddr), INET_NTOA(mask) 
FROM (
    SELECT 
     (1 << (@length * 8)) - 1 & ~((1 << (@length * 8 - cidr)) - 1) AS mask, 
     CAST(CONV(SUBSTR(HEX(ipaddr), 1, @length * 2), 16, 10) AS DECIMAL(20)) AS ipaddr, 
     CAST(CONV(SUBSTR(HEX(@myaddr), 1, @length * 2), 16, 10) AS DECIMAL(20)) AS searchaddr 
    FROM ip 
) ipo 
WHERE ipaddr & mask = searchaddr & mask 
+0

धन्यवाद। मुझे पूरा यकीन था कि मुझे सीआईडीआर करने के लिए टेबल की आवश्यकता नहीं थी, लेकिन इस तरह फ्लाई पर मास्क की गणना/निर्माण कर सकता था। मेरा मानना ​​है कि मास्क को सरलीकृत किया जा सकता है ((1 << cidr) -1), जहां ((1 << cidr) -1) सही सिडर बिट्स को सही सेट करता है, और नहीं, आईई: ~ सभी बिट्स को उलट देता है हस्ताक्षर किए गए लंबे समय तक कि सही सिडर बिट्स झूठे हैं और बाईं ओर वाले सभी सत्य हैं। प्रोग्रामर इंटरफेस का उपयोग करते हुए Win7 + कैल्क, इस तरह के मामलों में काफी मददगार है। – RocketRoy

-2

MySQL: सीआईडीआर

मैं एक तरह से MySQL का उपयोग करने के IP पते और उत्पादन में CIDR स्वरूपित पता है कि एक आईपी काली सूची को बनाए रखने के लिए उपयुक्त आईपी रेंज को कवर की एक श्रृंखला लेने के लिए के लिए खोज कई घंटे बिताए को IP श्रेणी में कन्वर्ट ।

मेरे पर्यावरण और आवश्यकताएँ के विशिष्टता मैं अपनी वेबसाइट पर यातायात को लॉग इन करने के लिए ओपनवेब Analytics का उपयोग करता हूं और कई जिन्हें मैं प्रबंधित करता हूं। मैंने ओडब्ल्यूए द्वारा लॉग किए गए अलग-अलग आईपी पतों को निकालने के लिए एक प्रक्रिया विकसित की और फिर भौगोलिक डेटा तत्वों को उन अभिलेखों पर विलय कर दिया जिन्हें बाद में कस्टम तालिका में रखा जाता है। आईपी-टू-लोकेशन डेटा की इस तालिका के साथ सशस्त्र अवांछित स्रोतों, या मेरे स्थानीय व्यापार - चीन, जापान, कोरिया, रूस इत्यादि से अप्रासंगिक स्रोतों की रिपोर्ट करने की क्षमता प्रदान करता है। इससे आईपी की बढ़ती सूची हुई है। पतों; जिनमें से कई एक ही नेटवर्क के भीतर आते हैं। मेरे सर्वर की .htaccess फ़ाइल के लिए रखरखाव आवश्यकताओं को कम करने के लिए यह सीआईडीआर प्रारूप में ब्लैकलिस्टेड आईपी पते रिकॉर्ड करने में सक्षम होने के लिए फायदेमंद हो जाता है। इसके बाद पहले से लॉग इन आईपी पते से सीआईडीआर को सक्षम और उत्पादन करने की आवश्यकता होती है।

MySQL दृष्टिकोण अधिकांश वेब होस्ट MySQL डेटाबेस तक पहुंच प्रदान करते हैं। हालांकि, अगर कुछ डेटाबेस कार्यों को बनाने की क्षमता की अनुमति देता है। यह कोडिंग थोड़ा जटिल है।

नमूना एसक्यूएल http://blog.watsoninfotech.com/2012/12/mysql-convert-ip-range-to-cidr.html

+1

मुझे यह देखने में परेशानी हो रही है कि यह पूछे गए प्रश्न से सीधे * सीधे * कैसे है। –

2

IPv4 पतों, नेटवर्क पते और netmasks पर उपलब्ध सभी uint32 नंबर दिए गए हैं और के रूप में "डॉटेड-quads" मानव पठनीय रूप में प्रस्तुत कर रहे हैं। किसी दिए गए नेटवर्क स्पेस (नेटवर्क/नेटमास्क) में कोई पता है या नहीं, यह जांचते समय कर्नेल में रूटिंग टेबल कोड बहुत तेज़ बिट-वार और तुलना करता है। यहां की चाल यूआईटीटी 32 के रूप में आपकी टेबल में बिंदीदार-क्वाड आईपी पते, नेटवर्क पते और नेटमास्क स्टोर करने के लिए है, और उसके बाद 32-बिट बिट-वार और आपके मिलान के लिए प्रदर्शन करें। जैसे

SET @test_addr = inet_aton('1.2.3.4'); 
SET @network_one = inet_aton('1.2.3.0'); 
SET @network_two = inet_aton('4.5.6.0'); 
SET @network_netmask = inet_aton('255.255.255.0'); 

SELECT (@test_addr & @network_netmask) = @network_one AS IS_MATCHED; 
+------------+ 
| IS_MATCHED | 
+------------+ 
|   1 | 
+------------+ 

SELECT (@test_addr & @network_netmask) = @network_two AS IS_NOT_MATCHED; 
+----------------+ 
| IS_NOT_MATCHED | 
+----------------+ 
|    0 | 
+----------------+ 
संबंधित मुद्दे