Thursday, 14 May 2015

Regex Squid Configurations


Filter Web
Dari bagian pertama tutorial, kita telah mengenal karakter-karakter meta dasar. Di bagian dua, kita mengenal quantifier, escape, match group, modifier i/s/m/g, dan meninjau bagaimana berbagai bahasa
pemrograman mendukung regex serta seperti apa sintaksnya. Bagian ketiga, substitusi, modifier e, dan mengambil headline berita. Kali ini kita kembali tidak akan banyak membahas karakter meta atau sintaks baru regex dulu, melainkan melancarkan dan mempraktikkan ilmu regex kita. Karena edisi majalah ini membahas browser, kita akan bermain-main dengan proxy Privoxy dan Squid. Ternyata regex juga banyak berperan di sana. Seperti apa? Mari kita lihat bersama-sama.

Iklan di Web
Ada yang bilang iklan online melesu beberapa tahun terakhir. Para pengiklan menemukan banner tidaklah terlalu efektif sebagai media beriklan, dan orang sudah terlatih mencuekkannya. CPM (cost per mile) dan CTR (clickthrough rate) banner pun menurun terus secara konsisten. Artinya, efektivitas banner semakin menurun saja dan tidak semenguntungkan dulu.
Tapi ternyata pendukung banner tidaklah menyerah semudah itu. Mereka menempuh segala macam cara untuk menarik mata pengunjung. Memvariasikan ukuran: dulu 468x60 menjadi ukuran standar yang bisa dilihat di mana-mana, kini bisa dijumpai banyak banner vertikal atau yang bahkan lebih besar lagi ukurannya. Memanfaatkan Flash dan teknologi interaktif lainnya: membuat game atau animasi halus, bahkan membuat gambar yang melayang-layang ke sana kemari menutupi pandangan. Dan memanfaatkan fitur browser untuk menuai impression: iklan pop under dan banner tersembunyi di luar layar. Banner bisa merugikan kita karena memakan sejumlah bandwidth, mengganggu pandangan, dapat mengganggu privasi, dan kadang juga merusak mood.
Dan itu semua menjengkelkan kita bukan? Tentu saja. Sebagai orang yang sudah berpengalaman di Web—yang seringkali berarti harus memelototi halaman web berjam-jam setiap hari—tentu kita tidak mau harus menelan bulat-bulat setiap gambar atau teks kelap-kelip yang muncrat ke muka kita bukan? Tentu saja. Dan apakah dengan belajar regex kita dapat melakukan sesuatu yang berguna dalam hal yang satu ini. Tentu saja.
Memfilter Banner
Ada berbagai cara yang bisa digunakan untuk memblok banner.
Pertama, dengan memanipulasi file hosts (/etc/hosts di Unix, atau c:\Windows\Hosts di Win9x, atau c:\WinNT\System32\Drivers\Etc\Hosts di NT/2K/XP). File hosts adalah file yang berisi daftar IP hostname, dan biasanya selalu dirujuk dulu oleh sistem operasi (sebelum bertanya ke nameserver) saat ada sebuah hostname yang perlu dicari alamat IP-nya. Jika ada sebuah halaman web yang mengandung banner yang imagenya diambil dari ad.detik.com misalnya, maka kita bisa menaruh baris berikut di file hosts:
127.0.0.1    ad.detik.com
dan setelah kita merefresh atau merestart browser, maka browser akan menganggap ad.detik.com beralamat IP 127.0.0.1 (localhost) dan tidak menemukan banner yang dimaksud lalu menampilkan tanda broken image di halaman web. Kita bisa juga memasang webserver di alamat IP localhost ini, misalnya, untuk selalu menyajikan image titik transparan sehingga kita melihat ruang putih bersih pengganti banner. Apache dibantu dengan konfigurasi RewriteRule dapat melakukan hal ini.
Kedua, dengan memasang server DNS lokal dan mengambil alih zona. Kita mengeset komputer kita agar menjadi nameserver pilihan pertama, lalu mengeset DNS agar menjadi master bagi domain ad.detik.com. Terakhir kita mengisi A record ad.detik.com dengan 127.0.0.1 (atau 192.168.1.1, atau IP jaringan lokal lainnya). Efeknya sama seperti memanipulasi file hosts, yaitu membuat program browser menyangka IP ad.detik.com sebagai IP lokal dan gagal mengambil banner.
Cara pertama dan kedua ini memiliki kelemahan. Keduanya hanya bisa melakukan pemblokiran berdasarkan host. Jika ada situs portalku.com yang menaruh banner-bannernya di http://portalku.com/images/banners/, maka kita tidak bisa begitu saja memblokir seluruh host portalku.com, sebab itu berarti halaman-halaman kontennya pun akan terblokir. Lalu keduanya juga tidak berfungsi kalau kita mengeset proxy HTTP di browser, sebab dengan keberadaan setting proxy browser akan membypass baik file hosts maupun DNS. Selanjutnya, jika ada banner yang URL-nya memakai alamat IP, file hosts dan DNS sudah pasti dibypass. Dan terakhir keduanya tidaklah fleksibel karena… tidak mendukung regex! Jangankan regex, wildcard pun tidak didukung oleh file hosts.
Cara ketiga, dan yang paling memuaskan, adalah dengan memasang proxy HTTP sendiri di komputer atau jaringan lokal. Proxy adalah software khusus yang memang tugasnya menjadi gerbang filter, sehingga fitur pemfilterannya pun jauh lebih komplet dari browser. Dengan memasang proxy sendiri ada beberapa keuntungan yang kita dapat. Selain pemblokiran bisa lebih mendetil dan fleksibel, kita dapat mengirit bandwidth; rata-rata proxy juga berfungsi sebagai cache dan cache ini—tidak seperti cache browser—dapat dishare di beberapa komputer. Lalu kita memperoleh log akses yang bisa diamati dan distatistik.
Ada dua macam cara pemasangan proxy, yang pertama adalah secara eksplisit dan kedua transparan. Eksplisit maksudnya, kita memasukkan setting alamat proxy yang ingin digunakan ke browser (misalnya, di IE dengan menu Tools > Internet Options > Tab Connections > Tombol LAN Settings > Use Proxy Server. Browser jadi mengetahui keberaadan proxy ini dan untuk setiap request akan langsung meminta kepada proxy (kecuali untuk situs-situs tertentu yang telah kita set agar direquest langsung tanpa lewat proxy). Sementara transparan berarti, kita menggunakan packet redirection di gateway. Setiap paket keluar TCP/IP untuk port tujuan 80 (port HTTP) kita belokkan dulu ke port 8080 misalnya (port tempat proxy transparan mendengarkan koneksi). Lalu baru request yang dijebak ini diproses proxy. Jawaban dari proxy lalu dikembalikan kepada host dan port si peminta. Hasilnya, browser di komputer klien menyangka dia tidak memakai proxy, padahal sebenarnya ia melewati proxy.
Keuntungan proxy transparan adalah, tidak perlu mengeset alamat proxy di browser. Banyak sekali pengguna ISP—termasuk saya, kadang-kadang—yang malas mengeset proxy. Maklumlah, di komputer Windows saya saja terpasang setidaknya lima jenis browser berbeda dan kadang kala harus melakukan instal ulang sehingga setting program tereset. Capek harus mengeset ini itu. Karena itu rata-rata ISP selalu menggunakan proxy cache transparan di gateway mereka, sehingga pemakai yang tidak mengeset proxy pun saat browsing atau mendownload melewati proxy. Ini sangat penting buat ISP, demi pengiritan bandwidth.
Keuntungan lain proxy transparan, semua program—browser maupun nonbrowser—jadi ikut “tertangkap”. Belakangan ini banyak program-program yang juga diam-diam menyedot banner. Program filesharing KazaA misalnya, atau program download manager GetRight, atau program IM ICQ. Versi trial browser shareware Opera pun mengambil banner dari situs opera.com. Semua ini tidak tercatat di history maupun Temporary Internet Files, sehingga sulit bagi kita untuk memblokirnya. Dengan proxy transparan, terungkaplah request-request “rahasia” ini. Berikut ini misalnya cuplikan log akses Squid saya:
1024995409.430     14 192.168.1.2 TCP_MEM_HIT/200 2013 GET +
http://www.bns2.net/bns/new/B_741600.HTM - NONE/- text/html
1024995409.471      4 192.168.1.2 TCP_HIT/200 12228 GET htt+
p ://websponsors.com/leads/2973/Slingo_468_prizes_R.gif - N+
ONE/- image/gif
Request di atas diluncurkan oleh KazaA. Sementara:
1025385564.402      1 192.168.1.2 TCP_DENIED/403 1161 POST +
http://rps1.opera.com/scripts/cms/xrps.asp - NONE/- -
diluncurkan oleh Opera dari waktu ke waktu. Hm, Opera kira-kira mem-POST informasi apa ya? Lebih baik saya blok saja.
Proxy transparan memiliki kerugian pula, salah satunya adalah: beberapa browser kesulitan merefresh jika dirinya tidak menyadari keberadaan proxy. Internet Explorer misalnya, jika tidak diberi setting proxy secara eksplisit, hanya akan mengirim header refresh If-Modified-Since: sehingga gagal melakukan refresh karena objek berada di cache proxy. Sementara Netscape/Mozilla umumnya selalu mengirimkan perintah refresh Pragma: no-cache yang akan dipatuhi oleh proxy. Selain itu, tanpa kehadiran proxy maka jika kita memasukkan sebuah alamat di browser maka browser akan melakukan resolving dulu terhadap host alamat tersebut. Ini tidak perlu terjadi jika kita menggunakan proxy eksplisit, sehingga proxy dapat lebih cepat melakukan pemblokiran banner.
Jadi jika Anda menggunakan browser, sebaiknya memang mengeset saja secara eksplisit alamat proxy. Proxy transparan digunakan untuk menangkap request-request dari program lain yang tidak mengenal proxy. Atau bisa juga kombinasikan cara pertama/kedua dengan ketiga, kalau ada waktu.
Konfigurasi Squid
Squid, www.squid-cache.org, adalah software proxy cache HTTP dan FTP gratis yang banyak dipakai di server Unix. Squid dapat juga dipasang transparan (istilahnya, menjadi “HTTP accelerator”). Instalasi Squid secara mendetil di luar cakupan bahasan artikel ini, jadi berikut ini instruksi singkat untuk Red Hat 7.2.
Untuk memasang Squid sebagai proxy biasa (nontransparan), pertama-tama pastikan Anda telah menginstal paket RPM squid. Jika sudah, jalankan squid dengan mengetikkan perintah /etc/rc.d/init.d/squid start. Defaultnya Squid akan mendengarkan koneksi HTTP di port 3028. Untuk mengubahnya, editlah file konfigurasi squid di /etc/squid/squid.conf dan ganti baris http_port agar menjadi bernilai port yang Anda inginkan (misalnya: 8080). Setelah itu ketikkan killall -HUP squid dari shell agar Squid membaca ulang konfigurasinya.
Cobalah sekarang memasukkan alamat proxy Squid Anda (mis: 192.168.1.1:8080) ke browser. Lalu terhubunglah ke Internet. Setelah itu cobalah mengambil sebuah halaman Web seperti www.yahoo.com. Jika Anda mendapatkan halaman Forbidden seperti di Gambar 1, berarti konfigurasi ACL, atau daftar akses kontrol Squid, masih belum benar. Anda perlu mempelajari dulu seperti apa ACL di Squid, tapi untuk mudahnya—dalam rangka coba-coba—berikan baris http_access allow all di file konfigurasi Squid di atas semua baris http_access yang lain. ACL ini artinya perbolehkan semua akses HTTP (request Web) ke Squid. Squid memiliki banyak mekanisme kontrol akses, misalnya per waktu (siang-siang hanya boleh mengunjungi situs ini itu), per host sumber (anak-anak Lab Kendali tidak boleh browsing), per host tujuan (tidak ada yang boleh mengunjungi playboy.com atau groups.yahoo.com), dan tentu saja per pencocokan regex terhadap URL, yang nanti akan kita bahas.


Gb 1. Tampilan forbidden Squid
Untuk memasang Squid sebagai proxy transparan bagi komputer lain, pertama-tama pastikan Squid dan /sbin/iptables terinstal di server (mis: mesin yang beralamat IP 192.168.1.1). Lalu berikan perintah ini:
echo 1 > /proc/sys/net/ipv4/ip_forward
/sbin/iptables –F
/sbin/iptables -t nat -F
/sbin/iptables -P FORWARD ACCEPT
/sbin/iptables -t nat -A POSTROUTING -o ppp+ -j MASQUERADE
/sbin/iptables -t nat -A PREROUTING -i eth+ -p tcp --dport 80 \
  -j REDIRECT --to-port 8080
Perintah-perintah ini dapat ditaruh di /etc/rc.d/rc.local misalnya, agar selalu terjalankan manakala server diboot. Empat perintah iptables yang pertama untuk menyiapkan daftar rule untuk masquerading, yaitu agar komputer-komputer klien (mis: mesin-mesin beralamat IP 192.168.1.2, 192.168.1.3, dst.) dapat terhubung ke Internet melalui satu modem saja yang online di server. Perintah iptables terakhir meredireksi setiap paket yang datang dari komputer klien dan ingin menuju ke port 80, agar diarahkan ke port 8080. Kita lalu menginstal Squid di port 8080. Untuk opsi transparan, editlah konfigurasi Squid sehingga mengandung baris-baris berikut ini:
httpd_accel_host virtual
httpd_accel_port 80
emulate_httpd_log
Lalu restartlah Squid. Kini cobalah mengakses sebuah URL situs luar dari komputer klien. Maka Anda akan melihat bahwa request ini melewati Squid. Buktinya, Anda akan melihat baris log di /var/log/squid/access.log.
Jika Anda kesulitan mensetup Squid, cobalah meminta bantuan pada teman yang lebih ahli, atau bertanyalah di milis-milis Linux seperti linux-admin@linux.or.id. Jika ada waktu, Anda juga bisa mencoba membaca dulu manualnya secara tuntas. Di sana ada instruksi instalasi dan konfigurasi yang lebih mendetil.
Memfilter Dengan ACL
Pertama-tama kita akan mencoba memblokir banner dengan ACL Squid. Ingat bahwa pertama-tama ACL kita amat permisif: semua boleh menggunakan proxy, siapa saja, kapan saja, ke mana saja. Ini karena ACL kita hanya berisi seperti ini:
acl all src 0.0.0.0/0.0.0.0
http_access allow all
Baris pertama disebut baris ACL, yaitu yang menentukan apa yang tercakup. Baris kedua disebut baris operator ACL, yaitu menentukan apa yang diatur/dilarang. Kedua baris di atas berbunyi, “all artinya semua host sumber (peminta). Perbolehkan all mendapat akses proxy HTTP.”
Kita akan mencoba memblokir host dulu. Tambahkan baris-baris berikut sebelum ACL di atas, sebab Squid mencocokkan ACL dengan sistem first match. Kalau sudah cocok dengan sebuah rule, maka rule berikutnya tidak akan dicoba lagi. Karena itu kita hendak memblokir dulu host-host dan URL khusus, baru memperblehkan sisanya.
acl hostbanner dstdomain ad.doubleclick.net ad.ca.doubleclick.net m2.doubleclick.net
acl hostpopup dstdomain ads.x10.com www.desktopcollector.com webdp.gator.com
http_access deny hostbanner
http_access deny hostpopup
Baris-baris ACL di atas artinya, untuk host-host tujuan (dstdomain) seperti yang terdaftar di hostbanner dan hostpopup, jangan perbolehkan. Ingat, setiap kali selesai mengedit konfigurasi Squid, beri sinyal HUP pada Squid atau restart Squid agar file konfigurasi dibaca ulang. Jika Anda browsing lalu menemukan banner yang masih diload, catatlah nama hostnya lalu tambahkan ke dalam daftar ACL Anda. Saat ini di file konfigurasi Squid saya tercatat lebih dari 150–200 host banner. Lumayanlah, rata-rata situs yang sering saya kunjungi sudah bersih dari banner.
Sampai sejauh ini Squid tidak ada lebihnya dibandingkan file hosts atau bermain DNS. Bahkan kita belum menyentuh regex sama sekali. Tenang dulu.
Kelebihan Squid adalah mendukung regex. Dengan ACL jenis url_regex kita dapat memasukkan pencocokan regex untuk ACL. Misalnya, gambar-gambar ikon di Slashdot disatukan bersama banner di host images.slashdot.org. Tapi banner ditaruh di lokasi /banner. Mudah sekali bukan, kita tinggal menambahkan ACL ini:
acl urlbanner url_regex –i images.slashdot.org/banner
http_access deny urlbanner
Opsi -i adalah modifier case insensitive. Masih ingat bukan? Pola yang lebih tepat adalah barangkali:
^http://images\.slashdot\.org/banner
karena sebetulnya titik adalah karakter meta. Tapi dalam kasus ini saya jarang peduli akan regex yang “seakurat mungkin”. Bagi saya regex yang pertama sudah cukup dan sangat jarang meleset (toh kecil kemungkinan ada host bernama images-slashdot.org misalnya).
Berikut ini ada beberapa pola URL banner lain yang bisa Anda masukkan ke dalam daftar blok Squid Anda:
geocities.com/js_source/
angelfire.com/sys/
us.a1.yimg.com/us.yimg.com/a/
Biasanya untuk menyingkat tempat saya gabungkan saja beberapa pola sekaligus dengan menggunakan alternasi (|). Semua dalam satu baris:
acl urlbanner2 url_regex –i geocities.com/js_source/|+
angelfire.com/sys|us.a1.yimg.com/us.yimg.com/a/
dan baris operator ACL di bawahnya:
http_access deny urlbanner2
Restart Squid lalu rasakan bedanya!
Semakin panjang daftar ACL hostname dan regex URL yang Anda kumpulkan, maka untuk setiap request HTTP yang masuk Squid harus mencocokkannya dengan setiap pola. Tapi umumnya Anda tidak akan merasakan adanya perlambatan. Dalam satu detik bisa ratusan hingga ribuan pola regex yang dicocokkan oleh Squid, sehingga jauh lebih cepat dari kecepatan browsing Anda.
Berikut beberapa lagi pola regex yang saya comot dari squid.conf saya, just for fun:
fortunecity.[a-z]+/classification/
a.r.tv.com/cnet.[a-z0-9]+/Ads/
[a-z0-9]+.doubleclick.net
Untuk memblokir berdasarkan IP tujuan, gunakan ACL bertipe dst. Misalnya:
acl ipbanner1 208.63.69.8 64.200.58.83 151.196.147.197 205.188.250.25
acl ipbanner2 212.179.66.21
http_access deny ipbanner1
http_access deny ipbanner2

Lambang Broken Image Yang Jelek
Jika Anda mencoba memasukkan salah satu alamat yang diblok, katakanlah:
http://cb.icq.com/cb/533/datafiles/climage.cb
atau:
http://nitrous.exitfuel.com/code/kzpop.html
maka sebagai pengganti banner atau halaman Javascript banner yang sebenarnya, browser kita akan disuguhi halaman pesan error Squid, seperti di Gambar 1. Biasanya ini menghasilkan broken image atau kesalahan Javascript yang menjengkelkan karena kita harus menutup kotak dialog peringatan yang muncul. Atau jika muncul popup, meskipun popup-nya kosong atau hanya berisikan pesan error, tetap saja menjengkelkan karena masih harus ditutup. Ada beberapa cara untuk mengurangi kejengkelan ini.
Cobalah cari file /usr/lib/squid/errors/English/ERR_ACCESS_DENIED di server tempat Squid berada. Template inilah sebenarnya yang dipakai Squid dalam menampilkan pesan kesalahan karena pemblokiran. Cobalah menghacknya menjadi:
<script>function f(){return true;}window.onerror=f;self.close();</script>
<body bgcolor=ffffff text=ffffff>
<!-- <HTML><HEAD>
<TITLE>ERROR: The requested URL could not be retrieved</TITLE>
</HEAD><BODY>
<H1>ERROR</H1>
<H2>The requested URL could not be retrieved</H2>
<HR>
<P>
While trying to retrieve the URL:
<A HREF="%U">%U</A>
<P>
The following error was encountered:
<UL>
<LI>
<STRONG>
Access Denied.
</STRONG>
<P>
Access control configuration prevents your request from
being allowed at this time.  Please contact your service provider if
you feel this is incorrect.
</UL>
<P>Your cache administrator is <A HREF="mailto:%w">%w</A>.
--><xmp>
Pertama, kita menambahkan seksi kecil <script> agar semua error tidak perlu ditampilkan, plus perintah menutup diri sendiri. Lalu kita membuat warna teks menjadi putih seperti background, sehingga kata-kata pesan tidak terbaca. Terakhir kita menambahkan tag komentar dan <xmp> (hanya bekerja di IE). Hasilnya: rata-rata banner-banner <IFRAME> akan menjadi putih bersih, banner-banner kode Javascript akan tidak berefek menghasilkan kesalahan, dan window popup/popunder akan otomatis tertutup kembali. Cukup menyenangkan bukan? Oya, jangan lupa mereload Squid setelah mengedit file template ini, karena Squid mengcachenya juga di memori!
Tapi masih ada satu masalah, yaitu banner image biasa akan tetap muncul dengan ikon broken image. Apakah kita tidak bisa membuat Squid menghasilkan image titik kosong juga sehingga ruang banner menjadi putih bersih dan indah? Tentu bisa, dengan bantuan redirector.
Redirector
Redirector adalah sebuah proses eksternal (yang bisa berupa program buatan kita sendiri) yang akan diberi URL setiap request oleh Squid dan dapat memodifikasinya lalu mengembalikannya kepada Squid. Squid akan menjalankan redirector dan mengirimkan baris dengan sintaks berikut ke stdin program:
URL ip-address/fqdn ident method
Yang akan kita perhatikan saat ini hanyalah URL. Untuk setiap baris input, redirector harus mengeluarkan sebaris URL baru ke stdout, atau baris kosong jika tidak ingin mengubah apa-apa. Redirector juga bisa menyisipkan kode status respon di depan URL, misalnya: 301:http://server.com/blank.gif agar Squid memberikan redirect kepada klien. Redirector harus terus-menerus menerima baris input dari stdin dan tidak boleh exit; jika exit maka Squid akan kelabakan, sebab redirector ini jika dipasang akan terus ditanyai Squid untuk setiap URL request yang masuk.
Cara memasang redirector adalah dengan menambahkan baris konfigurasi berikut:
redirector_program /path/ke/program/atau/skrip/kita
Lalu restartlah Squid. Ketik ps ax. Anda akan melihat 5 buah proses anak skrip kita distart oleh Squid. Jumlah proses anak ini dapat Anda sesuaikan di squid.conf melalui baris perintah redirector_children. Defaultnya memang 5.
Program Perl berikut adalah redirector pembunuh banner sederhana yang bisa Anda pakai. Saya beri nama banner-killer.pl.
#!/usr/bin/perl -l

use URI::URL;
$|++;

%bdomains = map {$_=>1} qw(
    doubleclick.net
    egr.yahoo.com
    ads.mircx.com
    media.fastclick.net
    ads.tucows.com
    ads.targetnet.com
    image.linkexchange.com
);

%pdomains = map {$_=>1} (
    'exitfuel.com',
    'internetfuel.com',
    'pop.mircx.com',
    'gator.com',          # die, die you stupid crocodile!
    'bonzi.com'           # die, die you stupid gorilla!
);

@bregexes = (
    qr#images.slashdot.org/banner#i,
    qr#phpbuilder.com/RealMedia#i,
    qr#askmen.com/house_banners/#i,
    qr#global.msads.net/ads#i,
    qr#cnet.com/Ads/#i,
);

@pregexes = (
    qr#business2.com/subs/#i,
    qr#cnn.com/virtual/editions#i,
    qr#imesh.com/popup#i,
    qr#iklanbaris.co.id/pengumuman.htm#i,
    qr#www1.detik.com/komentar/khopingho.html#i
);

$btarget = "http://steven.server.localdomain/dotclear.gif";
$ptarget = "http://steven.server.localdomain/close.html";

URL:
while (<>) {
    ($url) = split;
    $u = URI::URL->new($url);
    $host = lc $u->host;

    # cocokkan host
    $_ = $host;
    do {
        if (exists $bdomains{$_}) {
            print $btarget; next URL;
        } elsif (exists $pdomains{$_}) {
            print $ptarget; next URL;
        }
        s/[^.]+(\.|$)//;
    } while $_;

    # cocokkan regex
    for (@bregexes) {
        if ($url =~ /$_/) {
            print $btarget; next URL;
        }
    }
    for (@pregexes) {
        if ($url =~ /$_/) {
            print $ptarget; next URL;
        }
    }

    # no match, so print empty line
    print "";
}
Ketik dan simpan ke file lalu set agar bisa dieksekusi. Setelah itu edit squid.conf dan masukkan path skrip ini di baris redirector_program.
Pertama-tama kita memasukkan daftar host banner dan popup yang ingin diblokir masing-masing ke hash %bdomains dan %pdomains. Ini dimaksudkan agar pengecekan bisa dilakukan dengan cepat, karena toh tidak butuh regex. Jika ada host di hash yang cocok dengan host URL, maka yang akan dicetak adalah masing-masing $btarget dan $ptarget. Nilainya bisa Anda ganti dengan URL di webserver lokal Anda sendiri. dotclear.gif adalah sebuah titik transparan yang akan menggantikan banner-banner. Sementara close.html berisi kode Javascript <script>self.close;</script> agar semua popup tertutup kembali secara otomatis.
Perhatikan baris dalam loop pencocokan host:
s/[^.]+(\.|$)//;
Mula-mula kita memberi nilai $_ berisi host dari URL. Tapi dalam mencocokkan, kita membabat bagian demi bagian $_ sampai habis untuk dicocokkan dengan hash %bdomains dan %pdomains. Misalnya, browser meminta URL http://ad.ca.doubleclick.net/blablabla.gif. Maka nilai $_ mula-mula adalah ad.ca.doubleclick.net. Ketika dicocokkan pertama kali, tidak ada yang cocok di daftar. Lalu regex tadi menghilangkan “ad.” (huruf a, d, dan titik). $_ menjadi bernilai ca.doubleclick.net. Tidak ada yang cocok juga. Kembali ke loop. Lalu terjadi pemotongan lagi menjadi doubleclick.net. Kali ini cocok dengan elemen di %pdomains. Maka Squid akan memberikan isi dotclear.gif pada browser. Tada! Tak ada lagi banner dari DoubleClick yang harus kita pelototi.
Jika tidak ada host yang cocok bahkan setelah $_ habis terbabat, maka kita lalu mencocokkan $url dengan deretan regex. Perhatikan @bregexes dan @pregexes. Setiap elemen array-array ini berisi regex yang dikutip dengan operator Perl qr(). Operator pengutip regex ini akan menyimpan versi regex yang sudah terkompilasi, dan dapat menyimpan setting modifier (pada contoh kita selalu memakai modifier i). Ketika kita mencocokkan lagi dengan ekspresi $url =~ /$_/, kita tidak perlu menyebutkan kembali modifier i, melainkan akan otomatis mengikuti setting case insensitive dari qr## yang telah disimpan sebelumnya.
Perhatikan bahwa, sekali lagi, saya tidak peduli dengan regex yang terlalu akurat. Titik pada regex tidak saya escape. Saya juga memberlakukan modifier i untuk semua regex, padahal hanya host saja sebetulnya yang case insensitive. Path yang berbeda huruf kapital/huruf kecil dapat saja berbeda isinya. Di Perl, kita bisa mengatur kelakuan case sensitive maupun insensitive untuk sebagian pola saja.

Pola Extended
Flavor regex Perl, dan juga PCRE, memiliki beberapa pola extended yang tidak ditemui pada mesin regex lain. Kita akan membahas dulu satu, yaitu (?:). Masih ingatkah Anda pada karakter meta ()? Ya, gunanya untuk mengelompokkan dan mengambil subpola/match group. Misalnya perhatikan substitusi ini:
s#(\w+)#exists $kamus{lc $1} ? $1 : "<font color=red>$1</font>"#eg;
Perintah di atas akan menangkap setiap kata (\w+) dan mengeceknya di hash %kamus. Kalau kata ini ada, maka tidak diapa-apakan, tapi jika tidak dikenal maka kita menambahkan tag <font> agar kata tersebut dihighlight merah.
Contoh lain untuk “menghidupkan” link:
s#\b((mailto|https?|ftp):\S+)#<a href=$1>$1</a>#g;
Perhatikan ada dua tanda kurung di situ. Tanda kurung terdalam dan terluar. $1 akan berisi seluruh URL, sementara $2 hanya berisi string protokolnya saja. Kita tidak membutuhkan string protokolnya sebetulnya, tapi karena kita harus mengelompokkan alternasi, maka kita menggunakan tanda kurung. Jika ada banyak tanda kurung seperti ini, maka sebetulnya ada pemborosan memori karena setiap subpola yang diberi tanda kurung akan diambil dan disimpan dalam match group. Regex Perl memiliki sintaks (?:) yang berfungsi hanya untuk mengelompokkan (clustering) tapi tidak untuk menangkap (capturing) subpola. Jadi kita bisa mengubah regex sebelumnya menjadi seperti di bawah, tanpa mengubah arti tapi membuatnya sedikit lebih efisien:
s#\b((?:mailto|https?|ftp):\S+)#<a href=$1>$1</a>#g;
Tadi saya mengatakan di Perl regex kita bisa berlaku case sensitive atau insensitive untuk subpola. Bagaimana caranya? Pola (?:) yang baru kita bahas tadi sebetulnya mengizinkan kita menaruh modifier di antara karakter tanda tanya dan titik dua. Modifier yang dapat ditaruh adalah i, s, m, dan x. Modifier x bisa juga ditaruh di belakang pola seperti biasa, dan akan dibahas pada kesempatan lain. Sementara modifier g dan e tidak relevan di dalam (?:). Berikut contoh regex untuk melakukan pencocokan bagian host secara case insensitive, tapi bagian path secara sensitive.
@s = qw(
  www.phpbuilder.com/RealMedia/1
  WWW.PHPBUILDER.COM/RealMedia/
  phpbuilder.com/realmedia/
);

for (@s) {
    print "$_ \t\t",
        m#(?i:phpbuilder.com)(?-i:/RealMedia)# ? "cocok":"tidak cocok",
        "\n";
}
Perhatikan tanda minus di depan modifier i kedua yang berarti tidak.

Mengambil Host Dari URL
Kembali ke skrip banner-killer.pl kita, coba lihat baris:
$u = URI::URL->new($url);
$host = lc $u->host;
Saya sedikit “curang” karena menggunakan modul yang sudah jadi (URI::URL) untuk memparse URL, padahal artikel ini tutorial regex. Mari kita mencoba mengambil sendiri host dari URL FTP atau HTTP dengan regex. Bagaimana caranya?
^(?:https?|ftp)://([^/]+)(?::|/|$)
Kita mengambil semua karakter hingga tanda titik dua (port) atau garis miring (awal path URI). Sehingga jika kita berikan http://mwmag.com/issue/06/ maka kita akan memperoleh string mwmag.com di match group $1. Sementara jika kita memberikan URL https://survey.mwmag.com:443/survey.html, maka $1 akan bernilai survey.mwmag.com.
Tunggu dulu, bagaimana dengan URL http://user:pass@www.host.com/blabla.html? Dengan regex sebelumnya, $1 akan bernilai user:pass@www.host.com padahal kita tahu hostnya adalah hanya string www.host.com. Regex sebelumnya perlu kita poles lagi menjadi:
^(?:https?|ftp)://(?:.+?\@)?([^/]+)(?::|/|$)
Kalau kita ingin menangkap bagian username dan password, maka kita bisa mengganti subpola (?:.+?\@) dengan (?:(.+?)\@) agar $1 mengambil bagian user:pass sementara nama host kini bisa ditemui di $2. Semoga Anda tidak kesulitan menerapkan semua ini di bahasa lain seperti PHP atau Python misalnya, sebab regexnya sama saja.
Memparse URL secara benar-benar sempurna (sesuai RFC) tidak sederhana. Karena itulah di skrip banner-killer.pl saya menggunakan modul yang sudah jadi. Agar tidak perlu terus-menerus berkutat dengan regex yang itu-itu lagi.

Privoxy
Privoxy, sebelumnya bernama JunkBuster, adalah sebuah software proxy lain yang gratis. Tersedia untuk Windows maupun Unix. Bedanya dengan Squid, Privoxy melakukan manipulasi konten. Squid sendiri paling banter hanya memanipulasi beberapa header request dan respon. Isi respon, seperti halaman HTML atau gambar, sama sekali tidak disentuh. Sementara Privoxy memfilter juga konten karena tujuan utama program ini adalah untuk penyensoran.
Instalasi Privoxy mudah sekali. Cukup download atau ambil instaler dari CD, lalu jalankan. Di Linux, instal paket RPM yang disediakan. Setelah Privoxy berjalan, set-lah browser Anda agar menggunakan proxy localhost:8118.
Mengapa saya membahas Privoxy? Karena file konfigurasinya penuh dengan regex! Dapat Anda pelajari dan amati satu-persatu sebagai bahan latihan.
Konfigurasi Privoxy defaultnya berada di c:\Program Files\Privoxy\config, default.filter, dan default.action. Lokasi log di c:\Program Files\Privoxy\privoxy.log. Mari kita lihat beberapa contoh di default.filter, yaitu daftar rule yang dipakai untuk memfilter konten:
s*<blink>|</blink>**ig
Sintaks regex di konfigurasi Privoxy mirip dengan di Perl. Contoh di atas menghapus tag pembuka atau penutup <blink> sehingga teks yang diapit menjadi tidak berkedip lagi. Sebetulnya sekarang <blink> jarang kita lihat karena tidak didukung browser-browser baru, tapi… tidak ada ruginya kan?
Berikut contoh lain yang sedikit lebih kompleks (semua dalam satu baris):
s/<img\s+[^>]*?(width|height)\s*=\s*['"]?1\D[^>]*?(width|hei+
ght)\s*=\s*['"]?1(\D[^>]*?)?>/<!-- Squished WebBug -->/sig
Regex di atas mengganti semua tag <img> yang berukuran satu kali satu, dan menggantinya dengan komentar. Perhatikan bahwa di kedua atribut kita memasang (width|height) karena bisa saja urutannya terbalik.
Contoh lain yang saya sukai:
s/window.status\s*=\s*['"].*?['"]/dUmMy=1/ig
Regex ini berusaha membunuh kode Javascript yang mengubah-ubah status bar dengan scrolling text atau tulisan-tulisan menipu atau mengganggu lainnya.
Ada banyak contoh lain. Anda dapat mempelajarinya sendiri.
Kelemahan Privoxy dibandingkan Squid, seperti yang mungkin telah Anda rasakan, adalah tidak bisanya sebuah halaman distream. Privoxy harus mendownload keseluruhan halaman konten dulu (apakah itu 10KB, 100KB, atau 1MB) lalu menjalankan berbagai substitusi regex seperti yang termuat di file konfigurasinya. Baru setelah selesai dipermak, halaman hasilnya diberikan kepada kita. Selama mendownload halaman, kita harus menunggu. Sementara Squid dapat melakukan streaming karena tidak menyentuh konten sama sekali. Jika dapat 1000 byte konten dari modem, langsung 1000 byte tersebut diberikan lagi kepada klien browser. Kita langsung dapat melihat halaman sedikit demi sedikit dirender menjadi lengkap. Ya, itulah risiko content filtering.
Jangan lupa membaca FAQ Privoxy untuk mengenal lebih lanjut cara penggunaan software ini.

Lakukan Yang Anda Suka
 Selain memblokir banner, ada banyak lagi yang bisa Anda lakukan. Benci Flash setengah mati? Ingin memblokir semua .swf dari proxy?
$url =~ /\.swf$/i
Atau semua PDF? Semua Javascript diganti dengan halaman kosong?
Dengan Squid atau Privoxy pun, Anda bisa mengalahkan atau mencuekkan situs-situs yang gemar sekali mengirim Pragma: no-cache atau Expires: yang pendek-pendek (seperti geocities.com atau groups.yahoo.com) agar bisa mengirit bandwidth dan meningkatkan responsivitas browsing. Atau membuang cookie dari situs-situs yang Anda curigai (dan karena dilakukan oleh proxy, setting ini tak perlu Anda masukkan berulang-ulang ke setiap browser yang Anda pakai). Atau mengganti header request User-Agent sehingga webserver di seberang sana tak perlu tahu Anda pakai browser atau OS apa. Atau memasang banner di Cnet atau detikcom secara gratis! (setidaknya di jaringan lokal). Semua kendali di tangan Anda.
Satu PR atau tantangan untuk Anda. (Catatan: hanya untuk tujuan edukasi. Saya tidak bertanggung jawab atas segala sesuatu yang terjadi akibat tindakan Anda.) Cobalah menggunakan Squid saja, atau Privoxy saja, untuk membersihkan seluruh halaman depan www.detik.com dari banner, baik itu banner image biasa, banner Flash, atau scrolling applet di sisi kanan, maupun semua pop up yang kadang muncul. (Untuk menghilangkan banner teks, diperlukan Privoxy karena menyangkut manipulasi konten). Jadikan semua space banner menjadi sama dengan latar belakang (dotclear.gif) sehingga semua nampak putih bersih. Setelah itu, bandingkan ukuran total halamannya. Maka Anda akan mengetahui berapa persen dari ukuran total halaman yang Anda download, yang sebetulnya adalah iklan.
Penutup
Regex adalah sebuah bahasa. Bisa dikata bahasa yang mini karena sintaks dan aturannya tidak sekompleks atau sebanyak bahasa pemrograman pada umumnya, namun tetaplah bahasa. Dan yang namanya bahasa, untuk menguasainya adalah dengan banyak latihan. Cobalah temui berbagai program yang mengizinkan regex dalam sintaks konfigurasinya, dan pakailah. Atau dalam bahasa pemrograman yang Anda pakai, saat ingin mengolah string cobalah menggunakan fasilitas regex. Maka niscaya Anda akan semakin lancar dan fasih menulis dan membaca regex. (sh)
Rujukan
Squirm, salah satu redirektor Squid untuk memblok banner, squirm.foote.com.au
Privoxy, www.privoxy.org
Internet JunkBuster, cikal bakal Privoxy, www.junkbusters.com
Halaman manual Perl bagian regex (perlre)
mw
Arsip mwmag



No comments:

Post a Comment