lf278, SystemAdministration: Sistem yönetimini ssh ve scp ile otomatikleştirmek
Bu makalenin farklı dillerde bulunduğu adresler: English Castellano Deutsch Francais Italiano Nederlands Russian Turkce Polish
tarafından Erdal Mutlu
Erdal, LF'nin Türk editörlerinden birisidir. Şu anda Sistem yöneticisi olarak Linotype Library'de çalışmaktadır. Üniversite yıllarından beri bir Linux hayranıdır ve bu ortamda çalışmaktan ve uygulama geliştirmekten hoşlanmaktadır.
Neden ssh kullanalım?
Dosya ve dizinlerin scp ile kopyalanması
ssh kullanarak komut çalıştırmak
Uzakataki bilgisayara geçişsözcüğü kullanmaksızın bağlanmak
Yapılandırım dosyalarınızın yedeğini almanın basit bir yolu
Sistem yönetimini ssh ve scp ile otomatikleştirmek
Eğer, yönetmekte olan Linux/Unix bilgisayarlarınızın sayısı çok ise, bazı işleri otomatik yapmak için kabuk programlarına gereksiniminiz olacaktır. Günlük çalışmalarınız sırasında yaptığınız işlemler her sistem için aynı veya hemen hemen aynı olduğunu fark etmişsinizdir. Belkide bu işleri otomatik olarak yapmanın yollarını da düşünmüşsünüzdür. Bu durum özellikle benzer şekilde yapılandırılmış çok sayıdaki Linux/UNIX sistemleriniz varsa geçerlidir. Bu yazıda bunu yapmak için ssh araçlarını kullanan bir yöntemi size tanıtacağım.
Aslında yapılması gereken, kullandığım bilgisayardan belirleyeceğim dosyaları bazı sunuculara veya iş istasyonlarına kopyalamak ve daha sonra da onlara bağlanıp rpm ile program yükleme gibi bazı sistem ayarlarını değiştirici komutlar çalıştırmaktır. Bazen öncelikle çeşitli komutlar çalıştırıp daha sonra da bir takım dosyaları, ki bunlar çalıştırdığımız komutların sonucu oluşmuş dosyalar da olabilir, kendi bilgisayarımıza kopyalamak isteyebiliriz.
Bu yazıyı takip edebilmek için kabuk programlama ile ilgili temel bilgiye sahip olmanız gerekmektedir. Kabuk programlama ile ilgili daha fazla bilgi LF'nin Katja ve Guido Socher tarafından yazılmış Kabuk programlama yazısını okuyabilirsiniz. Ayrıca, ssh-keygen, ssh-add, scp, sftp gibi ssh araçları hakkında da bilgi sahibi olmanız gerekmektedir. SSH protokolünün Linux için serbest yazılım çerçevesinde geliştirilmiş araçlarını OpenSSH'dan bulubilirisniz. Ayrıca, bunların man sayfaları da vardır.
Sorunun cevabı iyine bir sorudur: Neden olmasın? rsh-rcp veya telnet-ftp ikililerini de kullanmak mümkündür, ancak bunlar İnternet ve belkide iç ağlar gibi, kullanılması güvenli olmayan ortamlar için uygun olmayabilirler. Ssh güvenli olmayan bir ağ'da iki bilgisayar arasında kriptolanmış bir bağlantı sağlamaktadır. Bu araçların kullanımdan doğabilecek güvenlik risklerini burada anlatmayacağım. Bunun için Georges Tarbouriech'ın Tunel içerisinden yazısına bakabilirsiniz.
Aslında geçmişte ben telnet/ftp kullanan kabuk programları kullanmıştım.
Yerel bilgisayardan başka bir bilgisayara bir dosya kopyalamak için aşağıdaki komutu kullanabilirsiniz:
Bu örnekte yerel bilgisayardaki file1 dosyası remote_host (Bu IP adresi de olabilir.) adındaki bilgisayarın /remotedir dizinine newfile yeni ismiyle kopyalanmaktadır. Eğer, 'user' olarak girdiğiniz geçişsözcüğü doğru ve kopyalamak için gerekli haklara sahip iseniz, kopyalama işlemi gerçekleştirilecektir. İsterseniz hedef dosya ismin vermeyebilirsiniz. Bu durumda dosya aynı isimle kopyalanacaktır. Kısacası, kopyalama sırasında dosya adını değiştirmek mümkün olmaktadır.
Kopyalama yönünü değiştirmek de mümkündür. Başka bilgisayardaki bir dosyayı kendi bilgisayara da kopyalamak:
scp komutunun çok kullanışlı bir özelliği daha var. Bir dizini tüm içeriği ile birlikte, yani tüm dosyaları ve dizinleri ile birlikte kopyalamak için '-r' seçeneği kullanılmaktadır.
Yukarıdaki komut, remote_host adlı bilgisayarda bulunan remotedir dizini ve içerdiği tüm dosya ve dizinleri ile birlikte bulunduğumuz dizin altına aynı adla kopyalamaktadır. Not:Burada remote_host adlı bilgisayarda sshd servisinin çalıştığı varsayılmıştır.
rlogin veya telnet yerine daha güvenli olan ssh kullanılabilir:
Yapılandırmanıza göre geçişsözcüğü veya geçişcümlesi girmeniz gerekecektir. Eğer, giridiğiniz bilgiler doğru ise, helvetica.fonts.de bilgisayarına erdal kullanıcısı ile bağlanmış olacaksınız. ssh komutunun gereksinimlerinize göre çeşitli seçenekleri vardır. Bunun için ssh'nın man sayfasına bakabilirsiniz.
Uzaktaki bir bilgisayarda ssh kullanarak komut çalıştırmak da mümkündür:
Komutun kullanımı uaktaki bilgisayara erişim ile öok benzeşmektedir. Tek fark, bilgisayara adından sonra çalıştırılacak komutun (Örneğimizde 'df -H') yazılmasıdır. Komutun çıktısı yerel bilgisayarda görüntülenecektir
Geçişsöcüğü kullanmak yerine genel/özel (public/private) anahtar çifti kullanılabilir. Bunun için öncelikle anahtarlarınızı yaratmanız gerekmektedir. ssh-keygen programı ile anahtarlarınızı yartmanız mümkündür:
Komutu çalıştırıldığında özel (private) anahtarı için dosya adı girmeniz gerekecektir. Genel anahtarın saklandığı dosya adını, özel anahtar dosya adına '.pub' eklenmesi ile oluşturulmaktadır. '-b 1024' anahtarda yer alan bit sayısıdır. Eğer, böyle bir değer belirtmezseniz benimsenmiş değer kullanılacaktır. '-t dsa' ile anahtar tipi belirlenmektedir. 1 sürüm numaralı protokol için 'rsa1', 'rsa' veya 'dsa' ise 2 sürüm nolu protokol için olan seçeneklerdir. Size tavsiyen SSH'nın 2 sürümlü protokulünü kullanmanızdır. Ancak, sisteminizde çok eski sunucular varsa, ki bunlar sadece 1 nolu protokolü destekliyorlardır, o zaman '-t rsa1' seçeneği ile bir anahtar çifti yaratmanız gerekecektir. ssh programını kullanırken 1 veya 2 sürüm nolu protokolün kullanılmasını sağlamanız mümkündür. Bunun için sırasıyla '-1' veya '-2' seçeneklerini kullanmanız gerekecektir.
Anahtarınızı kullanabilmek için genel (public) olanını bağlanacağınız bilgisayara yüklemeniz gerekecektir. Bunun için genel anahtarın içeriği $HOME/.ssh/authorized_keys veya $HOME/.ssh/authorized_keys2 dosyasına eklenmelidir. İki protokol için olan anahtarlarınızı karıştırmamaya dikkat etmelisiniz. authorized_keys 1 sürüm nolu SSH protokolü, authorized_keys2 ise 2 sürüm nolu SSH protokolü için kullanılamaktadır. Eğer, anahtarlarınızı düzgün bir şekilde yüklediyseniz, o bilgisayara bir sonraki bağlantınızda öncelikle geçişcümlesi girmeniz istenecektir. Yanlış giriş yapmanız durumunda, geçişsözcüğü girmeniz istenebilir. sshd'nin /etc/ssh/sshd_config yapılandırma dosyasında 'PasswordAuthentication no' değişikliğini yaparak o bilgisayara sadece anahtar kimliklendirilmesi kullanılarak giriş yapılmasını sağlayabilirsiniz.
Şu ana kadar herşey tamamdır. Başka bir bilgisayarda uzaktan komut çalıştırma ve oradan kendi bilgisayarımıza veya kendi bilgisayarımızdan uzaktaki bilgisayara güvenli bir şekilde dosya kopyalamanın yollarını öğrendik. Ancak, işleri otomatikleştirmek için geçişsözcüğü veya geçişcümlesi girmememiz gerekir. Yoksa, otomatikleştirmeyi unutun. Bir çözüm, herbir kabuk programı içine geçişsözcüğünü veya geçişcümlesini yazmak olabilir. Daha iyi bir yöntem ise, ssh-agent kullanmaktır. ssh-agent, arka planda çalışan ve özel anahtarları saklayarak sizin yerinize otomatik olarak kullanan bir araçtır. Programı aşağıdaki gibi çalıştırmak mümkündür:
Özel anhtarlarınızı eklemek için
komutları kullanılabilir. id_dsa DSA tipli özel anahtar, identity ise RSA1 tipli özel anahtardır. Bunlar, ssh-keygen programını kullanırken benimsenmiş değer olarak yaratılan dosya isimleridir. ssh-add anahtarları ssh-agent'a eklemeden önce geçişcümlenizin girilmesini isteyecektir. Eklenmiş anahtarlarların listesini aşağıdaki komutla alabilirsiniz:
Eğer, anahtarınızı yüklediğiniz bilgisayara tekrar bağlanırsanız, hiçbirşey girmeden bağlantı sağlanmış olur! ssh-agent kimliklendirme işlemini yerine getirmiş olacaktır.
ssh-agent'ı yukarıdaki gibi kullandığınızda, sadece çalıştırdığınız konsoldan kullanmanız mümkündür. Eğer, herhangi bir konsoldan kullanmak istiyorsanız, biraz daha fazla işlem yapmanız gerekecektir. ssh-agent'ı çalıştıran küçük bir kabuk programı yazdım:
Yukarıdaki kabuk programı, kullanıcının ev dizinini altında ssh ile ilgili dosyalarının bulunduğu dizin, ki genelde bu '.ssh/' dır, içindeki agent_info dosyasının varlığını denetlemektedir. Eğer, bu dosya varsa, kullanıcı dosyanın varlığı hakkında uyarılmakta ve ne yapılabileceği hakkında kısa bir mesaj görüntülenmektedir. Eğer, kullanıcı ssh-agent programını çalıştırmadıysa, agent_info dosyasını silinmesi ve kabuk programının tekrar çalıştırılması gerekmektedir. Kabuk programı ssh-agent'ı çalıştırıp, onun çıktısının ilk iki satırını agent_info dosyasına kaydetmektedir. Bu bilgi ssh araçları tarafından daha sonraları kullanılacaktır. En sonunda ise, dosyayı sadece kullanıcının okuyup yazablmesine yönelik dosya hakları chmod komutuyla değiştirilmektedir.
ssh-agent çalıştırdığınız andan itibaren anahtarlarınızı eklemeniz mümkündür. Ancak, daha öncesinde agent_info dosyasındaki bilgileri ssh araçlarının ulaşabilecek duruma getirmeniz gerekmektedir. Bunun için aşağıdaki komutlardan birini kullanabilirsiniz:
source ~/.ssh/agent_info veya . ~/.ssh/agent_info
Şimdi ssh-add ile özel anahtarlarınızı ekleyebilirsiniz. Aşağıdaki satırları .bashrc dosyasına ekleyerek, her yeni konsol açtığınızda agent_info bilgilerine ulaşmış olacaksınız:
UYARI: ssh-agent ve otomatik yükleme kabuk programını çalıştıracağınız bilgisayarın güvenliğini sağlamak zorundasınız. Yoksa, sizin hesabınıza ulaşabilen herkes, anahtarlarınız ile ulaştığınız tüm hesaplara ulaşabilecektir. Herşeyin bir fiyatı var tabii!
Sistem yönetcisinin bazı işlerini nasıl otomatikleştireceğimizi anlatmanın zamanı geldi artık. Programın sağlayacağı şey, belli sayıdaki komutu belli bilgisayarlarda çalıştırmak ve o bilgisayarlara veya o bilgisayarlardan yerel bilgisayara dosyalar kopyalamaktır. Bu da zaten sistem yöneticisinin sıkça yaptığı işlerdendir. Kabuk programının çıktısı aşağıdadır:
Kabuk programını ainstal.sh (automated installation) adı altında kayıt edelim ve herhangi bir parametre vermeden çalıştırmayı deneyelim. Aşağıdaki mesajı elde ederiz:
Eğer, komut çalıştrımak istemeyiyorsanız, commands_file parametresi yerine commands_empty.txt verebilirsiniz ve eğer, dosya aktarmak istemiyorsanız files_file parametresi yerine de files_empty.txt ismini verebilirsiniz.
Programı satır satır açıklamaya geçmeden önce bir örnek üzerinde duralım: Diyelim ki sisteminize ikinci bir DNS sunucu eklediğinizde, bilgisayarların /etc/resolv.conf dosyasına bilgisayarın IP numarasını eklemeniz gerekecektir. Kolaylık olsun diye tüm bilgisayarlarınızın aynı resolv.conf dosyasına sahip olduğunu varsayılım. Dolayısıyla, yapmamız gereken tek şey yeni bir resolv.conf dosyasını her bilgisayara kopyalamaktır.
İlk önce hangi bilgisayarlara kopyalama yapacağınızı bilmeniz gerekecektir. İlgili tüm bilgisayarları hosts.txt dosyasına yazalım. Bu dosyanın biçimi, her satıra bir bilgisayar adı veya IP numarası gelecek şekilde bir listeden oluşmaktadır. İşte bir örnek dosya:
Örnekten görüldüğü gibi tam bilgisayar adı verebildiğimiz gibi, sadece bilgisayar adı vermek, yani alan kısmı olmadan, mümkündür. Daha sonra hengi dosyaların aktarılacağını belirten bir dosyaya gereksinim olacaktır. İki olasılık vardır:
Yerel bilgisayarlardan hosts.txt dosyasında yer alan bilgisayarlara kopyalamak. Bu bizim örneğimize karşılık geliyor.
hosts.txt dosyasında yer alan bilgisayarlardan yerel bilgisayara kopyalamak. Bu yapılandırım dosyalarını yedeklemede kullanılan kabuk programının kullanıldığı duruma bir örnektir.
Aktracağımız dosyaları files_file.txt adında bir dosyaya yazalım. Dosyanın biçimi şu şekildedir: Her satır sadece bir dosyanın aktarımı bilgisini içermektedir. Bilgiler üç sütun halindedir ve bir boşluk veya tab karakteri ile ayrılmaktadır. l2r (local to remote) yerel bilgisayardan uzaktaki bilgisayara ve r2l (remote to local) uzaktaki bilgisayardan yerel bilgisayara olarak iki olası dosya aktarım yolu vardır. Aktarım yönünü belirten kelimeden sonra iki dosya adı gelmektedir. İlk gelen dosya aktarım yönüne göre diğeri üzerine kopyalanmaktadır. Uzaktaki bilgisayar için verilen dosya adı yoltanımı ile verilmelidir, yoksa kopyalama root kullanıcısının ev dizinine olacaktır. İşte bizim files_file.txt :
Görüldüğü gibi dosyanın başında açıklama (İngilizce olarak) yer almaktadır. Bu açıklamayı genellikle her dosyanın başına getiriyorum. Belgelendirme yapmak yerine böyle bir çözüm kullanıyorum. Bu basit ve güzel bir çözümdür. Örneğimizde, resolv.conf dosyasını uzaktaki bilgisayarların /etc dizine aynı isimde kopyalayacağız. Göstermek amacıyla, kopyalamadan sonra dosyanın kullanıcı ve erişim haklarını değiştiren komutlar ekledim. Çalıştırılacak komutlar ayrı bir dosyaya yazılmaktadır. Dosyanın biçimi her satır bir tek komut içerecek şekildedir. Komutların yer aldığı dosyaya commands_file.txt adını verelim:
Komutlar sırayla çalıştırlılmaktadır ve biri bitmeden diğer komuta geçilmemektedir.
Evet, programı çalıştırmak için gerekli olan herşeye sahibiz artık. Belirtilmesi gerek tek şey 'mode' seçeneğidir. Bu, dosya aktarımımı ardından komutlar mı çalıştırılsın, yoksa komutlar çalıştırıldıktan sonra dosyalar mı aktarılsın seçeneklerini belirtmeye ayaramaktadır. İlk önce dosyalar aktarılsın ve ardından komutlar çalıştırılsın seçeneği mode=1 durumuna karşılık gelmektedir.Önce komutlar çalıştırılsın ve ardından dosyalar aktarılsın seçeneği mode=2 durumuna karşılık gelmektedir. Şimdi programı gerekli tüm seçenekler ile birlikte çalıştırabiliriz:
Küçük bir öneri: files.txt dosya adınının başına files_ (files_resolvconf.txt) ve commands.txt'nin başına commands_ (commands_resolvconf.txt) yazmanızı öneririm.
Programın kendisini açıklama zamanı geldi artık. Program, kendisine verilen parametre sayısanı denetleyerek başlamaktadır ve eğer bu sayı 4 değil ise, kullanım mesajı ekranda görüntülenerek sona ermektedir. Eğer, parametre sayısı doğru ise, herbiri ilgili değişkenlere atanmaktadır. Ardından, '~/.ssh/agent_info' dosyasının varlığı denetlenmektedir ve eğer var ise, aktif hale getirilmektedir. Eğer, ssh-agent'ı kullanmıyorsanız, geçişsözcüklerini veya geçişcümlelerini elle girmeniz gerekecek ki, bu durumda otomatileştirmeden söz edemeyiz. Daha sonra, dosyalar (hosts, files ve commands) var olup olmadığı denetlenmektedir. files_empty.txt ve commands_empty.txt isimleri özel olarak denetlenmektedir. Eğer, bunlar verilmişse, dosyanın varlığının denetlenmesi gerekmemektedir. Programın bu kısmını bu yazının yazımı sırasında değiştirdim. Eski bu kısım aşağıdaki gibiydi:
Bu durumda files_empty.txt veya commands_empty.txt dosyaların var olması gerekir. Yaptığım bütün işlemleri tek bir dizinde olduğu için bu dosyaları bir kere yaratmak yeterli olmuştu ve benim işimi görmüştü.
Sonunda 'doit' fonksiyonu çalıştırılmaktadır. Herşey bu fonksiyon içerisinden yönetilmektedir. Fonksiyonda, '$hosts_file' dosyası içerisinde yer alan her bilgisayar için copy_files ve execute_commands fonksiyonları çalıştırılmaktaır. Bu işlem 'cat' ve 'while'den oluşan bir döngü içerisinde olmaktadır. Dolayısıyla hebir bilgisayar için iş yerine getirilmiş olur.
Şimdi copy_files fonksiyonuna bir gözatalım. Bu fonksiyonda ilk önce 'files_file' değişkeninin değerinin 'files_empty.txt' değerine eşit olup olmadığına bakılmaktadır. Eğer, eşit ise, hiç bir şey yapılmamaktadır. Eğer, değil ise, '$files_file' dosyasındaki her satır için 'direction' (yön), 'file1' ve 'file2' değişkenlerine değerleri atanmakta ve ardından aktarım yönüne ('direction') göre aktarım işlemi scp ile yapılmaktadır.
Son olarak execute_commands foksiyonunu inceleyelim. Foksiyon ilk önce 'commands_file' değişkeninin değerinin 'commands_empty.txt' olup olmadığını denetlemektedir. Eğer, eşit ise, hiçbir işlem yapılmamaktadır. Eğer, değil ise, '$commands_file' dosyasında yer alan her komut arka planda çalıştırmaktadır. Komutu çalıştırdıktan sonra wait komutu '$!' parametresi ile çalıştırılmaktadır. wait programını bu şekilde çalıştırmakla her komutu ardışık olarak ve birinin diğerinden sonra gelecek şekilde çalıştırmaktadır. '$!' nın değeri en son arka planda çalıştırılan programın işlem numarasına eşit olmaktadır.
İşte bu kadar. Kolay, öyle değil mi?
Yukarıdaki programın daha gelişmiş bir kullanım şekli aşağıdaki programda uer almaktadır. Buradaki amaç, bilgisayarlarınızın yapılandırım dosyalarının yedeğini almaktır. Bunun için ainstall.sh programını kullanan basit bir kabuk programı yazdım:
servers adında bir dizine sahip olmanız gerekmektedir. Bu dizin içinde files_getbackup.txt ve ll_servers.txt adında iki dosya olmak zorundadır. 'files_getbackup.txt' dosyasının içeriği aşağıdaki gibidir:
'll_servers.txt' dosyasında yedeği alınacak bilgisayarların adları veya IP numaraları yer almaktadır. 'll_servers.txt' dosyasında yer alan her bilgisayar adı veya IP numarası için aynı isimde 'servers' dizini altında bir dizin olması gerekmektedir. Bu dizinlerde /root/backup.tgz arşivini oluşturmaya yarayan 'commands_make_backups.txt' dosyası ve yedeklerin saklanacağı 'backups' dizini olmak zorundadır. Eğer, 'll_servers.txt' dosyası aiağıdaki gibi ise:
'$servers' dizin yapısı aşağıdaki gibi olmalıdır:
'commands_make_backups.txt' dosyasına birkaç örnek aşağıda verilmiştir:
Yukarıdaki dosyada samba, atalk ve isim sunucusu dosyalarının yedeğini alan komut yer almaktadır.
Yukarıdaki dosyada apache sunucusunun yedeğini alan komut yer almaktadır.
Yukarıdaki dosyada squid ve ikincil isim sunucularının yedeğini alan komut yer almaktadır.
Yukarıdaki programı kullanarak ve gereksinimleriniz doğrultusunda 'commands_make_backup.txt' komutları oluşturarak sunucularınızın yedeklerini alabilirsiniz.
ainstall.sh programı sistem yöneticisinin işlerini otomatikleştirmektedir. Program, ssh araçlarının basit kullanımına dayanmaktadır. Programın yararını, fazla sayıda sistemi yönetmekte olduğunuz zaman daha iyi göreceksiniz.
SSH, The Secure Shell: The Definitive Guide, Daniel J. Barrett ve Richard Silverman tarafından.
Tünel içerisinden, Georges Tarbouriech tarafından.
Kabuk programlama,Katja ve Guido Socher tarafından.
2002-12-24, generated by lfparser version 2.27