Yapılan yeni düzenleme ile birlikte 5651 saylı kanun ile yer sağlayıcı firmalara getirilen, site erişim loglarını en az altı ay saklama yükümlülüğü en az bir yıla çıkarılmakta ve aksi durumlarda 100 bin TL’ye varan para cezaları öngörülmekte. Erişim loglarının saklanması süreci malesef zahmetli ve masraflı bir işlem. Çokça kullandığımız kontrol panellerini örnek alırsak, cPanel ve diğer tüm hosting yazılımları, erişim kayıtlarını, paneldeki bir dizi istatistiki veriyi oluşturmak üzere işlemekte ve bu işlem sonucunda yer tutmaması amacı ile silmekteler. Logların arşivlenmesi işleminin, hem kontrol paneli işlevlerini bozmaması, hem de arada kaçak olmaksızın yapılabilmesi gerekmektedir. Bu yazımızda, ar-ge ekibimizin ürettiği, cPanel erişim logu arşivleme sistemini sizler ile paylaşacağız.

cPanel loglarının daha düzenli,istenilen formatta alınabilmesi için en iyi yöntemlerden biri cPanel hooklarıdır.Bu hooklar cpanel bazı işlemleri gerçekleştirmeden önce,sonra veya işlem sırasında bize istediğimiz işlemleri yaptırma olanağı sağlar.

cPanel logları ile ilgili fonksiyonlar Stats Functions altında toplanmıştır.Bu fonksiyonlar RunAll(pre/post),RunUser(pre/post) olarak 4 ana fonksiyondan oluşmaktadır.Bu iki fonksiyonda logları işlemek için büyük önem taşımaktadır.

RunUser
RunUser fonksiyonu ile her kullanıcı için belirlemiş olacağınız hook çalışacaktır.Burada dikkat edilmesi gereken husus bu hook’un kullanıcı yetkileri ile çalıştırılacak olmasıdır. RunUser ile belirtilen hook, her kullanıcı için ayrı ayrı çağrılmaktadır. cPanel hookta beliritlen dosyayı çağırırken, stdin vasıtası ile, aktif işlem ile alakalı bilgiyi JSON formatında göndermektedir.

RunAll
RunUser fonksiyonu ile tüm kullanıcı stats işlemleri tamamlandıktan sonra çalışacak bir hook tanımlanabilmektedir. cPanel bu hook fonksiyonunu çağırırken herhangi bir data göndermez.

Hooklar birçok dille yazılabilmektedir ancak cPanel’in bize sunduğu örneklerden yola çıkarak Perl diliyle bir yedekleme hooku oluşturalım.

İlk olarak /usr/local/cpanel dizini içerisine hookumuzun yer alacağı bir dizin oluşturalım.Bu dizini paket ismimiz olarak kullanacağız.

mkdir /usr/local/cpanel/Netinternet

Sonrasında Perl modülümüzü oluşturalım.Bu modülü dilediğimiz ismi verebiliriz.

touch /usr/local/cpanel/Netinternet/NetinternetBackup.pm

Sonrasında basit bir perl modülü oluşturalım.Burada cPanel hooklarında bulunması gereken describe metodunu tanımlamamız gerekmektedir.Bu metod hookun ne zaman çalışacağını ve diğer önemli bilgileri içerir.Bu metodla cPanel & WHM’e hooku kayıt etmiş oluruz.Buradaki bazı bilgiler hookumuz eklerken komut satırı flag’leriylede belirtilebilecek olsada en güzeli modül içerisinde tanımlamaktır.Aşağıda bununla ilgili Perl ve Php örneğini görebilirsiniz.

package Netinternet::NetinternetBackup;
use strict;
use warnings;

sub describe {
my $hooks = [
{
'namespace' => 'Stats',
'function' => 'RunUser',
'hook' => 'Netinternet::NetinternetBackup::copy_logfiles',
'stage' => 'pre',
},
];
return $hooks;
}

sub copy_logfiles {

return 1;
}

1;


PHP Örneği

'Stats',
'function' => 'RunUser',
'stage' => 'pre',
'hook' => 'yedekal.php',
)
);

if ( in_array('--describe', $argv) ) {
print json_encode($describe);
exit();
}


Perl scriptimiz üzerinden devam edecek olursak yukardaki perl modülümüz ile basit bir modüle sahip olduk. Netinternet::NetinternetBackup::copy_logfiles kısmı Perl her bir kullanıcı için çalıştırılacak olan subroutine işaret etmekdir.Bu subroutine’i scriptimizde hali hazırda oluşturduk.Şimdi asıl işlemleri yapacak kısmı olan bir subroutine oluşturalım.

Basitçe yapmak istediğim her bir kullanıcı için

///

dizin yapısında logları kaydetmek.Bunun için bazı Perl modüllerine ihtiyacımız var.Tarihi işlemek için POSIX modülü , dizin yapısını oluşturmak için ise File::Path ve kopyalama işlemi için ise File::Copy modüllerine ihtiyacımız var.

package Ninet::NinetBackup;
use File::Copy;
use File::Path;
use strict;
use warnings;
use POSIX;


Bu modüller eklendikten sonra;
Tarih değişkenlerimizi subroutine içerisinde oluşturabiliriz.

my $year = POSIX::strftime('%Y', localtime());
my $mon = POSIX::strftime('%m', localtime());
my $mday = POSIX::strftime('%d', localtime());


RunUser pre ile kullanıcının aşağıda belirtilen verilerine ulaşmamız mümkündür;

{
'lastruntime' => "Unix formatında, bu kullanıcı için logların en son işlendiği zaman."
'user' => "O anda logları işlenen kullanıcı adı."
'homedir' => "İlgili kullanıcının ev dizini."
'rLOG_CONF' => "Hangi analiz programının kullanıcının hangi domaininde koşulacağını belirten bir hash."
'maindomain' => "Ana domain adı."
'rALLDOMAINS' => "Kullanıcıya ait tüm domainleri gösteren dizi"
'logfiledesc' => "O anda işlenen tüm logları belirten dizi."
{
'domain' => "Alan adı."
'filename' => "Log dosyasının adı."
'logfile' => "Log dosyasının tam yolu."
};
};


Kullanıcı adını alalım.

my ( $context, $args ) = @_;
my $user = $args->{'user'};


Kullanıcı bilgisi alındıktan sonra kullanıcının her bir domaini için yedekleme işlemi yapmamız gerekmektedir.Bunun için yukarıdaki RunUser verilerinden logfiledesc içerisindeki domainleri tek tek işlememiz gerek.

foreach my $log_ref ( @{ $args->{'logfiledesc'} } ) {

}


Artık $log_ref değişkenimizle her bir domaine ait verilere foreach içerisinde ulaşabiliriz.

Kullanıcı domain loglarımızı veriler içerisinden alalım ve verileri kopyalayacağımız dizini bir değişken olarak belirleyelim.

my $access_log = $log_ref->{'logfile'};
my $backup_location = "/yedek/$user/$year/$mon/$mday/" . $log_ref->{'domain'} . '.' . time();


Değişkenimizde belirttiğimiz dizin varmı kontrol edelim yoksa yeni bir dizin oluşturalım.

if ( !-e "/yedek/$user/$year/$mon/$mday" ) {
mkpath("/yedek/$user/$year/$mon/$mday/");
}


Scriptimizi terminal üzerinden denemeler yapmak ( /scripts/runweblogs ) bir geribesleme ekleyebiliriz;

print "Yedek " . $log_ref->{'domain'} . " domaini için su konuma aliniyor : $backup_location\n";

Artık loglarımızı kopyalamaya hazırız;

File::Copy::copy( $access_log, $backup_location ) || print STDERR $! . "\n";

Scriptimizin son hali;

package Netinternet::NetinternetBackup;
use File::Copy;
use File::Path;
use strict;
use warnings;
use POSIX;
sub describe {
my $hooks = [
{
'namespace' => 'Stats',
'function' => 'RunUser',
'hook' => 'Netinternet::NetinternetBackup::copy_logfiles',
'stage' => 'pre',
},
];
return $hooks;
}

sub copy_logfiles {
my $year = POSIX::strftime('%Y', localtime());
my $mon = POSIX::strftime('%m', localtime());
my $mday = POSIX::strftime('%d', localtime());
my ( $context, $args ) = @_;
my $user = $args->{'user'};
foreach my $log_ref ( @{ $args->{'logfiledesc'} } ) {
my $access_log = $log_ref->{'logfile'};
my $backup_location = "/yedek/$user/$year/$mon/$mday/" . $log_ref->{'domain'} . '.' . time();
if ( !-e "/yedek/$user/$year/$mon/$mday" ) {
mkpath("/yedek/$user/$year/$mon/$mday/");
}
print "Yedek " . $log_ref->{'domain'} . " domaini için su konuma aliniyor : $backup_location\n";
File::Copy::copy( $access_log, $backup_location ) || print STDERR $! . "\n";
}
return 1;
}

1;


Artık modülümüzü cPanel’e bağlayabiliriz.Bunun için yapmamız gereken sadece aşağıdaki komutu çalıştırmak;

/usr/local/cpanel/bin/manage_hooks add module Netinternet::NetinternetBackup

Bu işlemler sonucunda her bir cPanel kullanıcısı için istatistik verileri oluşturulurken, logların birer kopyası, belirttiğimiz dizine kopyalacaktır. Bu scripte isterseniz logların kopyalanırken sıkıştırılması gibi bir fonksiyon da ekleyebilirsiniz ancak bunun işlem süresini uzatabileceğini göz önünde bulundurun. Biz Netinternet’te sıkıştırma işlemleri logları ham halde aldıktan sonra yapmaktayız. Erişim dosyaları metin dosyalar oldukları için gunzip gibi araçlar ile %90 oranında sıkıştırma yapılabilmektedir.

Burada yenilenen kanun açısından bir konuyu daha belirtmek gerekiyor. Kanun maddesi, logların saklanmasının yanında bütünlüğünün korunması gibi bir sorumluluğu da işaret etmekte. Ancak teknik anlamda detaylandırılmamıştır.

Kaynak: http://blog.ni.net.tr/cpanel-sunucularda-5651-sayili-kanuna-uygun-log-arsivlenmesi/