Upstart ve System V init Karşılaştırması

Ubuntu Boot Proseslerinin devamı olan çeviri ve notlarıma Upstart konusuyla devam ediyorum. Aradaki farkları görmem için iyi oldu. Upstart scriptleri yazabilecek seviye gelmeye çalışacağım. Önümüzdeki yazı da büyük bir ihtimalle o konuyla ilgili olacak.

System V init iyi bir sistemdi ve Linux üzerinde yıllarca iyi bir şekilde çalıştı. Buna rağmen kusursuz değildi. Eğer servisler sonlanırsa init scripti bunları tekrardan yaratacak otomatik bir mekanizmaya sahip değildi. Örneğin planlanmış programları çalıştıran cron programı (cron daemon, UNIX man pages) bazı sebeplerden dolayı patlarsa, bunu izleyebileceğiniz ve prosesi yeniden başlatabileceğiniz bazı araçlara ihtiyacınız olacaktır.

init scriptlerle ilgili diğer bir problem ise genellikle runlevel değişimlerinde ve sistem açılışında etkili olmalarıdır bunların dışında elle müdahale etmediğimiz sürece çalışmayacaklardır. Network bağlantısına bağımlı olan init scriptler buna güzel bir örnek. Ubuntu üzerinde networking adındaki init script ağ bağlantılarını sağlar. Ağ bağlantısına bağımlı olan bütün scriptler bu init scriptten daha sonra gelen bir isimle tanımlanmıştır ve böylece ağ bağlantısı kurulduktan sonra çalışırlar. Eğer ağ kablosunu çıkarıp sistemi çalıştırırsak ne olur? Networking scripti çalışır fakat ağ bağlantısına ihtiyaç duyan diğerleri birer birer zaman aşımına uğrar. Er ya da geç giriş ekranına gelecek ve giriş yapabileceksiniz. Sisteme giriş yaptıktan sonra ağ kablosunu takıp networking sevisini yeniden başlatırsanız ağa bağlanacaksınız ama ağ bağlantısına ihtiyaç duyan servislerin hiç birisi otomatik olarak başlamayacaktır. Hepsini elle tek tek yeniden başlatmak zorundasınız.

Upstart sadece System V init’in eksikliklerini kapatmak için tasarlanmadı ayrıca daha dayanıklı bir yönetim servisleri sistemini sağlar. Upstart ana getirilerinden birisi olay güdümlü olmasıdır. Upstart sürekli olarak kaçınılmaz olayların olmasını izler ve olduklarında bu durumlara göre kendisini yeniden konfigüre edip harekete geçer. Bazı örnek olaylar, açılış, kapanış, CTRL+ALT+DEL tuş kombinasyonuna basılması, renlevel değişimi ve Upstart scriptinin çalışması veya durmasıdır. Olay güdümlü sistemin geleneksel init scriptini nasıl geliştirdiğini görmek için ağ bağlantısı kesilmiş bir sistemin boot edildiği örneğine geri dönelim. Network kablosu bağlanınca tetiklenecek bir Upstart scripti yazabilirsiniz. Bu servis sizin için ağ servisini yeniden başlatabilir. Ağ bağlantısına ihtiyaç duyan servisleri, ağ servisi başarılı bir şekilde sağlandığında tetiklenecekleri şekilde konfigüre edebilirsiniz. Şimdi boot işlemi olurken istediğiniz zaman ağ kablosunu takabilirsiniz, Upstart scriptleri bütün hepsiyle ilgilenecektir.

Upstart, System V init yapısının yerini tamamıyla almamıştır ama en azından servisler için getirilmiştir. Upstart şu anda init ve /etc/inittab dosyasının görevini yerine getirmektedir ve runlevellarındaki değişiklikleri, açılış ve kapanışları, uçbirim ttyleri, daha fazla çekirdek özelliklerini halledebilecek kadar geliştirilmiştir. Fakat /etc/init.d içindeki standart init scriptlerini ve bütün /etc/rc?.d sembolik bağlantılarını (symlinks) hala bulabilirsiniz. Şu anda aralarındaki fark Upstart runleveller değişince servisleri çalıştırıp durdurmaktadır.

Bu yazı aşağıdaki yazımın devamıdır.

http://www.cagdastopcu.com/ubuntu-boot-prosesleri.html

Kullanılan kaynaklar:

Official Ubuntu Server Book (The Second Edition)

UNIX man page

Ubuntu Boot Prosesleri

Bu yazımda Ubuntu Server sisteminde boot işlemi üzerine tuttuğum notları ve çevirimi paylaşıyorum. Boot işlemi benim için her zaman büyülü anlaşılması zor olan bir kavramdı. Şimdi bunun oldukça mantıklı bir sistemle ve gereksinimler üzerine inşa edildiğini anladım.

Proseslerin Kontrolü

Öncelikle işimize yarayacak bazı kodlara bakalım. Bunları eminim herkes biliyordur ancak hatırlatma gibi olsun istedim.

  • top

Sistemimizdeki en çok sistem kaynaklarını tüketen programları anlık olarak takip etmemizi sağlar.

  • ps -ef

Sistem açıldığından itibaren kullanılan prosesleri yazdırır.

  • ps – ef | less

Bir önceki komutun çıktısını daha sade hale getirir.

  • kill $PID

Proses ID’si ile prosesi sonlandırmanızı sağlar.

  • kill -9 $PID

Her proses kill işlemine cevap vermeyebilir bunun için onu zorlayabiliriz. Bu koddan önceki kodu denememiz daha uygundur. Böylece proses kendisini daha düzgün sonlandırmayı dener.

Çıktılar ekrana sığmıyorsa shift PgUp-PgDown tuşlarıyla sonuçlar üzerinde gezinebilirsiniz.

 Sistemde root hesabını kullanmak güvenlik açısından pek tavsiye edilmez. Onun yerine hepimizin sevgilisi olan sudo kullanılır :)

  • sudo reboot

 

Ubuntu Boot Prosesleri

Ubuntu Upstart servisleriyle tamamiyle değişik start-up prosesi kullanır. System V init modeliyle uyumlu olarak tasarlanmıştır.

Grub Boot Loader

Mster Boot Record’da (harddiskin ilk 512 byte’ı) bulunan bir koddur. Hangi Linux kernelinin boot edileceğini kontrol eder.

 

Konfigurasyon dosyası: /boot/grub/grub.cfg.

 

Bu dosyayı elle değiştirmiyoruz. Değişiklik yapmak istersek /etc/default/grub u düzenliyor ve aşağudaki kodu çalıştırıyoruz:

 

  • sudo update-grub

Desktop versiyonu için bunu kullanmamız gerekmese de Ubuntu Server için bu dosya üzerinde değişiklikler yapmamız gerekebilir. Dökümantasyon için bu konfigurasyon dosyalarındaki yorumları veya projenin kendi sitesine bakabilirsiniz. Döküamnın hepsi için:

 

  • info -f grub -n ‘Simple configuration’

Grub ayarları açılışta da yapılandırılabilir. Eğer Grub menüsünü göremiyorsanız shift tuşuna basın. Ardından menüde değiştirmek istediğiniz Kernel sürümünü seçip E tuşuna basın. Bundan sonra istediğiniz ayarı değiştirebilirsiniz. Ctrl x ile menüye geri dönün.

Eğer shift tuşuna zamanında basmakta zorlanıyorsanız /etc/default/grub içindeki GRUB_HIDDEN_TIMEOUT değeri daha büyük bir değerle değiştirin (10 gibi) ardından

  • sudo update-grub

komutunu çalıştırın.

Kernel Boot Prosesi

GRUB menüsünden kerneli seçtiğimizde GRUB o kerneli bellekteki initrd dosyasına (initial RAM disk) yükler. initrd dosyası aslında initramfs dosyası olarak bilinen gziplenmiş cpio arşividir. Eğer bu özel initramfs dosyasına eklenen dosyaları merak ediyorsanız aşağıdaki işlemleri uygulayınız:

  • cp /boot/initrd.img-3.0.0-12-server /tmp/initrd.img-3.0.0-12-server.gz

  • cd /tmp

  • gunzip initrd.img-3.0.0-12-server.gz

  • mkdir initrd

  • cd initrd

  • cpio -idv < /tmp/initrd.img-3.0.0-12-server

Şimdi bu /tmp/ dizininde root dizinine benzer dizinlerin bir kısmını göreceksiniz. Kernel boot olurken öncelikle temel konfigürasyon dosyalarına, kernel modüllerine ve sistem binarysini yükleyecek kadar root dosya sistemini oluşturur.

 

Kernel modüllerinin root dosya sisteminde olması, o dosya sistemine erişebilmek için de bu kernel modüllerine ihtiyaç duyulması mantıksal bir problem oluşturur(tavuk yumurta problemi). Bu da initramfs dosyasına açıklık getirir. initramfs dosyası root dosya sisteminin yüklenebilmesi ve boot işlemine devam edilmesi için gerekli olan temel kernel modülleriyle birlikte kerneli ve sistem binarisini sağlar. Kernel derlenirken kernelin boot olabilmesi için gerekli olan bu initramfs dosyasını yapılandırır.

Kernel boot olurken initramfs RAM’e açılır ve onun root dizinindeki init scripti çalışır. Yukarıdaki yönergeyi izleyerek bu koda ulaşabilirsiniz. Mount işlemlerini sağlayan bash kodundan ibarettir. Görevini tamamladıktan sonra kurduğu gerçek root dosya sistemindeki /sbin/init kodunu çalıştırır. Bu boot prosesindeki diğer fazı başlatır.

/sbin/init

/sbin/init programı sistemde çalışan bütün programların öncül prosesidir. Bu prosesin PID’si her zaman 1′dir ve Linux sistemindeki bütün proseslerden sorumludur. Unix sistemlerinde farklı başlatma standratları vardır fakat klasik Linux sistemlerinin çoğunluğu System V init modelini kullanır. Ubuntu Server bunun yerine Upstart modeline geçmiştir. Ubuntu runlevels ve /etc/rc?.d dizinleri gibi bir çok yapıyı eskiye yönelik uyumluluk için korumuştur. Upstart artık kaputun altındaki herşeyi yönetmektedir.

Classic System V init

Bu init sisteminde, init prosesi /etc/inittab konfigürasyon dosyasını öntanımlı runlevelini keşfetmek için okunur. Ardından bu runlevele (çalışma aşaması) girilir ve runlevelde çalışacal konfigüre edilmiş prosesler çalıştırılır.

RUNLEVELLAR

System V init prosesi farklı sistem durumlarıyla tanımlanmıştır bunlar runlevelleri olarak bilinir. Runlevelleri 0′dan 6′ya kadar numaralarla ayrılmıştır. Her numara tamamiyle değişik durum sistemini belirtir. Örneğin runlevel 0 halted sistem durumu için ayrılmıştır. Eğer runlevel 0′a girerseniz, sistem bütün prosesleri kapatır, bütün sistem dosyaları unmount edilir ve enerji kesilir. Runlevel 6 ise reboot işlemi için ayrılmıştır. Runlevel 1 tek kullanıcı modu için ayrılmıştır-sadece bir kullanıcı bu durumda sisteme giriş yapabilir. Bu tek kullanıcı modunde genellikle az sayıda proses çalıştırılır. Sistemin tamamıyla boot olamadığı durumlarda arıza giderimi için oldukça kullanışlıdır. GRUB menüsündeki recovery modu runlevel 1′e girmenizi sağlar.

2′den 5′e kadar olan runlevelleri dağıtımların tanımlaması için bırakılmıştır. Birçok Farklı runlevellerinin olmasının altında yatan serverin girebileceği birçok modu kullanıcının yaratabilmesini sağlamaktır. Geleneksel olarak Linux sistemleri bir grafik masaüstü runleveli (RedHat için 5) ve bir de grafiksiz runleveli (RedHat için 3) içerirler. Kullanıcı diğer runlevellerini tanımlayabilir, örneğin network bağlantısı olmadan açılış gibi. Boot ederken bu runleveli seçebilirsiniz. Ayrıca sistem boot edildikten sonra init komutu ile runlevelinizi değiştirebilirsiniz. Ubuntu Server sisteminizde tek kullanıcılı moda geçmek için aşağıdaki kodu çalıştırabilirsiniz.

  • sudo init 1

Sisteminizi kapatmak için halt komutuna alternatif olarak aşağıdaki kodu kullanabilirsiniz.

  • sudo init 0

init Scriptleri

/etc/inittab’ın yanında sistemdeki bütün büyük servsiler için açılış ve kapanış scriptleri, init scriptlerini barındıran önemli V System dosya ve dizinleri içerir.

etc/init.d

Bu dizin bütün runlevellerindeki açılış scriptlerini içerir. Bunlar tipik olarak shell scriptleridirler ve temel standartlara uyarlar. Her script en az iki argümana sahiptir. Bunlar başla ve dur’dan oluşur ki bunlarla servisiniz başlatılıp durdurulur (örneğin Web Server). Buna ek olarak init scriptleri başka özellikleri de içinde barındırır. Bunlar, restart (servisi durdur ve çalıştır), status (servisin o anki durumunu geri döndürür), reload (servise konfigürasyon dosyalarından ayarların tekrar yüklenmesini söyler) ve force-reload (servisi ayarları yeniden yüklemesi için zorlar). Eğer scripti argümansız çalıştırırsak, genellikle kabulettiği argümanların listesini geri döndürecektir.

/etc/rc0.d – /etc/rc6.d

Bu dizin runlevellerine göre init scriptlerini içerir. Pratikte bunlar /etc/init.d’deki gerçek dosyalara sembolik olarak (symlink) bağlanmışlardır. Bu init scriptleri D,S,K gibi haflerle başlamış ve ardından bir sayı gelen isimlendirmeye sahiptir. init bir runlevel’e girdiğinde K ile başlayan bütün scriptleri sayısal sırasıyla çalıştırır ve dur argümanına geçer (bu sadece çağırılan init script önceki runlevel’e aitse geçerlidir). Daha sonra init script bütün S scriptlerini sırasıyla çalıştırır ve başla argümanına geçer. D ile başlayan bütün scriptler ihmal edilir. Bu size özel bir runlevelde bir init scriptini geçici bir süre için kapatabilmenize izin verir. Sadece symlinkini silerek de bunu yapabilirsiniz. S01foo ve S05bar adında iki scriptimiz olsun, init scriptimiz farklı bir runlevele girdiğinde önce S01foo start ardından S05bar start işlemlerini çalıştırır.

/etc/rcS.d

Bu dizinde açılış esnasında runleveli değişmeden önce çalışan bütün init scriptlerini bulabilirsiniz. Bu dizindeki scriptlerde değişiklikleri yaparken dikkatli olmalısınız çünkü bu tek kullanıcı moduna (kurtarma kipi) geçmenizi engelleyebilir.

/etc/rc.local

Bütün dağıtımlar rc.local kullanmaz ama geleneksel olarak bu kullanıcının değiştirebileceği bir shell scriptidir. Bu genellikle init işleminin sonunda çalıştırılır. Yeni bir init scripti oluşturmaya gerek kalmadan kendi kodlarnızı koyabilirsiniz.

V System init sistemini bir boot örneğiyle açıklayalım. İlk önce init çalışır ve /etc/inittab ‘ı öntanımlı runleveli belirlemek için okur, bizim örneğimizde bu runlevel 2. Ardından init /etc/rcS.d’ye gider ve S ile başlayan bütün scriptleri start argümanıyla çalıştırır. Daha sonra aynı işlemi /etc/rc2.d dizini için yapar. Son olarak init durdurulmuştur ancak runlevelin değişmesini bekler halde arkaplanda çalışmaya devam eder.

Bu yazının ardından devamı niteliğinde Upstart konusu üzerinde durulacaktır. Yazıdaki kodlar Ubuntu Server 11.10 Virtualbox üzerinde denenmiştir. Kaynak olarak http://www.amazon.com/Official-Ubuntu-Server-Book-Edition/dp/0137081332/ref=dp_ob_title_bk kitabı kullanılmıştır.

Upstart Bölümü geçikmedi :) Yazının devamını aşağıdaki linkten okuyabilirsiniz:

http://www.cagdastopcu.com/upstart-ve-system-v-init-karsilastirmasi.html

 

Linux BackTrack 5 Kitabı Çıktı

Kemal Demirez’in yeni kitabı Linux BackTrack 5 çıktı. Bugün aldım çok merak ettiğim konular var içerisinde. Fiyatı kitapçılarda 20 lira. Ancak yazarına ulaşarak incelemek için ücretsiz olarak temin eden ubuntu-tr kullanıcısı da var. Kitap daha çok nereden başlayacağını bilmeyen güvenlikle alakalı konuları merak eden insanlar için yazılmış.

Bölüm bölüm içindekileri aktarmaya çalışacağım:

1- Tanımlar

Güvenlik ve internetle ilgili temel tanımlar var. Porttan Buffer Overflow’a kadar bir çok terim kısa kısa açıklanmış.

2- BackTrack 5 Kurulumu

Vmware üzerine kurulumu anlatılmış ve genel olarak BackTrack 5 dağıtımı hakkında bilgiler verilmiş.

3- Linux Shell ve Konsol

Basit shell komutları, genel olarak penetrasyon ve test methodları ile izlenen yollar anlatılmış.

4- BackTrack Araçları

En güzel bölüm bu sanırım. WireShark’tan Metasploit’e bir çok program giriş seviyesinde anlatılmış.

5- Forensics

6- Raporlama Araçları

Güvenlikle alakalı konuları merak edenler için güzel bir giriş kaynağı. Okudukça yorumlarımı paylaşacağım.

Java ile Thread Kullanarak Socket Programlama

Bu yazımda çok işlevsel olmasa da Android için telnet client’ı yazarken kullandığım echo server kodlarını anlatacağım. NIO paketini kullanmadığım için aslında çok da sağlıklı değil ve her bağlantı için ayrıca bir thread oluşturulmaktadır. Bu nedenle çok fazla yüklenmelere dayanamayacak bir server olacak bizimkisi.

Önce Java’da socket işleri nasıl yürüyor ona bakalım. Javada ServerSocket ve Socket olmak üzere kullanıma hazır iki socket türü var(Aslında LocalSocket de var). Server sürekli bekleme işini yaptığımız ve dışardan birisi bağlanırsa ona gereken cevabı verdirttiğimiz makinede sürekli çalışmak zorunda olan programımız. ServerSocket sınıfının constructoru ile hangi porttan bu server hizmetini vereceğimizi belirlememiz gerekiyor.

Olay ise şundan ibaret:

1- ServerSocket’imiz bir portu izler durur.

2- Client bir Socket yardımıyla bizim Server’ımızın portuna naber der.

3- ServerSocket bu bağlantıyı accept() static methoduyla aldıktan sonra bir socket oluşturur.

4- Bu oluşturulan socket ile haberleşirler. Ve mutlu son :)

Neden Thread Kullanmalıyım?

Çok basit! Server’a birden fazla client’ın bağlanabilmesi için bu yapılır. Client tarafından gelen verinin ne kadar sürede geleceği belli değildir. Bu sebeple o verilerin alınma işlemleri bir thread’ın run methodunun içine gömülür. Ardından serverda start() static methodu ile thread çalıştırılır.

Server’ımızın Kodu:

 

package com.cagdas.network;

import java.io.IOException;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;

public class EnterpriseEchoServer {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ServerSocket ss;

		try {
			ss = new ServerSocket(23);
			System.out.println(InetAddress.getLocalHost() + " hazir");
			while (true) {

				Socket s = ss.accept();
				System.out.println(s.getInetAddress().getHostName() + " "
						+ s.getInetAddress().getHostAddress() + " baglandi");
				new EESThreadPart(s).start();
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}// Telnet hizmeti

	}

}

Burada 23 numaralı telnet portunu seçtim. Kodda görüldüğü üzere s socketi serversocketinin accept metodu ile gelen isteği kabul edilip oluşturuluyor. getInetAdress() methodu ile bağlanan kişinin bilgileri HostName ve HostAdress gibi bilgileri alınabiliyor. Ardından s socketi thread’li kısma gönderiliyor.

 

Thread kullanılan Sınıf

 

package com.cagdas.network;

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

public class EESThreadPart extends Thread {

	private Socket s;

	public EESThreadPart(Socket s) {

		this.s = s;
	}

	public void run() {
		PrintStream pr;
		try {
			pr = new PrintStream(s.getOutputStream());
			Scanner sc = new Scanner(s.getInputStream());
			pr.println("Server'a baglandiniz. Cikmak icin bye yazin."); // Client'a
			String gelen; // gonderiliyor
			while (true) { // sonsuz dongu
				gelen = sc.nextLine(); // client'dan geliyor
				if (gelen.trim().equalsIgnoreCase("bye"))
					break;
				System.out.println("Client:" + gelen);
				pr.println("Echo:" + gelen);
			}
			s.close();
			System.out
					.println(s.getInetAddress().getHostName() + " "
							+ s.getInetAddress().getHostAddress()
							+ " serverdan cikti!");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}

Burada PrintStream kullanılarak Client’a veri gönderilmiş ve ondan gelenler de Scanner yardımıyla sonsuz döngü içerisinde beklenmiştir. Bye yazıca client ile bağlantıyı sağlayan socket sonlandırılmakta.

Server’ımızı Nasıl Deneriz?

Telnet portunu (23) kullanmamızın bir nedeni vardı :) Herhangi bir telnet clientı ile programınız çalışıyorken denemelerinizi yapabilirsiniz. Mesela ubuntuda şöyle kullanılabilir:

cagdas@cagdas-K53SV:~$ telnet
telnet> open localhost
Trying 127.0.0.1…
Connected to localhost.
Escape character is ‘^]’.
Server’a baglandiniz. Cikmak icin bye yazin.

Google Android SDK Tehlikelidir Yasaktır

Saçmalık ancak Android’in sitesi birçok google hizmeti gibi yasaklanmış. Android için yazılım geliştirmede kullanılan SDK’yı ubuntuda kurmak istiyorsanız önce haysiyetsiz beyinciklerce yasaklanmış olan google sitelerini açıyoruz. Bunun için komut satırına

sudo gedit /etc/hosts

yazın ve çıkan dosyaya aşağıdakileri kopyalayıp kaydedin. Böylece rahatça sdk’nızı indirip programlamaya başlayabilirsiniz.

Continue reading