Uslanmayan Robotlardan ve Akılsız Ajanlardan PHP Scriptlerinizi Nasıl Korursunuz
Günümüzde php scriptlerimiz artık oldukça yoğun işler yapıyor.
Veritabanlarımızda fink atıyor, verileri derleyip toplayıp ayıklıyor,
şablona geçirip sunuyor ve durmaksızın çalışıyorlar. İnternet geniş bant
hızındaki artışa paralel olarak da git gide daha çok gelen aynı andaki
istekleri karşılamaya yetişiyorlar. Aslında yetişemiyorlar. Hosting
firmaları ya da sunucu sorumluları sistem yenilemekten ve optimize etmekten
yoruldu. Hadi hosting firmaları çözümü fazla bantgenişliği fiyatlarını
arttırmakta buluyor da, zavallı üniversitelerimiz, kurumlarımız ya da
kendi sunucularını işleten kobi firmalarımız ne yapsın?... En iyisi onlar da
bu yazıyı okusun.
Sunuculara asıl yük oluşturanların başında aslında kullanıcılar değil de
akıllı olduğu varsayılan robotlar ve akıllı ajanlar (intelligent agents)
geliyor. Kendi sunucunuzun akıp giden log'larını matrix izler gibi takip
ediyorsanız biliyorsunuzdur. Bazen bu robotlar ısrarla aynı anda akın
ederler. Üstelik de bunların çoğu, robots.txt yasamızı tekerlekleri altında
ezerek gelir. robots.txt dosyanıza riayet edenlerse, robots.txt
değişikliklerini kendi büyüklüklüklerinden 1-2 gün geç algıladıklarından
gene size zararları dokunur.
Akıllı Ajanların ve Tarayıcı Robotların Zararları Şöyle:
1. Scriptiniz bir geçit scriptidir, internetten birşey indirip regexp vs.
ile sağını solunu burkalayıp yeni bir site içine gömüyordur (phproxy, borsa
ticker, dinamik bir rss feed arayıcı vs. gibi). Bu durumda robotlarca
indekslenmeye çalışılacak bu scriptiniz hem çılgınlar gibi bant
genişliğinizden yiyecek hem de işlemcinizi yoracaktır. Geçidinizi kötü
niyetli kullanmaya kalkacaklar da cabası (sizi tünel niyetine kullanıp mp3
film vs. çekmeye uğraşanlara geçit vermemelisiniz).
2. Scriptiniz bir kullanıcı scripti olabilir. Mesela bir kullanıcının
nadiren bakacağı bir ekran olarak planlamışsınızdır ve yoğun olarak, o
kişinin sitede yaptığı aktiviteleri veritabanından küme birleşimleri vs.
ile çekerek gösteren bir scripttir. Cümle karışık oldu ama bu sık
karşılaşılan bir durum. Kullanıcı kimliğine göre pek çok veritabanı
tablosunda çapraz sorgu yapılır, belli kriterlere göre sıralanır ve
gösterilir. Mesela bir sosyal imleme sitesi ise, veya ajaxlı birşeyse o kişi
kaç oy vermiş nerelere vermiş, onu kimler arkadaşı yapmamış, kimler kara
listeye almış, bu kişi en son ne yazmış ve ona kimler ne yanıt yazmış vs.
vs. vs. Kısaca işlemci gücü açısından pahalı sorgular yapan scriptlerinizi
zora sokar aynı anda gelen robot ve ajan yüklemeleri. Üstelik eğer bir
hosting firmasında ise siteniz, firmadan uyarı almanız ya da hesabınızın
dondurulması an meselesi olabilir.
3. Scriptiniz yoğun bir kayıt tutuyordur. Her ziyaret pek çok dosyanın
açılmasına ve yazılmasına sebep oluyor olabilir. Bir robot akını anında
sabit disk sürücünüz RAID-0 SCSI bile olsa sizi zora sokacaktır.
4. hotscripts.com gibi bir siteden ne idüğü belirsiz bir kod
yüklemişsinizdir ve işlemcinizle bantgenişliğiniz sizin haberiniz olmadan
çarçur ediliyor olabilir.
Özetle buraya size özel durumlar da ekleyebilirsiniz. Scriptinizde
öngöremediğiniz ya da zamanının olmadığından ilgilenemediğiniz verimlilik
sorunları olabilir. En iyisi o sorunları giderene dek akıncılara, karşı en
pratiğinden bir duvar çekmek:
403: YASSAK HEMŞERİM
İnternette birşeyler arayan bu akıllı ajanları (mesela spam için eposta ya
da birilerinin telefon numarasını veyahut da telif ihlali arıyor olabilirler),
bir nebze olsun durdurabilmek için robots.txt'yi de ilgili kurallarla
dolduralım gene; ne kadar köşeye sıkıştırsak o kadar kârdır. Ama daha iyisi
USER_AGENT'a yazmış olabilecekleri kimliklerinden ve IP'lerinden engelleyelim.
Ve saptadıklarımıza 403 Forbidden başlığı gönderelim gitsin.
PHP içinde robot adını HTTP_USER_AGENT özel sunucu değişkeni ile
öğrenebiliyoruz:
$adamimiz=$_SERVER['HTTP_USER_AGENT'];
İşte bu değişken içindeki kimlik bilgilerini olağan şüphelilerle
karşılaştıracağız. Yakaladığımıza da şu şekilde kapıyı göstereceğiz:
header(' ',true,403);
exit;
Yalnız PHP 4.3'ten daha eski bir PHP sürümü kullanıyorsanız header('Status:
403 Forbidden'); demeniz gerekecek. Neyse...
Olağan şüphelilerimizi listeleyelim:
cat /var/log/apache/Web_Sitenizin_Kaydi-access_log|grep robots.txt|sort -u|more
Bu satırda apache'nin loglarında robots.txt'yi aramış olan iyi niyetlileri
seçip ikinci ".." çift tırnak grubundaki user_agent bilgilerini cut ile
aldık ve sort'un -u parametresi ile aynı olan satırları sildirdik.
Örneğin ben şimdi yazıya azıcık ara verip yaptım şunlar çıktı:
ArabyBot (compatible; Mozilla/5.0; GoogleBot; FAST Crawler 6.4; http://www.araby.com;)
Baiduspider+(+http://www.baidu.com/search/spider_jp.html)
BilgiBot/1.0(beta) (http://www.bilgi.com/; bilgi at bilgi dot com)
DidikleBot/0.1; http://www.didikle.com/
FAST MetaWeb Crawler (helpdesk at fastsearch dot com)
Gigabot/3.0 (http://www.gigablast.com/spider.html)
holmes/3.11 (http://morfeo.centrum.cz/bot)
ia_archiver-web.archive.org
Java/1.6.0_02
Lsearch/sondeur
Mediapartners-Google
MJ12bot/v1.2.0 (http://majestic12.co.uk/bot.php?+)
Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; Girafabot; girafabot at girafa dot com; http://www.girafa.com)
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)
Mozilla/5.0 (compatible; BecomeBot/3.0; +http://www.become.com/site_owners.html)
Mozilla/5.0 (compatible; Charlotte/1.0b; http://www.searchme.com/support/)
Mozilla/5.0 (compatible; Exabot/3.0; +http://www.exabot.com/go/robot)
Mozilla/5.0 (compatible; Yahoo! Slurp China; http://misc.yahoo.com.cn/help.html)
Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)
Mozilla/5.0 (Twiceler-0.9 http://www.cuill.com/twiceler/robot.html)
Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.4) Gecko/20070515 Firefox/2.0.0.4 (larbin@unspecified.mail)
msnbot/1.0 (+http://search.msn.com/msnbot.htm)
msnbot-media/1.0 (+http://search.msn.com/msnbot.htm)
MSRBOT (http://research.microsoft.com/research/sv/msrbot/
Pagebull http://www.pagebull.com/
page_verifier (http://www.securecomputing.com/goto/pv)
Pockey-GetHTML/4.11.6 (Win32; GUI; ix86)
psbot/0.1 (+http://www.picsearch.com/bot.html)
SBIder/SBIder-0.8.2-dev (http://www.sitesell.com/sbider.html)
Snapbot/1.0 (Snap Shots, +http://www.snap.com)
Sogou Orion spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)
Sogou web spider/3.0(+http://www.sogou.com/docs/help/webmasters.htm#07)
Speedy Spider (http://www.entireweb.com/about/search_tech/speedy_spider/)
StackRambler/2.0 (MSIE incompatible)
SurveyBot/2.3 (Whois Source)
Turkce-Arama/GezginBot v0.1 - (http://www.turkce-arama.com/)
VadixBot
Yahoo-MMCrawler/3.x (mms dash mmcrawler dash support at yahoo dash inc dot com)
Yeti/0.01 (nhn/1noon, yetibot@naver.com, check robots.txt daily and follow it)
Evet, dikkat edersek çoğunda geçen ortak bir sözcük bulabilir bir taşla,
yani bir regexp ile pek çok kuş vurabiliriz. Mesela "bot" sözcüğü epey
kullanılmış. Bakalım bunu ayrı tutunce geriye neler kalıyor. grep -v ile
listeletelim:
cat /var/log/apache/Web_Sitenizin_Kaydi-access_log|grep robots.txt|grep -v -i bot | sort -u |more
Yarı yarıya azaldı. Geri kalanlarda spider sözcüğü de dikkat çekiyor; "bot"
ve "spider"'ı her halükarda kullanmaya karar vererek diğerlerine göz atıyoruz:
cat /var/log/... | grep -v -i -e bot -e spider |sort -u
İçlerinden robot adlarını cımbızla seçip alalım:
fastsearch
ia_archiver
Lsearch
searchme
Slurp
larbin
Pagebull
page_verifier
SBIder
GetHTML
StackRambler
MMCrawler
Mediapartners
Sonuncuyu isterseniz almayabilirsiniz. Bu Adsense'in robotu. Ama zeten
robotlardan uzak tutacağınız bu scriptte olasılıkla reklama yer olmasa
gerek. Fakat zaten sadece javascript ile sayfanız açıldığında koşturur bu
robot. Biz şimdilik onsuz idare edip bir dizi (array) oluşturalım:
$istenmeyenler=array("/bot/i", "/spider/i", "/fastsearch/i", "/ia_archiver/i", "/Lsearch/i", "/searchme/i", "/Slurp/", "/larbin/i", "/Pagebull/i", "/page_verifier/i", "/SBIder/i", "/GetHTML/i", "/StackRambler/i", "/MMCrawler/i", "/Lynx/i", "/sphider/i", "/lwp-request/i");
Evet... Son 3'ünü de ben ekledim. Aslında daha epey var. Fakat ben başka
önlemler yüzünden onları log'larda zaten göremiyorum. Bu diğer önlemleri de
3-5 yıl önce başka bir yazıda anlatmıştım. Spam amaçlı mektup adresi toplayan robotlara
engel koyma yöntemleri anlatılıyordu o yazıda da...
Şimdi ise USER_AGENT'ın içinde bu dizidekilerden biri var mı diye bakalım.
Bu arada dizideki tırnak içi ifadeler regexp denklikleri, ve sonlarındaki 'i'
harfi de büyük küçük harf ayrımı önemsiz anlamına geliyor. Bu regexpleri
preg_match php işlevi ile tek tek de kontrol edebiliriz. Ama bunu bizim için
yapacak bir başka işlev icat etsek daha kullanışlı olur gibi:
<?php
function toptan_preg($dizi, $kimlik) {
$varmi = false;
if (is_array($dizi)) {
foreach ($dizi as $d) {
if (preg_match($d, $kimlik)) $varmi = true;
}
} else {
// yanlışlıkla dizi yerine normal bir harf dizgesi (string) vermişsek:
if (preg_match($dizi, $kimlik) ) $varmi = true;
}
return $varmi;
}
?>
Bunu kolaylık olsun diye kaydedelim bir yere. Mesela "islevler" diye bir
klasör açıp web sayfasının ana dizininde, içine "islev.toptan_preg.php"
adıyla kaydedelim gitsin.
Evet, şimdi bu işlevi kullanalım bakalım:
Bunları php scriptimizin en başına yazıyoruz
<?php
require_once("islevler/islev.toptan_preg.php");
$agent=$_SERVER['HTTP_USER_AGENT'];
$istenmeyenler=array("/bot/i", "/spider/i", "/fastsearch/i", "/ia_archiver/i", "/Lsearch/i", "/searchme/i", "/Slurp/", "/larbin/i", "/Pagebull/i", "/page_verifier/i", "/SBIder/i", "/GetHTML/i", "/StackRambler/i", "/MMCrawler/i", "/Lynx/i", "/sphider/i", "/lwp-request/i");
if ( toptan_preg($istenmeyenler,$agent) ) {
header(' ',true,403);
exit;
}
?>
Kimliğe göre engel için yapılacakların hepsi bu kadar. Gayet kolay. Yalnız
ara ara log'ları yeniden gözleyerek olası yeni robot ve ajanları da
eklemekte yarar var.
Şimdi benzerini IP'ler için yapalım. Loglarımızı tarayarak robots.txt ile
ilgilenenleri ya da ilgili hassas scriptimiz ile ilgilenenleri bulacağız:
cat /var/log/apac..... |grep -i robots.txt|cut -f1 -d\
Dikkat! cut komutunun en sonundaki ters bölü işaretinden sonra bir boşluk
var. log satırlarının en başında yer alan IP adresini kesip çıkarmak için
gerekli o boşluk. Yalnız şimdi bir sürü IP'miz oldu. Biz bunları önem
sırasına göre dizsek güzel olurdu. Yapalım bari, boşluklar unutulmadan hepsi aynı satıra giriliyor:
i=0;onceki="yok";(cat /var/log/...access.log|grep robots.txt|cut -f1 -d\ |sort;echo EOF)|while read ip;do if [ "$ip" != "$onceki" ];then
j=$i;echo -e "$j\t$onceki";onceki=$ip;i=0;fi;let i=$i+1;done|sort -rn|grep -v yok
İşte Pardus ya da bir Linux, Unix vb. kullanmanız için bir sebep daha. Tek
satırlık kara büyüler yapmanıza olanak tanıyor.
Yukarıdaki tek satırlık (gemicik kadar) komutçukta log'lardan çıkardığımız IP'leri bulunma
sıklıklarına (frekanslarına) göre dizdik. Algoritma mantığımız basitti. Önce
elimizdeki IP'leri dizdik. Sonra tek tek okumaya başlayıp içimizden saymaya
başladık. Yeni okuduğumuz IP bir öncekinden farklıysa kaça kadar saydığımızı
ve önceki IP'yi ekrana bastık. Kaçta kaldığımızı unutarak sayacımızı
sıfırladık. Şimdiki değişmiş IP'yi önceki IP adayı olarak ilan ettik ve
yolumuza devam ettik. Tüm IP'ler bitince de sort komutuyla, numerik ve ters
sıraladık. Böylece Büyükten küçüğe doğru, ve daha fazla ziyaret eden IP'ler
yukarıda olacak şekilde sırlandı hepsi. Şu, içinde 'yok' ve 'EOF' sözcüğü geçen
kısımlar ise işin püf noktası. İlk IP'den öncekini bilemeyeciğimiz ve son
IP'den sonra zınk diye durduğumuz için kullandık onları. cat ve echo EOF
komutunu parantez içinde kullanarak ikisinin ortak çıktısını tek bir boru
hattıyla (pipe '|') while döngüsüne verebildik.
Bu işten sonra elimizde biriken IP'lere bir göz atalım:
66.249.72.170
131.107.151.112
66.249.66.161
131.107.151.157
88.131.153.91
65.55.212.98
65.55.212.144
65.54.188.77
209.249.86.17
64.1.215.165
...
Hımm. Kim ki bunlar? host komutuyla bir ikisini yoklayalım:
$ host 66.249.72.170
170.72.249.66.in-addr.arpa domain name pointer
crawl-66-249-72-170.googlebot.com.
Evet. bu tanıdık.
En iyisi hepsine bir bakalım:
cat Az_onceki_liste.txt | cut -f2-|while read str;do echo -n -e "$str ";host $str;done|grep -v "not found"|cut -f1,6 -d\
Bu da ufak bir büyücük. Satır satır okuyup IP'yi yazdırdık ama '-n'
parametresi ile bir alt satıra geçmesini engelledik. Ardından host komutu
ile IP'ye baktık. Bir kayıt bulduysa bunları sadece IP ve DNS çözümü olacak
şekilde yazdırdık.
Şöyle bir sonuç çıktı:
66.249.72.170 crawl-66-249-72-170.googlebot.com.
66.249.66.161 crawl-66-249-66-161.googlebot.com.
88.131.153.91 speedyspider.entireweb.com.
65.55.212.98 livebot-65-55-212-98.search.live.com.
65.55.212.144 livebot-65-55-212-144.search.live.com.
65.54.188.77 livebot-65-54-188-77.search.live.com.
64.1.215.165 crawl-9.cuill.com.
208.36.144.10 crawl-19.cuill.com.
74.6.25.151 lj511497.crawl.yahoo.net.
74.6.23.235 lj511797.crawl.yahoo.net.
74.6.22.216 lj511938.crawl.yahoo.net.
...
Hepsi de bildik şeyler. Biz bunları çok ziyaretten az ziyarete olacak
şekilde sadece belli bir kısmını seçip kullanırsak az IP ile derdimizin
çoğundan kurtuluruz. Yüzlerce IP var. Ama kimisi sadece bir kez yoklamış
mesela pahalı scriptimizi, kimisi ise bir saatte yüz kez. İşte biz bu sorunlu
tırtıklayıcılara odaklansak yeter. Beş on IP'den fazlası zarar. Sistemi
yükten kurtaracağız derken ek yüke sebep olmayalım.
Bunlardan tepedekilerini bir diziye hemencecik yazalım:
$istenmeyenipler=array("/66.249.72.170/", "/131\.107\.151\./", "/66.249.66.161/", "/88.131.153.91/", "/65\.55\.212\./", "/65\.54\.188\./", "/64\.1\.215\./");
Ziyaretçinin IP'sini de öğrenelim. Belki iletişimin bir noktasında bir proxy
vardır diyerek dikkatlice doğru IP'yi seçelim:
if ( $_SERVER['HTTP_X_FORWARDED_FOR'] ) {
$ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip=$_SERVER['REMOTE_ADDR'];
}
$ipp=explode(" ",$ip);
if ( $ipp[count($ipp)-1] != "" ) $ip=str_replace(",","",$ipp[0]);
Ve bunu yukarıdaki gibi ilgili scriptin başlarına yerleştirerek kullanalım:
if ( toptan_preg($istenmeyenipler,$ip) ) {
header(' ',true,403);
exit;
}
Evet, bitti! Teşekkürler Unix. Teşekkürler Linux. Teşekkürler Pardus.
Unix felsefesi sayesinde istediğimizi kolayca, pratik bir şekilde, tıpkı
lego parçalarıyla oynar gibi küçük kısa komutları ardarda ekleyerek elde
edebildik.
İlker Fıçıcılar
24 Eylül 2007
İlgili Benzer Yazılar:
Arama önerileri:
robot,
user agent,
intelligent agent,
web spider,
tarama,
arama motorları,
akıllı ajanlar,
yapay zeka,
data mining,
veri madenciliği,
web sunucu ayarları,
php script,
script örnekleri,
Kaynak gösterecekler için referans:
"Uslanmayan Robotlardan ve Akılsız Ajanlardan PHP Scriptlerinizi Nasıl Korursunuz",
İlker Fıçıcılar,
http://www.KlavyeMonitor.com/php_scriptlerini_sunucuyu_yavaslatan_robotlardan_korumak.html
, Eylül 2007
|