2012-06-07 49 views
3

我有一個相當大的IP和IP塊的列表,我想禁止。我有列表在塊這樣的形式完成的,目前:如何使用基於PHP/MySQL的腳本來禁止網站上的IP塊?

1.2.3.4-1.2.3.54 
5.6.7.8-5.6.7.8 
2.3.4.5-2.3.4.116 

我試圖找到最有效的方式,通過某種方式將它們放入一個MySQL數據庫來阻止這些IP地址。當然,我可以將所有塊分離爲單獨的IP並將它們放入它們自己的MySQL記錄中,但這對於大量的IP來說效率極低。阻止整個範圍,例如「1.2.3。*」也會導致不必要地禁止大量用戶。

有沒有辦法有效地做到這一點?

回答

1

您可以使用MySQL INET_ATON()和INET_NTOA()函數。請記住這些是特定於MySQL的,但您也可以使用php來實現它們。

這些函數將IP地址從點符號轉換爲整數。然後,您可以將它們存儲在帶有「start_ip」和「end_ip」列的表格中。當您查詢IP是否被禁止時,您可以使用BETWEEN查詢。

SELECT * FROM bans WHERE INET_ATON("127.0.0.1") BETWEEN start_ip AND end_ip 
+0

我正在考慮嘗試它的簡單性。我唯一擔心的是,在每次加載頁面時,在數千個IP範圍上運行BETWEEN命令將會帶來很大壓力。使用真理更簡單的方法會減少壓力嗎? –

+0

如果在表格上有適當的索引,MySQL將非常有效地找到符合條件的行,最有可能比迄今提到的任何其他方法快得多。在查詢之前,您也不需要處理IP將其分成兩部分。如果你不需要禁止表中的任何其他信息,並且start_ip和end_ip列都被索引所覆蓋,那麼可以很快地確定IP是否被禁止,因爲MySQL只需要訪問索引本身,而不是數據文件。 –

+0

出於好奇,我對類似的查詢做了一些性能測試。該表包含大約200萬條記錄。返回〜40k結果的查詢在大約0.01秒內執行。返回幾個結果的查詢在0.00秒內完成,因此我懷疑您在性能方面有什麼擔心。 –

5

爲什麼不使用netmasks

  • 192.168.1.0/24塊192.168.1.0 - 182.168.1.255
  • 1.0.0.0/8塊1.0.0.0 - 1.255.255.255

你只需要5個字節的IPv4地址此辦法。如果你想用你的掩碼變得狡猾,那麼把這8個字節。

這可以通過簡單地將掩碼與IP進行OR操作來快速進行比較。這是IP路由的工作原理。

此外,您可以使用MySQL函數INET_NTOAINET_ATON將點格式的IP地址轉換爲其數字格式,然後再轉回,從而使存儲效率更高,並且易於使用。

+0

可能是比我的更好的答案。 –

1

我將有一個表像這樣:

range | start_number | end_number 
------+--------------+----------- 

將舉行(例如):1.2.3454分別。

然後,您可以輕鬆檢查連接IP地址是否在該範圍內,並且如果最後一部分介於start_numberend_number之間。

相關問題