22 Aralık 2014 Pazartesi

Shellde Boş Satırları Silmek

Bir dosyadaki boş satırları silmek ya da ekrana birşeyler basarken boş satrılardan kurtulmak için aşağıdaki sed ve grep komutları kullanılabilir:

$ sed '/^$/d' input.txt > output.txt

$ grep -v '^$' input.txt > output.txt

Hem grep hem sed  ^$ desenini boş satırları yakalamak için kullanıyor. Grep ile kullanılan -v seçeneği ise yakalanan satırları gözardı etmek için kullanılıyor.

16 Haziran 2012 Cumartesi

Elastix Call Center Modülü Kullanımı

Bu yazıda Elastix geliştiricileri tarafında geliştirilen Call Center modülünün dışarı aramalar (outbound calls) için nasıl kullanılacağından bahsedeceğim. Kullandığım Elastix sürümü 2.3.0 ve Call Center sürümü 2.1.3. Öncelikle Call Center modülünü kurmamız gerekli (Elastix’in hali hazırda kurulu olduğunu varsayıyorum). Bunun birden fazla yolu var. Komut satırından paket yöneticisi ile kurulabileceği gibi Elastix’in sitesinden indirilen kaynak kodlar yardımıyla da kurulabilir. Ama en kolayı Elastix arayüzünden, Addons(Eklentiler)  menüsü altından kurmak. Addons menüsü altında kurabileceğiniz birçok eklenti bulunmaktadır.

Call Center modülünü kurduğumuzda Elastix arayüzünde Call Center adlı bir menü oluşacaktır. Dışarı aramalar yapabilmek için Configuration alt menüsünden Dialer sürecini çalıştırmamız gerekecektir.  Dialer Status altında Current Status : Running olacak şekilde daemonımızı çalıştıralım. Deamon’ı çalıştırdıktan sonra dış aramalarımızı yapmak için bir Outgoing Campaign oluşturmamız gerekmektedir. Ama kampanyamızı oluşturmak için hali hazırda varolması gereken bazı gereklilikler var.

Yapmamız gereken ilk şey agent’larımızı oluşturmak. Agent görüşmeyi yapacak insanlar/kişiler olarak düşünülebilir. Bunun için Call Center -> Agent Options yolunu izleyerek agent menüsüne geliyoruz. Burada zaten varolan agentları görebilir, düzenleyebilir, silebilir ya da yeni agentlar ekleyebilirsiniz. Yeni bir agent eklemek için Show Filter’a ardından da New Agent linkine tıklıyoruz. Açılan sayfada agent’ımız için isim, numara, parola gibi bilgileri giriyoruz. ECCP Password şimdilik önemli değil, boş bırakabilirsiniz. Save deyip agent’ımızı kaydediyoruz. Bu şekilde kaç çağrı merkezi görevlimiz varsa her biri için bir agent oluşturuyoruz.

Bir sonraki aşamada yapmamız gereken bir Form oluşturmak. Form’lar görüşme sırasında kullanıcılardan bilgi almak için kullanılan yapılardır. Eğer web basit de olsa kullanıcıdan girdi alan bir web sayfası tasarladıysanız bu yapıya yabancılık çekmeyeceksiniz. Call Center -> Forms, ardından Show Filter -> Create New Form yolunu izleyerek kullanıcıdan alacağımız verilere göre bir Form oluşturuyoruz. Formumuzu da oluşturduktan sonra bir Break oluşturmamız gerekli. Break Agent’ın kampanya sırasında görüşmeler arasında mola almasını sağlamak için kullanılmaktadır. Call Center->Breaks yolunu ardından Show Filter ve Create New Break yolunu izleyerek yeni bir Break oluşturuyoruz.

Oluşturmamız gereken bir diğer yapı da Queue. Normalde Queue’ler gelen aramaları düzenlemek için kullanılsa da Call Center modülünde giden aramalar için de kullanılmaktadır. Yapılan her bir dış arama başarılı olursa Queue’ye atılmakta, daha sonra da Queue’deki uygun bir Agent tarafından karşılanmaktadır. PBX->PBX Configuration -> Queues yolunu izleyerek Queue sayfasına geliyoruz. Gerekli kısımları doldurarak Queue’mizi oluşturuyoruz. Agent’larımızı eklemeyi unutmayalım. Agent’lar Queue’ye iki şekilde eklenebilir: statik ve dinamik. Statik olarak eklenen Agent’lar her zaman Queue’de varsayılırken, dinamik Agent’ların giriş yapmaları gerekmektedir.
Queue’mizi de oluşturduktan sonra geriye aranacak numaraları düzenlemek kalıyor. Numaralarımızı kampanyamıza csv formatında yüklüyoruz. Dosyamızın ilk kolonunu her zaman telefon numaralarından oluşmalıdır. Telefon numaraları dışında arama sırasında görünmesini istediğimiz müşteriye ait bilgileri de virgülle ayrılımış biçimde dosyamıza ekleyebiliriz. Eğer kolon başlıkları da eklemek istersek ilk satır virgülle başlayacak şekilde ekleyebiliriz.
Son olarak aranacak numaraların olduğu dosyamızı da oluşturduğumuza göre kampanyamızı oluşturmaya başlayabiliriz. Call Center -> Outgoing Calls yolunu izleyerek kampanya sayfasına gelelim. Önce Show Filter’a ardından da Create New Campaign linkine tıklayalım.

Seçeneklerin hemen hepsi ne işe yaradıklarını açıklar niteliktedir. Kampanyamıza bir isim veriyoruz, kampanyanın geçerlilik süresini belirtecek başlama ve bitiş tarihlerini seçiyoruz, önceki adımda oluşturduğumuz Form’umuzu seçiyoruz, aramanın yapılacağı Trunk’ı seçiyoruz (Trunk’ın önceden oluşturulduğunu varsayıyoruz), kampanyamız için kullanılacak maksimum kanal sayısını seçiyoruz (Agent sayımıza eşit olabilir), yine önceki adımlarda oluşturduğumuz Queue’mizi seçiyoruz, başarısız olan bir arama için tekrar deneme sayısınısı belirliyoruz, oluşturduğumuz csv dosyasını seçiyoruz ve ardından kampanyamız için hatırlatma amaçlı bir Script yazıyoruz. Daha sonra Save diyerek kampanyamızı kaydediyoruz.

Aramaların gerçekleşebilmesi için Agent’larımızla giriş yapmamız gerekmektedir. Call Center -> Agent Console yolunu izliyoruz. Buradan giriş yapacağımız Agent’ı ve Extension’ı seçiyoruz (önceden oluşturulmuş). Enter dediğimizde Extension’ın telefonu çalmaya başlayacak. Telefonu açıyoruz ve Agent için belirlediğimiz parolayı girip # tuşuna basıyoruz. Başarılı bir şekilde giriş yaptığımızda kampanyamızla ilgili Form, script gibi bilgilerin ve bir arama bağlandığında aramaya ait bilgilerin gösterildiği konsola düşeceğiz. Eğer o saat için belirlenmiş bir kampanya varsa Call Center modülü arka planda sırasıyla aramaları gerçekleştirecek ve başarılı aramaları Agent’a bağlayacaktır.

23 Ocak 2012 Pazartesi

Python'da map, filter ve reduce Fonksiyonları

Bu yazıda listelerle kullanıldığında çok yararlı olan üç fonksiyondan bahsedicem:
filter(), map() ve reduce()

filter(function, dizi) dizideki her eleman için için function(eleman) değerinin true olduğu bir dizi döndürür.
Dizi string veya tuple tipindeyse sonuç da aynı tipte olur; aksi halde sonuç list tipindedir. Örneğin 2 ve 3'e bölünmeyen
bir sayı dizisini hesaplamak için:

>>> def f(x): return x % 2 != 0 and x % 3 != 0
...
>>> filter(f, range(2, 25))
[5, 7, 11, 13, 17, 19, 23]

map(function, dizi) dizideki her bir eleman için function(eleman) fonksiyonunu çağırır ve dönen değerlerin bir listesini
döndürür. Örneğin, birkaç sayının küpünü hesaplamak için:

>>> def cube(x): return x*x*x
...
>>> map(cube, range(1, 11))
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]

Birden fazla dizi de kullanılabilir. Bu durumda fonksiyonun aynı sayıda parametreye sahip olması gerekir. Fonksiyon dizilerdeki
elemanlar karşılıklı olacak şekilde çağırılır. Eğer dizilerden biri daha kısaysa None değeri kullanılır. Örneğin:

>>> seq = range(8)
>>> def add(x, y): return x+y
...
>>> map(add, seq, seq)
[0, 2, 4, 6, 8, 10, 12, 14]

reduce(function, dizi) function ikili fonksiyonunun önce dizinin ilk iki elemanı ile çağrılır. Sonra çıkan sonuç ve bir sonraki eleman ve bu şekilde devam eder. En son tek bir sonuç üretilir. Örneğin 1'den 10'a kadar olan sayıların toplamını hesaplamak için:

>>> def add(x,y): return x+y
...
>>> reduce(add, range(1, 11))
55

Dizide sadece bir eleman varsa onun değeri döndürülür. Eğer dizi boşsa hata oluşur.

Başlangıç değeri olarak bir üçüncü parametre eklenebilir. Bu durumda dizi boş ise başlangıç değeri döndürülür ve fonksiyon önce başlangıç değeri ve dizinin ilk elemanı ile çağrılır. inin ilk iki elemanı ile çağrılır. Sonra çıkan sonuç ve bir sonraki eleman ve bu şekilde devam eder. Örneğin:

>>> def sum(seq):
...     def add(x,y): return x+y
...     return reduce(add, seq, 0)
...
>>> sum(range(1, 11))
55
>>> sum([])
0


şekilde devam ederek çağrılmasıyla tek bir sonuç döndür.

28 Ekim 2011 Cuma

GNU Screen Hakkıda Kısaca


   Screen genelde çok az kişinin kullandığı çok faydalı bir araç. Screen 'i pencere çoklayıcısı olarak tanımlamak mümkün. Bunun anlamıysa screen kullanarak tek bir terminalde oluşturacağınız değişik sayıda pencerelerde aynı anda değişik programları çalıştırabileceğiniz. Günümüzde grafiksel uç birimler sekme özelliğine sahip olsa da screen 'in yetenekleri çok daha fazla.

    Screen 'i paket yöneticinizi kullanarak kurabilirsiniz. Pardus için '$ sudo pisi it screen' yeterli olacaktır.
$ screen
komutunu vererek yeni bir screen oturumu açabilirsiniz. Screen de birçok program gibi ayar doslarını nokta(dot) dosyası olarak kullanıcının ev dizininde tutar. İlk çalıştırdığınızda muhtemelen sizi screen 'in lisansını, hataların nereye raporlanacağını vb. bilgileri içeren bir sayfa karşılayacaktır. Bu sayfayı kapatmak için ~/.screenrc sayfasına aşağıdaki satırı ekleyebilirsiniz: 
startup_message off
    Yaratılan her screen oturumu eşsiz bir numara ile tanımlanır. İlk pencere 0 ile numaralandırılır ve 1, 2, 3 şeklinde devam eder. Ctrl+a screenin varsayılan komut karakteridir. Bununla birlikte Ctrl+a 'dan sonra girilen komut büyük/küçük harf duyarlıdır. Yani Ctrl+a n ve Ctrl+a N farklı anlamlara gelir.

    Yeni bir pencere yaratmak için Ctrl+a c (create) kombinasyonunu kullanabilirsiniz.

    Oluşturulan pencereler arasında geçiş yapmak için değişik yöntemler vardır:
  • Ctrl+a n (next)tuşlarıyla bir sonraki pencereye, Ctrl+a p (previous) ile de bir önceki pencereye geçebilirsiniz.
  • Ctrl+a sonrasında 0-9 arasında bir sayı ile karşılık gelen pencereye geçiş yapabilirsiniz.
  • Ctrl+a " ile bütün pencerelerin listesini görebilir, istediğinize geçebilirsiniz.
    Ctrl+a A tuşlarıyla kullanmakta olduğunuz pencereyi yeniden adlandırabilirsiniz.
   
    Yeni pencereler oluşturmayı ve aralarında geçiş yapmayı öğrendik. Oturumdan kopmak(detach) için Ctrl+a d kullanılabilir. Bunun yerine sadece oturumu içeren uç birimi de kapatabilirsiniz. Ama bu yöntemlerden hiçbiri oturumunuzu sonlandırmaz. Yaptıkları oturumunuz ve uç birim arasındaki bağlantıyı koparmaktır. Eğer Ctrl+a d komutunu kullandığınız sırada hali hazırda çalışan bir program varsa çalışmayı sürdürecektir ve istediğiniz zaman tekrar bağlanarak işinize devam edebilirsiniz.     
    Koparılan bir oturuma yeniden bağlanmak için aşağıdaki komut kullanılabilir:
$ screen -r
    Koparılan sadece bir tane screen oturumu varsa direk olarak ona bağlanırsınız. Birden fazla oturum olması durumunda ise bir şuna benzer liste karşınıza çıkar:
$ screen -r
There are several suitable screens on:
        2608.pts-0.pardus2011   (Detached)
        2665.pts-0.pardus2011   (Detached)
     Bir tanesini seçip yeniden bağlanabilirsiniz:
$ screen -r 2608.pts-0.pardus2011
    Screenin bir başka önemli özelliği de bir screen ourumunu paylaşabiliyor olmanızdır. Bunun için aşağıdaki adımları izlemeniz yeterlidir: 
  1. root olarak: # chmod u+s /usr/bin/screen ()
  2. # chmod 755 /var/run/screen
  3. root kullanıcısından çıkış yapın ve screen oturumunu paylaşacak kullanıcıyla bir screen oturumu açıp isim verin: $ screen -S oturumAdı
  4. Çoklu kullanıcı özelliğini açmak için Ctrl+a :multiuser komutunu verin.
  5. Screen oturumuna bağlanacak ikinci kullanıcıya gerekli izinleri vermek için Ctrl+a :acladd kullanıcı2 (kullanıcı2 bağlanacak olan diğer kullanıcının ismi)
  6. Daha sonrasında kullanıcı2 SSH kullanarak bilgisayara bağlanmalı ve $ screen -x kullanıcı1/oturumAdı (kullanıcı1 screen oturumunu oluşturan kullanıcı) komutuyla oluşturulan screen oturumunu kullanmaya başlayabilir.
    Böylece iki kullanıcı da aynı screen oturumunu paylaşabilir ve komut çalıştırabilir.

    Screen pencereleri iki veya daha fazla yatay pencereye bölmenizi sağlar. Bu sayede, örneğin, bir yandan sistem kaynaklarını görüntülerken ("top"), pencerenin bir diğer kısmında çalışmaya devam edebilirsiniz.

     Screen'i ikiye ayırmak için önce iki screen oturumu oluşturun. Ctrl+a S screeni ikiye ayıracaktır; üst kısımda hali hazırda kullandığınız oturum, altta boş bir tane.

    Alttaki kısma geçmek için Ctrl+a TAB kullanılabilir. Bu komut konsol imlecini alttaki kısma geçirecektir. Alt kısma geçtiğinizde önceden oluşturduğunuz screen oturumlarından bir tanesini seçmelisiniz. Bunun için Ctrl+a " kullanın ve varolan screen oturumlarını listeleyin. Listeden bir tanesini seçerek kullanın. Yalnız yukarı kısımda kullanılan oturumu seçmemeye dikkat edin, böyle bir durumda iki kısımda da aynı oturumu kullanıyor olursunuz. Bir screen oturumu seçtikten sonra top komutunu verin ve Ctrl+a TAB ile yukarıdaki kısma geçin. Şimdi altta sistem kaynaklarını izlerken üst kısımda çalışabilirsiniz.


    Tekrar tam ekran durumuna dönmek için çalışmaya devam etmek istediğiniz kısma geçin ve Ctrl+a Q komutunu kullanın.

    Screen ayar dosyasında bazı düzenlemeler yaparak screeni daha kullanışlı hale getirmek mümkün. Bazı düzenlemelerle pencerenizin en altında aktif screen oturumlarını listeleyebilir, sistem saati ve bilgisayar ismi gibi bilgileri görebilirsiniz. Bununla yanında başlangıçta oluturulacak screen oturumları da tanımlayabilirsiniz. Örneğin:
hardstatus alwayslastline
hardstatus string '%{= kG}[ %{G}%H %{g}][%= %{=kw}%?%-Lw%?%{r}(%{W}%n*%f%t%?(%u)%?%{r})%{w}%?%+Lw%?%?%= %{g}][%{B}%Y-%m-%d %{W}%c %{g}]'

# Default screens
screen -t shell1 0
screen -t shell2 1
screen -t server 2 ssh me@myserver
    İlk iki satırda durum çubuğunun en altta olması gerektiği ve bu satırda ne olması gerektiği yazılıdır. # ile başlayan satır yorum satırı, yorum satırının altındaki "screen -t ScreenAdı ScreenNumarası KabukKomutu" formatındaki satırlar ise başlatılacak screen tanımlamalarıdır. 

    Screen oturumlarını kapatmak için ise Ctrl+a Q komutunu verebilir veya exit komutunu kullanabilirsiniz. 

Kaynaklar:
[1] http://magazine.redhat.com/2007/09/27/a-guide-to-gnu-screen/
[2] http://news.softpedia.com/news/GNU-Screen-Tutorial-44274.shtml

Debian: OpenLDAP Kurmak


    Özet
    Bu yazının amacı Debian üzerinde OpenLDAP kurulumunu ve yapılandırmasını kolay anlaşılır bir şekilde anlatmaktır.
    Bu rehberin sonunda, bireysel makinelerde elle kullanıcı yaratmaya gerek kalmayacak şekilde, ağdaki bütün makilerde kullanıcı girişi için merkezi yetkilendirme sistemi olarak hizmet verecek fonksiyonel bir LDAP sunucusuna sahip olacaksınız.
    Bununla birlikte, gelişmiş yetkilendirme güvenliği ve gerçek bir ağ tabanlı çözüm için, LDAP'ın Kerberos ile birlikte kullanılması önerilir. Kerberos kurulumu MIT Kerberos 5 Guide belgesinde anlatılmaktadır,
    Bu yazı Spinlock Solutions'ın, Debian GNU Guide, MIT Kerberos 5 Guide, OpenLDAP Guide, OpenAFS Guide ve FreeRADIUS Guide'ı içeren 5 yazılık Unix ağlarına giriş serisinin bir parçasıdır.
    
    Giriş
    LDAP geleneksel olarak sistem yöneticilerinin ve ileri düzey kullanıcıların ilgisini cezbeden bir servistir. Ama yüksek girdi bariyeri(high entry barrier) ve altyapı gereksinimleri birçok kişiyi onu kullanmaktan uzak tutmuştur.
    LDAP hali hazırda sayısız yayının konusu olmuştur. Burada sadece gerekli bir özet sunacağız; içeriği yerleştirmek ve pratik sonuçlar elde etmek için yeterli bilgi.
    Harici bağlantıları izlemek zorunda değilsiniz; bununla birlikte, belirli tekil konuların belirli teknik işleyişine işaret etmesi amacıyla, bağlantılar makale boyunca kullanılmış ve makalenin sonunda hep birlikte sunulmuştur.

    Bir ağda LDAP'ın rolü
    OpenLDAP, Lightweight Directory Access Protocol - Hafifletilmiş Dizin Erişim Protokolü'nün açık kaynaklı bir uygulamasıdır. Dizin ağaç yapısında, okuma-en iyilenmiş(read-optimized) haldedir. Sarı sayfalar ya da bir telefon rehberi, zihinde canlandırmak açısından iyi örnekler ancak LDAP çok daha güçlüdür.
    OpenLDAP'ı, bireysel(individual) makinelere ilk eriştiklerinde ev dizinlerini de otomatik olarak yaratacak şekilde, ağda herhangi bir yerdeki kullanıcı girişleri için bir merkezi yetkilendirme konumu sağlamak için kullanacağız.
    Bu belge OpenLDAP'ı hem yetkilendirme sağlamak hem kullanıcı üst verisi sunmak amacıyla kullanmak için kendi başına yeterlidir. Bununla birlikte, LDAP sunucusuna yapılan düz metin bağlantıları ve kablo üzerinde parolaların gezinmesi sebebiyle LDAP'ı burada anlatıldığı şekilde yetkilendirme amacıyla kullanmak güvenli değildir. Bu nedenle LDAP'ı üstün ve güvenli ağ yetkilendirme mekanizması Kerberos'la kullanmak tavsiye edilir. Kerberos bir diğer makale MIT Kerberos 5 Guide'da anlatılmaktadır.
    Haydi, LDAP kurulumumuza başlayalım.
    Teknik bir bakış açısından, LDAP dizini sıradüzensel olarak düzenlenmiş girdilerin(entries) kümesini içerir. Her girdi belli Nesne Sınıflarına (Object Classes) aittir ve özellikler(attributes) olarak adlandırılan değişik sayıda  anahtar=değer(key=value) çifti içerir.
    Her girdi bir Ayırıcı İsim (Distinguished name - "DN") ile tekil olarak(uniquely) tanımlanır. DN ağacın başından başlayan, girdiye ait "tam yolu" (full path) sağlayan, virgüllerle ayrılmış, bir özellikler kümesi şeklindedir. Örneğin, Example, Inc. şirketi dc=example,dc=com 'da ağacın köküne sahip olabilir. Example, Inc. şirketinde çalışmaya başlayan birisi DN'i cn=person,ou=People,dc=example,dc=com olan bir LDAP girdisine sahip olabilir.
    Bir girdide hangi özelliklerin olabileceği ya da olması gerektiği girdinin objectClass'ları tarafından yönetilir.
    Farkedebileceğiniz gibi, yukarıdaki cn=person gibi, DN'in tekil parçaları da anahtar=değer şeklindedir. Bu "anahtarlar", cn, ou ve dc; Common Name, Organizational Unit ve Domain Component kelimelerinin kısaltmalarıdır. Bunlar hergün kullanacağınız LDAP terminolojisinin bir parçasıdır.
    ObjectClassları; özellikler, söz dizimler(syntaxes), eşleşme kuralları (matching rules) ve ağaç yapısının diğer detayları LDAP sunucusunun başlangıcında /etc/ldap/slapd.conf dosyasında tanımlı şema (schema) dosyaları okunarak yapılandırılabilir ve yüklenebilir.
    Hadi hızlıca kurulumumuzdaki LDAP'a özel elemanları tanımlayalım:
  • LDAP geleneksel sistem kullanıcı isimleri ya da diğer veriyle herhangi bir şekilde bağlantılı değildir. Bununla birlikte, kurulumumuzda LDAP'ın işlenselliğinin bir kısmı gelenksel Unix dosyaları /etc/passwd ve /etc/group'da bilgi saklamayı içerir. 
        Kişilerin giriş isimleri (login names) kişileri LDAP ağacında karşılık gelen veriyle eşleştirilerek kullanılacaktır. Örneğin, person kullanıcı ismi uid=person,ou=People,dc=example,dc=com LDAP girdisine eşlenir.
  •  LDAP kullanıcı parolalarıın içerecek şekilde yapılandırılabilir. Parolalar belirli kullanıcıları yetkilendirmek ve korunan girdilere erişim sağlamak ve kullanıcının doğru parolayı bilip bilmediğini kontrol etmek için kullanılabilir.
         Bir kulanıcı bir LDAP istemcisi açıp dizini taradığında, DN'i ve parolası kimlik ve erişim yetkilerini sağlamakta kullanılır. LDAP kullanıcı yetkilendirme işi için yapılandırıldığında, DN'i ve parolası sadece LDAP dizinine bağlantı sağlanması için kullanılır - başarılı bir bağlantı ("bind") kullanıcının doğru parolayı bildiğini gösterir.
   
     Eksiksiz OpenLDAP belgelendirmesi için OpenLDAP web sayfasına bakabilirsiniz. Güvenilir bir OpenLDAP kitabı için ise, Gerald Carter'ın LDAP System Administration (by O'Reilly) kitabına bakabilirsiniz.

    Tutkal Katmanlar(Glue layers): LDAP'ı sistem yazılımıyla tümleştirmek
    NSS
    Bütün GNU/Linux-tabanlı platformlarda, NSS ağ veri bulma (network data retrieval) yapılandırması için erişilebilirdir. NSS, Name Service Switch mekanızmasının bir uygulamasıdır.
     NSS, LDAP'ın -doğal olarak LDAP desteklemese de- bütün servislerin "kullanıcı veri" yollarına ("user data" path) dahil edilmesine izin verir.
     NSS web sayfasında uygun giriş (ve eksiksiz belgelendirmeye) erişebilirsiniz. Ayrıca nsswitch.conf(5) kılavuz (manual) sayfasına bakınız.

    PAM
    Aynı şekilde, bütün GNU/Linux-tabanlı platformlarda, bulmacanın bir diğer parçası, Linux-PAM, servis-özel (service-specific) yetkilendirme yapılandırması için bulunur.. Linux-PAM, Sun Microsystems'ten PAM ("Pluggable Authentication Modules")'ın bir uygulamasıdır.
     Ağ servisleri,  hard-coded yetkilendirme arayüzleri ve karar mekanizmalarına sahip olmak yerine, standart, önceden-tanımlı arayüz üzerinden PAM'ı çağırır. Bundan sonrası, herhangi ya da bütün yetkilendirme işlerini işletmek ve sonuçları programa göndermek PAM'a aittir.
     PAM'ın kararı nasıl verdiği servisin ilgilendirmez. Geleneksel kurulumlarda (set-ups), bu sıklıkla kullanıcı ismini ve parolsını sorarak ve onaylayarak yapılırdı. Gelişmiş ağlarda, bu retina taramalarıyla olabilir ya da — Kerberos biletletiyle, seiden bir diğer makalede anlatıldığı gibi, MIT Kerberos 5 Guide.
     Linux-PAM web sayfasında uygun giriş (ve eksiksiz belgelendirmeye) erişebilirsiniz. PAM Configuration File Syntax sayfasının üzerinde özellikle durun. Ayrıca Linux-PAM(7) ve pam(7) kılavuz sayfalarına göz gezdirin.

    Conventions
    Belgelendirmedeki talimatları takip edememek gerçekten moral bozucu. Daha fazla devam etmeden bazı konular üzerinde anlaşalım:
  •  Üzerinde pratik bir kurulum gerçekleştireceğimiz platform Debian GNU olacak.
  •  sudo 'yu kurun. Sudo normal kullanıcı hesabınızdan sistem yöneticisi işlerini yapmanıza izin veren bir program. Bu makaledeki bütün örnekler root yetkileri gerektirmektedir, sudo kullanarak kodları kopyalayıp kabuğuna(shell) yapıştırmanız mümkün olacak.
su -c 'apt-get install sudo'

       Eğer şifre sorulursa root şifresini girin.
       sudo 'yu yapılandırmak için, aşağıdaki satırı $USERNAME i kullanıcı isminizle değiştirerek  /etc/sudoers dosyanıza ekleyin:

$USERNAME ALL=(ALL) NOPASSWD: ALL

  • Debian paketleri debconf arayüzüyle kurulum süreci boyunca bize sorular soracak. debconf 'u bilinen bir duruma ayarlamak için:
sudo dpkg-reconfigure debconf

       Sorulduğunda, arayüz=Diyalog (interface=Dialog) ve öncelik=düşük (priority=low) olarak cevaplayın.

  • Log dosyalarını görüntülemek hataların yakalanmasında çok kritiktir. Bunu yapmanın anlaşılır, hepsini kapsayan yolu bir terminal açmak ve aşağıdaki kodu çalıştırmak:
cd /var/log; sudo tail -F daemon.log sulog user.log auth.log debug kern.log syslog dmesg messages kerberos/{krb5kdc,kadmin,krb5lib}.log

       Komut hata log mesajlarını oluştukça ekrana yazacaktır.
  • Test sistemimizin adı monarch.spinlock.hr ve 192.168.7.12 IP adresine sahip. Sunucu ve istemcinin ikisi de aynı makineye kurulacak. Bununla birlikte, ilişkili oldukları yerlerde sunucu ve istemci rollerini ayırmak için, istemci monarch.spinlock.hr ve sunucu ldap1.spinlock.hr olarak adlandırılacak. /etc/hosts dosyasına yapılacak aşağıdaki gibi bir ekleme bu şemayı destekleyecektir:
192.168.7.12 monarch.spinlock.hr monarch krb1.spinlock.hr krb1 ldap1.spinlock.hr ldap1

    Dikkat
    Bazı Debian kurulumlarında sistemin ağ makine adı(hostname), localhost adresi 127.0.0.1 'e atanmış olabilir. Bu ağ işlemlerinde bazı hatalara yol açabilir ve açacaktır. Bu yüzden /etc/hosts dosyasındaki "localhost" girdisinin aynen aşağıdaki gibi olmasına dikkat edin(ne eksik, ne fazla):

127.0.0.1 localhost localhost.localdomain

    Son olarak, beklendiği gibi ağ kurulumunu test edelim. Makine isimlerine(hostnames) ping atmak uygun FQDN  ve IP'leri gösterecektir:

ping -c1 localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
....
ping -c1 monarch
PING monarch.spinlock.hr (192.168.7.12) 56(84) bytes of data.
....
ping -c1 ldap1
PING krb1.spinlock.hr (192.168.7.12) 56(84) bytes of data.
....

    OpenLDAP
    Sunucu Kurulumu
    OpenLDAP'ın sunucu bileşeni slapd olarak adlandırılır ve bütün ihtiyacımız olan bu.

sudo apt-get install slapd ldap-utils

Debconf cevapları:

Omit OpenLDAP server configuration? No
DNS domain name: spinlock.hr
Organization name? spinlock.hr
Administrator password: PASSWORD
Confirm password: PASSWORD
Database backend to use: HDB
Do you want the database to be removed when slapd is purged? No
Allow LDAPv2 protocol? No

    Kurulum tamamlanır tamamlanmaz OpenLDAP sunucusu (slapd komutu) başlayacaktır.

    Başlangıç Yapılandırması
    OpenLDAP sunucumuz hali hazırda çalışıyor. Hadi önce bütün LDAP istemcileri için ortak bir yapılandırma dosyası olan /etc/ldap/ldap.conf 'u düzenleyelim. Bu, ldapsearch ve diğer komutları her defasında temel parametreleri elle girmemize gerek kalmadan çalıştırmamızı sağlayacak.
    /etc/ldap/ldap.conf 'ta aşağıdaki iki satırı ekinleştirin, gerekirse dosyayı kendiniz oluşturun:

BASE dc=spinlock, dc=hr
URI ldap://192.168.7.12/

    Sonrasında, davranışını ayarlamak için sunucunun yapılandırma dosyası /etc/ldap/slapd.conf 'u düzenleyelim.
    Bütün şema dosyalarının etkinleştirildiğinden emin olun:

include /etc/ldap/schema/core.schema
include /etc/ldap/schema/cosine.schema
include /etc/ldap/schema/nis.schema
include /etc/ldap/schema/inetorgperson.schema

    Ayrıntı seviyesini 0 veya "none" 'dan 256 'ya değiştirin:

loglevel 256

    "index objectClass eq" satırını arayın ve bir başka arama indexi daha ekleyin. Belirli kombinasyonlarda, arama girdileri indexlenmediklerinde herhangi bir sonuç dönmemesi mümkün. Bu yüzden bu adım önemli:

index objectClass eq
index uid eq

    Yeni index seçeneğinin uygulanması için, aşağıdaki komutları çalıştırın:

sudo invoke-rc.d slapd stop
sudo slapindex
sudo chown -R openldap:openldap /var/lib/ldap
sudo invoke-rc.d slapd start

    Başlangıç Testi
    Artık kurulumumuzu test etmenin zamanı geldi. OpenLDAP sunucumuz çok fazla bilgi içermiyor ama basit bir okuma işlemi kolayca gerçekleştirilebilir.
    LDAP terimleriyle, okuma (read) işlemi "arama" ("search") olarak adlandırılır. Komut satırından bir arama işlemi yapmak için ldapsearch ve slapcat 'e sahibiz.
    Ldapsearch (ve "ldap" önekiyle başlayan diğer LDAP komutları) LDAP protokolünü kullanarak "çevrimiçi"("online") işlem gerçekleştirirler.
    Slapcat (ve "slapd" önekiyle başlayan diğer LDAP komutları) direkt olarak yerel dosya sisteminde dosyalar açarak "çevrimdışı("offline") işlem gerçekleştirirler. Bu yüzden, sadece yerel olarak LDAP sunucusunda çalıştırılabilirler ve yönetici hakları gerektirirler. Veritabanına yazmaları gerektiğinde, OpenLDAP sunucusu genellikle durdurulmalıdır.
    İki arama komutunun çıktısında, iki LDAP girdisi farkedeceksiniz, bir tanesi ağaçtaki en uç seviye elemanını, diğeri LDAP yönetici girdisini temsil ediyor. slapcat çıktısında, ldapsearch çıktısında gösterilmeyen extra özelliklere dikkat edin. Bunlardan bir tanesi userPassword, /etc/ldap/slapd.conf dosyasındaki öntanımlı erişim kısıtlamalarından dolayı anonim okuyuculara gösterilmez.

ldapsearch -x

# extended LDIF
#
# LDAPv3
# base <dc=spinlock, dc=hr> (default) with scope subtree
# filter: (objectclass=*)
# requesting: ALL
#

# spinlock.hr
dn: dc=spinlock,dc=hr
objectClass: top
objectClass: dcObject
objectClass: organization
o: spinlock.hr
dc: spinlock

# admin, spinlock.hr
dn: cn=admin,dc=spinlock,dc=hr
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator

# search result
search: 2
result: 0 Success

# numResponses: 3
# numEntries: 2

sudo slapcat

dn: dc=spinlock,dc=hr
objectClass: top
objectClass: dcObject
objectClass: organization
o: spinlock.hr
dc: spinlock
structuralObjectClass: organization
entryUUID: 350a2db6-87d3-102c-8c1c-1ffeac40db98
creatorsName:
modifiersName:
createTimestamp: 20080316183324Z
modifyTimestamp: 20080316183324Z
entryCSN: 20080316183324.797498Z#000000#000#000000

dn: cn=admin,dc=spinlock,dc=hr
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword:: e2NyeXB0fVdSZDJjRFdRODluNHM=
structuralObjectClass: organizationalRole
entryUUID: 350b330a-87d3-102c-8c1d-1ffeac40db98
creatorsName:
modifiersName:
createTimestamp: 20080316183324Z
modifyTimestamp: 20080316183324Z
entryCSN: 20080316183324.804398Z#000000#000#000000

    Temel Ağaç Yapısını Yaratmak
    Açıklandığı gibi, LDAP veritabanı ağaç şeklinde yapılandırılmıştır. Kurumunuz için en uç seviye elemanı genellikle alan adıdır(domain name). Alan adının spinlock.hr olması durumunda, en uç seviye elemanı dc=spinlock,dc=hr.
   Alttaki bir sonraki seviyede, kurumunuz, insanlar, gruplar, servisler, ağlar, protokoller vb. alt "kurumsal birimlere"("organizational units") ayrılır.
    Bu nedenle, LDAP dizininde insanların Unix "üst verilerini"("meta data") desteklemek için, bahsedilen kurumsal birimlerden iki tanesinin yaratılmasıyla ilgileneceğiz, İnsanlar(People) ve Grup(Group). Bu ikisi yaklaşık olarak Unix /etc/passwd ve /etc/group dosyalarına karşılık gelecektir.
    Ldap verisi LDIF denilen metinsel bir formata dönüştürülür. Komut satırı LDAP araçları bu formatta veri alır ve üretir. LDIF akışları(stream) aynı zamanda LDAP girdileri ekleme, değiştire ve silme gibi komutlar içerebilir.
    Bu bilgiyle, sunucuyla etkileşerek iki kurumsal birim ekleyecek basit bir LDIF dosyası yaratalım, /var/tmp/ou.ldif. Boş satırların girdileri ayırdığına dikkat edin:

dn: ou=People,dc=spinlock,dc=hr
ou: People
objectClass: organizationalUnit

dn: ou=Group,dc=spinlock,dc=hr
ou: Group
objectClass: organizationalUnit

    LDIF dosyasını sunucuya yüklemek için, çevrimdışı aracı, slapadd, kullanarak bir örnek gösterelim:

sudo invoke-rc.d slapd stop
sudo slapadd -c -v -l /var/tmp/ou.ldif
sudo invoke-rc.d slapd start

    Hadi ldapsearch kullanarak yaratılan girdileri kontrol edelim.

ldapsearch -x ou=people

# extended LDIF
#
# LDAPv3
# base <dc=spinlock, dc=hr> (default) with scope subt
# filter: ou=people
# requesting: ALL
#

# People, spinlock.hr
dn: ou=People,dc=spinlock,dc=hr
ou: People
objectClass: organizationalUnit

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

    Kullanıcı Hesapları Yaratmak
    İki kurumsal birim yarattığımız gibi, ilk grubumuzu ve buna ait bir kişi yaratalım. Tekrar, problemi bir LDIF dosyası yaratarak ve yükleyerek çözelim, /var/tmp/user1.ldif. Boş satırlar girdileri ayırmaktadır:

dn: cn=mirko,ou=group,dc=spinlock,dc=hr
cn: mirko
gidNumber: 20000
objectClass: top
objectClass: posixGroup

dn: uid=mirko,ou=people,dc=spinlock,dc=hr
uid: mirko
uidNumber: 20000
gidNumber: 20000
cn: Mirko
sn: Mirko
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
loginShell: /bin/bash
homeDirectory: /home/mirko

    LDIF dosyasını sunucuya yüklemek için, çevrimiçi aracı, ldapadd, kullanarak bir örnek yapalım. Önceden bahsedildiği gibi, ldapadd LDAP protokolünü kullanır, sunucuya sistem yöneticisi olarak bağlanmalı ve (slapd kurulumu sırasında tanımladığımız) yönetici parolasını girmeliyiz:

ldapadd -c -x -D cn=admin,dc=spinlock,dc=hr -W -f /var/tmp/user1.ldif

Enter LDAP Password: PASSWORD

adding new entry "cn=mirko,ou=group,dc=spinlock,dc=hr"

adding new entry "uid=mirko,ou=people,dc=spinlock,dc=hr"

    Şimdi kullanıcının parolasını tanımlamak için çevrimiçi bir araç kullanalım: ldappasswd. (Eğer LDAP'ı Kerberos ile birlikte kullanırsanız (MIT Kerberos 5 Guide) bu adım gerekli değildir)

ldappasswd -x -D cn=admin,dc=spinlock,dc=hr -W -S uid=mirko,ou=people,dc=spinlock,dc=hr

New password: NEW USER PASSWORD

Re-enter new password: NEW USER PASSWORD

Enter LDAP Password: ADMIN PASSWORD

Result: Success (0)

    Not
    Fark edebileceğiniz gibi bütün girdiler her zaman "fully qualified" olmalı ve soneki (dc=spinlock,dc=hr) ya da DN'in herhangi bir bileşenini gözardı edemezsiniz. Bu genellikle komut satırı örneklerinin uzun ve anlaşılmaz olmasına yol açabilir ve sıkıcı, gereksiz bir iş olarak görülebilir. Bunu sorun olarak görüyorsanız, çözüm için ya bu duruma alışmalısınız ya da bu bilgilerin bir çoğunu sizin için dolduran bir grafiksel LDAP sunucusu kullanmalısınız.

    Şimdi yaratılan kullanıcı girdilerini doğrulamak için ldapsearch kullanalım. /etc/ldap/slapd.conf dosyasındaki erişim kısıtlamalarından dolayı, yaratmış olsak bile parola alanı, userPassword, gösterilmeyecektir.

ldapsearch -x uid=mirko

# extended LDIF
#
# LDAPv3
# base <dc=spinlock, dc=hr> (default) with scope subtree
# filter: uid=mirko
# requesting: ALL
#

# mirko, people, spinlock.hr
dn: uid=mirko,ou=people,dc=spinlock,dc=hr
uid: mirko
uidNumber: 20000
gidNumber: 20000
cn: Mirko
sn: Mirko
objectClass: top
objectClass: person
objectClass: posixAccount
loginShell: /bin/bash
homeDirectory: /home/mirko

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

Tebrikler! Çalışan bir LDAP kurulumunuz var.

    NSS Yapılandırması
    Şimdi LDAP'ta yaratılmış yeni bir kullanıcımız var, sistemin onu görmesine izin vermeliyiz. Örneğin, root ve mirko kullanıcılarının varlığını test edelim. mirko görünmezken yönetici görünecektir:

id root
uid=0(root) gid=0(root) groups=0(root)

id mirko
id: mirko: No such user

    Sistemin LDAP hesaplarını görmesi için libnss-ldap (ki otomatik olarak libpam-ldap paketini de kuracaktır) ve nscd'yi kurmalıyız:

sudo apt-get install libnss-ldap nscd

    Bütün debconf cevapları:

LDAP server URI: ldap://192.168.7.12/ (Note the "ldap://", NOT "ldapi://"!)

Distinguished name of the search base: dc=spinlock,dc=hr

LDAP version to use: 3

Does the LDAP database require login? No

Special LDAP privileges for root? No

Make the configuration file readable/writeable by its owner only? No

Allow LDAP admin account to behave like local root? Yes

Make local root Database admin. No

Does the LDAP database require login? No

LDAP administrative account: cn=admin,dc=h15,dc=ri

LDAP administrative password: PASSWORD

Local crypt to use when changing passwords. md5

PAM profiles to enable: select all

     NSS modülünü yapılandırmak için, /etc/libnss-ldap.conf dosyasını açın. Yapılandırma satırlarını gösterildiği gibi yerlerştirin ve ayarlayın:

base dc=spinlock,dc=hr
uri ldap://192.168.7.12/

    Son olarak, LDAP NSS modulünü etkinleştirmek için, /etc/nsswitch.conf dosyasındaki passwd ve group ile ilgili satırları aşağıdaki iki satırla değiştirin:

passwd:         files ldap
group:          files ldap

    Nscd (the Name Service Caching Daemon) LDAP sunucusunu her seferinde sorgulamak yerine üstveriyi yerel olarak önbelleklemek için kullanılır. Uzun vadede çok etkili bir servis ancak test boyunca veriyi LDAP sunucusundan almak amacıyla bir an için durduracağız:

sudo invoke-rc.d nscd stop

    Şimdi LDAP kullanıcılarının görünür olduğunu doğrulayabiliriz:

id mirko

uid=20000(mirko) gid=20000(mirko) groups=20000(mirko)

    PAM Yapılandırması
    Bu makalenin son adımı LDAP'ı sistem yetkilendirme süreciyle tümleştirmekle ilgili.
    libpam-ldap'ı yükleyip yapılandıralım. (Bu adımı otomatik olarak libnss-ldap kurulumu sırasında yapmış olabilirsiniz — bu durumda Debian paketin zaten kurulu olduğunu söyleyecektir).
   

sudo apt-get install libpam-ldap

    Debconf cevapları:

Make local root Database admin. No

Does the LDAP database require login? No

Local crypt to use when changing passwords. md5

    PAM modülünü yapılandırmak için, /etc/pam_ldap.conf dosyasını açın. Yapılandırma satırlarını gösterildiği gibi yerlerştirin ve ayarlayın:

base dc=spinlock,dc=hr
uri ldap://192.168.7.12/

    Şimdi Linux-PAM 'ın kendisini yapılandıralım. PAM yapılandırması oldukça kırılgandır. Bu yüzden çalıştığı onaylanmış varolan örnekleri kullanın. Herhangi bir değişiklikte,  PAM Configuration File Syntax 'a bakmak isteyeceksiniz. Görünürde önemsiz varyasyonlar üzerinde özellikle durun — PAM'la birlikte, onlar genellikle büyük değişikliklere yol açarlar.
    PAM kullanıcının ya yerel parola dosyasında ya da LDAP'ta olmasını ve yetkilendirme sürecinin devamı için doğru parolayı bilmesini gerektirir.
    Burada anlatıldığı şekliyle LDAP'ta yetkilendirme yapmak LDAP sunucusuna bağlantılar düz metin şeklinde olduğundan ve parolalar kabloda dolaştığından güvenli değildir.
    LDAP sunucusuna bağlantının şifrelendirilmesi yerine, aşağıda gösterilen PAM dosyaları, eğer Kerberos kurulumu yaptıysanız, yetkilendirme için Kerberos'u da destekler. Bu durumda, yorum satırı olarak gösterilen PAM satırlarını değiştirin ve yetkilendirme Kerberos kullanılarak tamamen güvenli ve doğru bir şekilde yapılır.
 
    /ETC/PAM.D/COMMON-ACCOUNT

account sufficient      pam_unix.so
account required        pam_ldap.so

# Enable if using Kerberos:
#account required        pam_krb5.so


    /ETC/PAM.D/COMMON-AUTH

# Disable the three lines if using Kerberos:
auth [success=1 default=ignore] pam_unix.so nullok_secure
auth required pam_ldap.so use_first_pass
auth required pam_permit.so

# Enable the three lines if using Kerberos:
#auth    sufficient        pam_unix.so nullok_secure
#auth    sufficient        pam_krb5.so use_first_pass
#auth    required          pam_deny.so

    /ETC/PAM.D/COMMON-PASSWORD

password sufficient   pam_unix.so nullok obscure md5

# Disable if using Kerberos:
password required     pam_ldap.so use_first_pass 

# Enable if using Kerberos:
#password required pam_krb5.so use_first_pass

    /ETC/PAM.D/COMMON-SESSION

session required        pam_unix.so
session required        pam_mkhomedir.so skel=/etc/skel/ umask=0022

# Enable if using Kerberos:
#session  optional  pam_krb5.so minimum_uid=1000

    Sisteme Giriş Yapma
    Herşey gösterildiği şekilde ayarlandıktan sonra, mirko kullanıcısıyla sisteme giriş başarılı olmalıdır:

Login: mirko
Password: PASSWORD

Debian GNU/Linux tty5

Creating directory '/home/mirko'.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
mirko@host:~$

    Sonuç
    Bu aşamada işlevsel bir LDAP kurulumuna sahipsiniz.
    Merkesi ağ yetkilendirmesi ve kullanıcı üstverisinin paylaşılması (kullanıcı IDsi, grup IDsi, gerçek isimler, grup üyelikleri vb.)
    Bunula birlikte, yukarıda bahsedildiği gibi LDAP üzerinden yetkilendirme yapmak LDAP sunucusuna bağlantılar düz metin şeklinde olduğundan ve parolalar kabloda dolaştığından güvenli değildir. Bu sorunu çözmek için ağ yetkilendirmesi için LDAP yerine Kerberos kullanılması tavsiye edilir.
    Ayrıca, kullanıcılar başarılı bir şekilde yetkilendirildiklerinde, giriş yaptılır ve ev dizinlerine yerleştirilirler. Bununla birlikte, merkezi ağ yetkilendirme şemasında, kullanıcıların yaratılmadığı tekil makinelerde karşılık gelen ev dizinleri vrolmayacaktır. Bu sorun yukarıdaki pam_mkhomedir modülü tarafından halledilir. Bu modül eksik ev dizinlerini otomatik olarak yaratır.
    Bunun anlamı kullanıcı ev dizinlerinin ayrı ayrı giriş yaptıkları her makinede oluşturulur. Kullanıcılar değişik makinelerde değişik dosyalara sahip olacağı için, bu sorunlara yol açabilir. Bu durum Kerberos kullanıldığı taktirde, Kerberized ağlar dosyaların makineler arasında güvenilir ve parolasız olarak kopyalanmasını sağladığı için, kendi başına tamamen kabul edilemez olmayacaktır. Yine de kusursuz bir çözümden çok uzakta olacaktır. Bu sorunu gelişmiş, güvenli, heavy-duty dağıtık ağ dosya sistemleri ile çözmek için serideki bir diğer makaleye, OpenAFS Guide 'a bakınız.
 
    Kurduğumuz iyi bir temelle, LDAP hakkında daha ayrıntılı bilgi için erişilebilir diğer kaynaklara da bakın:
    Ticari danışma ve AFS içeren infrastructure-based ağlar için, Spinlock Solutions ya da OpenLDAP destek sayfasındaki diğer kuruluşlarla iletişim kurun.  

    Linkler

Platformlar:
GNU
Debian GNU

LDAP:
OpenLDAP
Gq — Gtk LDAP İstemcisi
Luma — QT LDAP İstemcisi
jXplorer — Java LDAP İstemcisi
Apache Directory Studio — Eclipse-tabanlı LDAP İstemcisi
web2ldap — web-tabanlı LDAP İstemcisi

Glue layer:
NSS
Linux-PAM

İlişkil altyapısal teknolojiler:
MIT Kerberos
OpenAFS
FreeRADIUS

Ticari destek:
Spinlock Solutions
OpenLDAP support organizations

Diğer:
DocBook

NOT: Bu yazı [1]  adresindeki makalenin Türkçeye çevrilmiş/çevrilmeye çalışılmış halidir. Anlamsal ve söz dizimsel hatalar içerebilir.
[1]: http://techpubs.spinlocksolutions.com/dklar/ldap.html

21 Ekim 2011 Cuma

iptables


    IP Tables, güvenlik duvarı için Linux'ta kullanılan temel araçlardan birisidir. Linux'un çekirdek uzayındaki güvenlik duvarı gerçekleştirimi olan netfilter ile etkileşime giren, kullanıcı uzayında çalışan bir takım araçların bir araya gelmesinden oluşmuştur. IP Tables bir takım kurallar(rules) ve eylemlere(actions) göre davranır. Kurallar hangi paketler (ör. belli bir ağdan gelen paketler) için hangi eylemlerin (ör. paketlerin düşürülmesi) gerçekleştirileceğini belirlerler. Netfilter her paket için bütün kuralları sırasıyla işletecektir. Eşleşen bir kural bulduğunda bu kural için tanımlanan eylemi işletir.

$man iptables

ile kılavuzu okuyabilirsiniz.

Tablolar
iptabes ismi iptables'ın tablolar üzerinde çalıştığı gerçeğinden gelmektedir. Tabloların her biri belli bir paket davranışı üzerinde özelleştirilmiştir. Aşağıdakiler Linux 2.6.8 çekirdeği üzerinde varolan tablolardır(değişik çekirdek sürümlerinde değişik tablolar olabilir):

Tablo Anlamı
raw Paketlerin düşük seviye ayrıştırılması.
nat Paket başlığında değişiklikler (where NAT takes place).
mangle Özelleştirilmiş paket ayrıştırması.
filter Paket filtreleme.

Paketle ne yapmak istediğinize bağlı olarak uygun bir tablo bulunmaktadır.

Zincirler (Chains)
Ip Tables'ta, her tabloya yapışık ve herbiri farklı trafik tipiyle ilişkili birçok zincir vardır:


Zincir Anlamı
PREROUTING Yönlendirmeden(routing) devreye girmeden makineye gelen trafik.
INPUT Makinenin kendisine gelen trafik.
FORWARD Makine üzerinden geçen trafik (başka makinede üretilen, hedefi başka makine olan).
OUTPUT Yerel olarak yaratılmış trafik (hedef yerel ya da dış bir makine olabilir).
POSTROUTING Dışarı giden trafik.

Ayrıca kendi zincirlerinizi oluşturmak da mümkün.

Veri Akışı
Linux çekirdeğinde her tablo/zincirde veri akışı aşağıdaki grafikte gösterilmiştir. Her kutuda zincir ve o zincir için geçerli tablolar gösterilmiştir. Trafik her zincir için geçerli her tablodan sırasıyla geçmektedir. Örneğin,  PREROUTING zincirinde raw, mangle ve nat tabloları var. Trafik akışı sırasıyla bu tabloların üçünden de geçer.



       Incoming
       Traffic
          |
          |
          V
     +----------+
     |PREROUTING|
     +----------+
     |   raw    |  <--------------+
     |  mangle  |                 |
     |   nat    |                 |
     +----------+                 |
          |                       |
          |                       |
       Routing                    |
    +- Decision -+                |
    |            |                |
    |            |                |
    V            V                |
  Local        Remote             |
Destination   Destination         |
    |            |                |
    |            |                |
    V            V                |
+--------+  +---------+           |
| INPUT  |  | FORWARD |           |
+--------+  +---------+           |
| mangle |  | mangle  |           |
| filter |  | filter  |           |
+--------+  +---------+           |
    |            |                |
    |            |                |
    V            |                |
  Local          |                |
 Machine         |                |
    |            |                |
    |            |                |
    V            |                |
 Routing         |                |
 Decision        |                |
    |            |                |
    |            |                |
    V            |                |
+--------+       |                |
| OUTPUT |       |                |
+--------+       |                |
|  raw   |       |                |
| mangle |       |                |
|  nat   |       |                |
| filter |       |                |
+--------+       |                |
    |            |                |
    |      +-------------+        |
    |      | POSTROUTING |      Local
    +----> +-------------+ --> Traffic
           |   mangle    |
           |     nat     |
           +-------------+
                 |
                 |
                 V
              Outgoing
              Traffic


Örnek olarak makinede üretilen ve yine makineye dönen bir trafik şu şekilde bir yol izler:

  1. Paket yerel bir süreç ya da çakirdek tarafından üretilir
  2. Yönlendirme kararı
  3. OUTPUT: raw
  4. OUTPUT: mangle
  5. OUTPUT: nat
  6. OUTPUT: filter
  7. POSTROUTING: mangle
  8. POSTROUTING: nat
  9. PREROUTING: raw
  10. PREROUTING: mangle
  11. PREROUTING: nat
  12. Yönlendirme kararı
  13. INPUT: mangle
  14. INPUT: filter
  15. Paket yerel bir süreç ya da çekirdek tarafından alınır
 Kurallar (Rules)
Belli zincir/tablolar için hangi paketlere hangi eylemlerin uygulanacağını belirlemek için kurallar tanımlamak yeterlidir. Bütün kurallar bütün zincirlere uygulanmaz.

Zincir yönetiminde kullanılan bazı seçenekler ve parametreler
Zincir yönetiminde kullanılan seçenekler:
-N: Yeni zincir ekleme
-X: Boş zincir silme
-P: Temel zincirlerdeki kuralı (policy) değiştirme
-L: Zincir kurallarını listeleme
-F: Zincirlerdeki kuralları boşaltma
-Z: Zincirlerdeki paket ve byte sayacını sıfırlama

Zincirlere kural tanımlamak için:
-A: Zincire yeni kural ekleme
-I: Zincirde herhangi bir konuma kural eklemek için
-R: Zincirde herhangi bir konumdaki kuralı değiştirmek için
-D: Zincirden herhangi bir kural silmek için

Zincirdeki kuralların yönetiminde kullanılan parametrelerden bazıları:
-p: protokol
-s: kaynak makine
-d: hedef makine
-i: Giriş işleminde kullanılacak arabirim
-o: Çıkış işleminde kullanılacak arabirim
-j: Uygulanacak kural
-t: Kullanılacak zincir

Basit Komutlar
sudo iptables -L

komutu iptables'taki kurallarınızı listeler. Eğer henüz herhangi bir kural tanımlamadıysanız şu şekilde bir çıktıyla karşılaşıcaksınız:

Chain INPUT (policy ACCEPT)
target prot opt source destination

Chain FORWARD (policy ACCEPT)
target prot opt source destination

Chain OUTPUT (policy ACCEPT)
target prot opt source destination

Kurulu Oturumlara İzin Vermek:
Halihazırda kurulu oturumların trafiğine izin vermek için:
$sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

Belli Bir Porttan Gelen Trafiğe İzin Vermek
Öntanımlı SSH portundan (22) gelen trafiğe izin vermek için, iptables'a bu porttan gelen bütün TCP trafiğine izin vermesini söyleyebilirsiniz:
$sudo iptables -A INPUT -p tcp --dport ssh -j ACCEPT
Komutu incelersek:
  • -A INPUT: Gelen trafiğe bakmak için kuralı girdi zincirine ekliyoruz
  • -p tcp: TCP olup olmadığına bakıyoruz
  • --dport ssh: Eğer öyleyse, girdinin ssh portuna gidip gitmediğine bakıyoruz
  • -j ACCEPT: Eğer öyleyse, girdiyi kabul ediyoruz
Bu eklemelerden sonra kuralları tekrar kontrol edersek:
$sudo iptables -L
 Chain INPUT (policy ACCEPT)
target     prot opt source               destination       
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh

Şimdi gelen bütün web trafiğine izin verelim:
$sudo iptables -A INPUT -p tcp --dport 80 -j ACCEPT
Kurallarımızı tekrar kontrol edelim:
$sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
Özel olarak ssh ve web trafiğine izin verdik ama herhangi bir engelleme yapmadığımız için bütün trafik devam edecektir.

Trafiği Engelleme
Bir paketi kabul etmek için bir kural tanımladığımızda, diğer kurallar onu etkilemez. Ssh ve web trafiğine izin veren kurallarımız önce geldiği sürece bütün trafiği engellesek de bu portlardan gelen trafik devam edecektir. Önemli olan bu kuralı sona eklemektir:
$sudo iptables -A INPUT -j DROP
$sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
DROP       all  --  anywhere             anywhere
Özel olarak herhangi bir arayüz(interface) belirtmediğimiz için, ssh ve web haricinde bütün portlardaki ve arayüzlerdeki trafik engellenir.
iptables Düzenleme
Son tanımladığımız kuralla loopback arayüzü de engellenmiş oldu. Engelleme kuralını özel olarak -i eth0 ile sadece eth0 için tanımlayabilirdik. Bunun yanında loopback için de bir kural ekleyebiliriz. Kuralımızı eklediğimizde en sona geleceği ve onun öncesinde bütün trafiği engellediğimiz için bir işe yaramayacaktır. Bu yüzden bu kuralı dah önceye eklemeliyiz:
$sudo iptables -I INPUT 1 -i lo -j ACCEPT
$sudo iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination        
ACCEPT     all  --  anywhere             anywhere           
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             tcp dpt:http
DROP       all  --  anywhere             anywhere
Bu açıdan bakınca ilk ve son satır neredeyse aynı. Daha detaylı bakmak için:
$sudo iptables -L -v
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination        
    0     0 ACCEPT     all  --  lo     any     anywhere             anywhere           
 2661  616K ACCEPT     all  --  any    any     anywhere             anywhere             state RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:ssh
    0     0 ACCEPT     tcp  --  any    any     anywhere             anywhere             tcp dpt:http
  222 24504 DROP       all  --  any    any     anywhere             anywhere


Kaynaklar:

9 Mayıs 2011 Pazartesi

Geliştirici Ailesinin En Yeni Üyesi

    Bugün geliştiri listesine gönderilen bir maille geliştici adaylık başvurumu başarıyla tamamladığım ve geliştirici ailesinin en yeni üyesi olduğum duyuruldu[1] :) Benim için çok sevindirici bir haber, o yüzden tüm ayvalı ıhlamurlar benden :) Bu yazıda da bu güne kadar ki süreçten kısaca bahsetmek istedim.
   Çomak projesine başlamamızla beraber Necdet Hoca'nın da dürtmesiyle Pardus geliştiricisi olmak için başvurmuştum. Sürecin nasıl işlediğine dair belge şurada[2]. Hata kaydını açtıktan sonra cevaplamam için 12 sorudan oluşan bir quiz gönderildi ve 10 gün içinde soruları cevaplamam istendi. Daha önceki bildiklerim ve bilmediklerimi de araştırıp öğrenerek soruları cevapladım ve gönderdim. Bundan sonra süreç oldukça yavaş işledi ve geri dönüş almam 3 aydan uzun bir zaman aldı. Ama sonunda cevap geldi ve birkaç gün de mentor atanmasını bekledikten sonra bişeyler yapmaya başlayabildim. Bunun için bugzillada junior job olarak işaretlenmiş hatalardan birini seçmem gerekiyordu.
    İlk olarak zsync paketini seçtim. Çomak projesinde çalışırken çokça yaptığım bir iş pisi paketi yapmak ve bu konuda biraz tecrübe edindim diyebilirim. Her neyse hızlıca zsync programını paketledim ve paket 2011 depolarındaki yerini aldı[3][4]. Daha sonra bir python modülü olan python-protobuf-socket-rpc ile ilgilendim[5][6]. O da pek fazla sorun yaşamadan review sürecinden geçerek depolara girdi. Bir sonraki adımda "Bejeweled" veya "Diamond Mine" benzeri bir bulmaca oyunu olan gweled ile uğraştım. Gweled de bu süreç sonunda depolara girdi[7][8]. En son uğraştığım hata ise giver uygulamasının paketlenmesiydi[9]. Onu da paketledim ancak bağımlılıklarının depolarda olmaması gibi sebeple giver depolara giremedi. Bu aşamada mentorum Gökhan Özbulak geliştirici adaylık sürecinde yaptığım çalışmaların yeterli olduğunu söyledi ve bugün itibariyle adaylık başvurusu hatam kapanarak Pardus geliştiricisi oldum.
    Benim için oldukça zevkli, bilgilendirici ve zevkle çalıştığım bir süreç oldu. Mentorum Gökhan Özbulak ve hocam Necdet Yücel başta olmak üzere bu süreçte bana yardımını ve desteğini esirgemeyen herkese çok teşekkürler ederim. Bundan sonra da elimden geldiğince Pardus'a katkı vermeye çalışacağım.


[1]http://lists.pardus.org.tr/gelistirici/2011-May/056248.html
[2]http://developer.pardus.org.tr/guides/newcontributor/how-to-be-contributor.html
[3]http://bugs.pardus.org.tr/show_bug.cgi?id=17075
[4]http://bugs.pardus.org.tr/show_bug.cgi?id=17270
[5]http://bugs.pardus.org.tr/show_bug.cgi?id=15132
[6]http://bugs.pardus.org.tr/show_bug.cgi?id=17509
[7]http://bugs.pardus.org.tr/show_bug.cgi?id=16674
[8]http://bugs.pardus.org.tr/show_bug.cgi?id=17763
[9]http://bugs.pardus.org.tr/show_bug.cgi?id=8854