BLOG

ANASAYFA > BLOG > + cPanel sunucularda 5651 sayılı kanuna uygun log arşivlenmesi
2014-02-19

cPanel sunucularda 5651 sayılı kanuna uygun log arşivlenmesi

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


<kullanici_adi>/<yıl>/<ay>/<gun>

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.”
‘rLOGCONF’ => “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 copylogfiles {
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. Veri bütünlüğü konusu bir başka yazıda ele alacağız.

Avatar
Abdullah Altunbaş Teknik Şef
Netinternet de Teknik Birim Şefi olarak 2011 yılından itibaren çalışmaktayım.
Yorumlar
Avatar
Barış 10 yıl önce

Haftalardır bomboş klasör hook olarak eklendi sorun ne olabilir?

Avatar
Timur 10 yıl önce

Merhaba aşağıdaki hataya göre Yazma iznini bu dosyaya nasıl nasıl verebiliriz ? teşekkürler.

[2014-11-21 23:14:08 +0200] warn [cpanellogd] mkdir /usr/local/cpanel//Netinternet/yedek: Permission denied at /usr/local/cpanel/Netinternet/NetinternetBackup.pm line 28

at /usr/local/cpanel/Cpanel/Hooks.pm line 288

Cpanel::Hooks::exec_module(‘main’, HASH(0x35e5708), HASH(0x35ca590), HAS H(0x35ca9e0)) called at /usr/local/cpanel/Cpanel/Hooks.pm line 131

Cpanel::Hooks::exec_hook(‘main’, HASH(0x35e5708), HASH(0x35ca590), HASH( 0x35ca9e0)) called at /usr/local/cpanel/Cpanel/Hooks.pm line 60

eval {…} called at /usr/local/cpanel/Cpanel/Hooks.pm line 55

Cpanel::Hooks::hook(HASH(0x35ca590), HASH(0x35ca9e0)) called at /usr/loc al/cpanel/Cpanel/Logd.pm line 630

Cpanel::Logd::dologs(HASH(0x35841d0), HASH(0x262e270), 1) called at /usr /local/cpanel/Cpanel/Logd.pm line 302

Cpanel::Logd::scan_a_user_logs(‘unalbili’, HASH(0x262e270)) called at /u sr/local/cpanel/libexec/cpanellogd line 273

warn [cpanellogd] mkdir /usr/local/cpanel/Netinternet/yedek: Permission denied a t /usr/local/cpanel/Netinternet/NetinternetBackup.pm line 28

Complete

Avatar
Hakan ERSU 10 yıl önce

NetinternetBackup.pm dosyası kullanıcının kendi yetkileriyle çalışmakta o yüzden yedeklerin alınacağı klasör 777 olmalı.Dizini /usr/local/cpanel/ yerine başka bir dizine yazma izinleriyle birlikte oluşturursanız problem ortadan kalkacaktır.

Avatar
Timur 10 yıl önce

çok teşekkürler,

my $backup_location = “/usr/local/cpanel/netinternet/yedek/$user/$year/$mon/$mday/” . $log_ref->{‘domain’} . ‘.’ . time();

if ( !-e “/yedek/$user/$year/$mon/$mday” ) {

mkpath(“/usr/local/cpanel/netinternet/yedek/$user/$year/$mon/$mday/”, 0777);

netinternet klasörüne ve yedek klasörüne 0777 yazma izni vererek düzelttim.

Bu mevzudaki (5651) düşüncem ise:
Anladığım kadarıyla Linux sunuculardaki loglama sistemi için tib bir format düşünmemiş. Mevcut log sistemini windows sunuculardaki şekliyle yapmak istesek manuel bir yapı ile düzenleme yapmak gerekiyor. Yanlış anlamadıysam TİB, kullanıcının ip adresini, server’a girdiği çıktığı zamanı ve MAC adresininin loglamasını istiyor. Bunun bu şekilde olması CPanel kullanıcıları için şu an için zor gibi gözüküyor. Birde biz bu logları arzu edilen formata çevirsek bile güvenirliğinin elle değiştirilebilinir olduğu gerçeği unutulmuş gibi:). sonuç olarak bu logların tutulmasına eyvallah ama sistemin bacaklarının linux’u unutması bir format belirlenmemesi ilginç. Logların imzalanması güzel fikir fakat Loglar’ın makine ile eş zamanlı olmadan imzalanması gibi bir durum sözkonusu gliba bu ilginç bir çıkmaz. Allah kolaylık versin :) ilginize teşekkür ederim.

Avatar
Hakan ERSU 10 yıl önce

Dediğiniz gibi belirli bir format istenmemiş ki açıkcası belirli bir format istenmesi durumunda ortaya tahmin edilemez birçok problem çıkacaktır.Sonuç olarak herkes apache veya nginx tabanlı bir sistem kullanmamakta.Durum başlı başına sıkıntılı bir süreç ve bu yasa için pek de üzerinde oturulup düşünüldüğünü sanmıyorum.

Bu konularda söyleycek çok sözüm olsada maalesef burada paylaşmam mümkün değil :)

Bu arada logların yollarını değiştirin.
if ile kontrol edilen ve içerisinde oluşturulan dizinin aynı dizin olmasına dikkat edin.Ben bu örnekte /yedek yani ana dizin içerisindeki yedek klasörünü kullandım ama siz /usr/local/cpanel/ dizini içerisinde klasörleri oluşturmaktasınız.Cpanel dosyaları içerisinde yedekleri tutmayın ve tahmin edilemez yollar kullanmayı deneyin.Örnek olarak bir yapılandırma daha ekliyorum ;

my $backup_location = “/var/log/yedek/$user/$year/$mon/$mday/” . $log_ref->{‘domain’} . ‘.’ . time();

if ( !-e “/var/log/yedek/$user/$year/$mon/$mday” ) {

mkpath(“/var/log/yedek/$user/$year/$mon/$mday/”);

}

Avatar
Çağrı 10 yıl önce

Teşekkürler çok faydalı bir makale olmuş. Logları sıkıştırma işlemini nasıl yaptığınızıda açıklayabilir misiniz ?

Yorum Yap