[英]Banning by IP with php/mysql
我希望能夠通過IP禁止用戶。 我的想法是將一個IP列表保存為BannedIPs表中的行(IP列將是一個索引)。
為了檢查用戶對表的IP,我將為每個會話保留一個名為$ _SESSION ['IP']的會話變量。 如果在任何請求中,$ _SESSION ['IP']與$ _SERVER ['REMOTE_ADDR']不匹配,我將更新$ _SESSION ['IP']並檢查BannedIPs表以查看IP是否被禁止。 (標志也將保存為會話變量,指定是否禁止用戶)
以下是我想知道的事情:
注意...
首先,我建議不要使用MySQL和PHP來執行此操作。 Apache有一個Deny
IP地址的Deny
指令,最終將比本土解決方案更好。
您可以輕松創建后端以查看和編輯包含所有這些條目的.htaccess
文件。
這是一個禁止2個IP地址的例子(那些想知道的人的谷歌DNS服務器)並顯示一個自定義頁面,如果被禁止...
Order Allow,Deny
Deny from 8.8.8.8
Deny from 8.8.4.4
Allow from all
ErrorDocument 403 /access_is_denied.htm
此功能由Apache 2.2中的mod_authz_host
提供。 有關每個指令的更多信息可以在Apache的mod_authz_host
文檔頁面中找到 。
話雖如此:
當用戶的IP在$_SERVER['REMOTE_ADDR']
始終可用時,為什么$_SESSION['IP']
使用$_SESSION['IP']
$_SERVER['REMOTE_ADDR']
? 我能看到的唯一原因是保存到數據庫的行程......但是如果你將這個IP添加到你的禁令列表中,他仍然可以訪問,直到他的會話到期。
如果您確實仍想使用數據庫,請將IP地址存儲為INT
(如果要支持IPv6,則存儲2個BIGINT
列)。 它們占用的空間少於字符串,比較快。
至於它的安全性......他們可以通過代理來繞過禁令。 如果您希望收到響應,則在數據包中欺騙IP地址是完全沒用的。
Select Count(*) from bannedIPs where ip = $input
,如果返回0,則不禁止IP。 一般情況下,我建議您記住,您的站點可能被一台路由器后面的許多計算機訪問,這意味着所有用戶都將顯示相同的IP。 你禁止一個,你禁止他們。 我決心通過電子郵件和其他方式禁止。 此外,我想說,那些傷害你網頁的人不會被ip禁令或其他手段阻止。 考慮到這一點,始終保護自己免受XSS,sql注入等常見的待遇。
回答你的第3個問題:
您可能需要處理IPv6以及IPv4,因此您的數據結構需要允許128位地址值。
10.000條目是MySQL的簡單游戲。 只需將索引設置為正確,此金額就沒有問題。
也許您應該考慮使用白名單而不是黑名單,這可能會減少您的IP地址列表?
只要用戶不在旋轉代理后面,您的策略就會起作用。 即通過AOL客戶端訪問網站的AOL用戶將擁有不同的IP地址,因為他們的請求來自不同的代理服務器。 通常這不是問題。
用戶的IP地址保存在您的會話中($ _SESSION ['IP']),該會話通常存儲在您的服務器上,因此足夠安全。
以下是檢查表中條目的示例代碼:
$raw = mysql_query ("SELECT ip FROM ip_blacklist WHERE ip = '" . mysql_escape_string(getenv('REMOTE_ADDR')) . "' LIMIT 0,1");
if ( mysql_num_rows ($raw) ) {
// match found
}
else {
// no match found
}
您可以將其修改為僅搜索IP的一部分。 即,而不是192.168.0.1,你可以搜索192.168.0。%:
… WHERE ip LIKE '192.168.0.%' …
這允許您過濾小型網絡,而不是定義所有IP地址。
使用整數通常是最好的方法,特別是如果您使用數據庫和范圍。 如果您想更好地理解/讀取數據,字符串會更好。
http://www.rubyrobot.org/article/protect-your-web-server-from-spambots
我們的想法是將禁令存儲在PHP(或其他)的數據庫中,但不要使用PHP進行任何過濾。 每個請求額外的數據庫命中可能是從快速到低速的轉折點。
執行阻塞的位是內核級防火牆iptables。 這由另一個只從數據庫中讀取的腳本更新。 如果你願意的話,你可以用簡單的CSV做一些類似的東西,並完全跳過數據庫聯系。
總之,iptables的不是一個完整的數據庫查詢的效率高得多 。
如果使用SQL,請確保轉義IP輸入。 我可能是偏執狂,但我已經通過$_SERVER['REMOTE_ADDR']
看到了各種各樣的廢話。
字符串。 它們不是數字,而是四個數字的排列。 IPv6是十六進制的。 字符串覆蓋所有基礎,處理成本很低。
您還應該知道服務器變量可能存在。 閱讀: 獲取用戶的真實IP
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.