MySQL un .htaccess banlistes veidošana (7)

@ 13.02.2010, 21:44

Kāds tad ir visvienkāršākais veids, kā lapā atbrīvoties no nevēlamajiem lietotājiem? Viens būtu satikt viņu un kārtīgi atštaukāt, taču ne vienmēr tas ir ātri un ērti izdarāms. Otrs būtu izveidot vienkāršu sistēmiņu, kas pārbaudīs vai IP adrese sakrīt ar lietotāja adresi un attiecīgi ļaus lietotājam piekļūt lapai vai nē.

Sāksim ar MySQL, vareni vienkāršs un diezgan ērts veids. Princips – nolasam no datubāzes banu tabulas visus ierakstus un pārbaudam, vai lietotāja IP adrese sakrīt ar kādu no tām. Ja sakrīt, tad attiecīgi rīkojamies. Kā tas izskatītos kodā:

<?
$kverijs = mysql_query("SELECT ip FROM bans WHERE ip = '".$_SERVER['REMOTE_ADDR']."'");
while($r = mysql_fetch_array($kverijs)) {
  if($r[0] == $_SERVER['REMOTE_ADDR']) {
    die('Tev nav piekljuves shai lapai!');
  }
}
?>


Otrs veids un, manuprāt, daudzkārt vienkāršāks ir ar .htaccess palīdzību. Vienkāršāks tamdēļ, ka nav jājauc iekšā datubāze un jāsalīdzina vērtības. Šis gan būs pieejams tikai lietotājiem, kuri izmanto Apache web serveri. Lai neatļautu piekļuvi kādai IP adresei, .htaccess failā ir jāieraksta pavisam vienkārša un īsa rindiņa:

deny from IP_adrese


Lai nebūtu katru reizi jākonektējas klāt FTP serverim un jārediģē .htaccess fails uzrakstīju vienkāršu skriptu – aizpildot formu, failam pievienosies klāt jauna rindiņa ar nobanoto IP adresi. Taču šis nebūs visai drošs veids, jo lai šo pasākumu realizētu, .htaccess failam nāksies mainīt tiesības (chmod), vismaz uz 0666 jeb rw-rw-rw-.

<?
$fails = $_SERVER['DOCUMENT_ROOT']."/.htaccess";
$saturs = file_get_contents($fails);
if(isset($_POST['ok'])) {
  $saturs .= "deny from ".$_POST['ip']."\n";
  file_put_contents($fails, $saturs);
  header("Location: ".$_SERVER['HTTP_REFERER']);
}
?>
<form action="" method="post">
  Ievadi IP adresi: <input type="text" name="ip" />
  <input type="submit" name="ok" value="Nobanot" />
</form>


Tas arī viss, lietotājs, kurš centīsies tikt mājas lapā, pretī saņems skaistu 403. kļūdas paziņojumu.

Komentāri (7)

1. x
@ 13.02.2010, 22:00

nus.. tā ir tikai skaista teorija.. praksē ir tā, ka ir simtiem webproxy, caur kuriem var apmeklēt lapu un aizliegumi uz konkrētu ip neko nepalīdzēs..

p.s. iečeko manu adresi :)

2. k4y
@ 13.02.2010, 22:05

Atkal ir tā, ka par kaut ko es nepadomāju, par prokšiem gan mazliet piemirsu. :) Tomēr pastāv tāda daļa lietotāju, kuriem proxy ir kaut kas svešs :D

3. deni2s
@ 13.02.2010, 23:46

Advancētāk ir ne tikai nobanot ip adresi, bet arī piemest banotajam lietotājam pirms tam cookie, kurā saglabātos info, ka šis ir banots. Un tiklīdz kāds ar tādu cookie ienāk lapā, tā nobanot pēc ip.

Tādā veidā arī nomainot ip adresi, bans saglabāsies.

4. k4y
@ 13.02.2010, 23:54

deni2s, ideja ir laba, katrā ziņā efektīvāka par prastu ip salīdzināšanu, taču, ja lietotājs ir pietiekami gudrs, tad gan jau pārbaudīs cepumus un ja būs kaut kas no attiecīgās lapas, tad to cepumu izdzēsīs un nāks pa jaunu.

5. deni2s
@ 14.02.2010, 00:02

nu tur ir jāpamanās iedomāties vienlaicīgi nomainīt gan ip, gan padzēst cookies ;)

Starp citu pirmo kodu var pārrakstīt, manuprāt, efektīvāk:

<?
$kverijs = mysql_query('SELECT * FROM bans WHERE ip="'.$_SERVER['REMOTE_ADDR'].'" LIMIT 1');
$r = mysql_fetch_array($kverijs);
if(mysql_num_rows($r)) die('Tev nav piekljuves shai lapai!');
?>

6. k4y
@ 14.02.2010, 00:08

Jā, to WHERE piemirsu pielikt, tas būtu noteikti ātrāk, vismaz skripts neskrietu cauri visiem ierakstiem vienlaicīgi. Labots.

7. Anpher
@ 16.02.2010, 12:10

LIMIT 1 droši vari piemest klāt un ciklu nahrenizēt :)
Vispār jau:
if(mysql_fetch_object(mysql_query("SELECT COUNT(*) AS c FROM `bans` WHERE ip=INET_ATON(".mysql_real_escape_string($ip).")"))->c > 0) die("Go home bitch!");

Ideja par datu kešošanu ir apsveicama, bet .htaccess diezvai būs labākais variants ... Man vienā otrā projektā bani glabājās iekš memcached, kur masīva atslēga ir ip2long($ip). Pati ip tiek veidota -> $ip = getenv(getenv('X-Forwarded-For') ? 'X-Forwarded-For' : 'REMOTE_ADDR');

P.S. Lietojot parasto webisko proxy, diezvai klienta cepumi vispār tiks sūtīti :) Tāpat arī maz ticams, ka X-Forwarded-For tiks padots

Ierakstīt komentāru

(vārds) *
(meils) (priekš gravatar)
(www)