Linux Notlarım
- Linux dizin yapısı
- rsync İle Dizinler Arasında Senkronizasyon
- Sabit ve Sembolik Bağlantılar
- stdin, stdout, stderr
- Eğer Hatayı Baskılamak İstersek
- log ve error Fonksiyonları
- Bir Günlük Kaydının İçeriği
- echo $? ile sonuç kodu gösterimi
- Grup İşlemleri
- grup yaratmak
- Kullanıcı Ekleme (userAdd mi, addUser mı?)
- Bir Kullanıcıyı SUDOERs Grubuna Eklemek
- Kullanıcıları Listelemek
- Konsolda Kullanıcı Değiştirmek
- groupadd, chmod, chown, chgrp
- chroot
- apt Komutları
- apt ile paketi sadece indirmek (kurmadan)
- systemd
- history İşlemleri
- Linux, kernel versiyonunu öğrenmek
- hostnamectl
- /etc/os-release
- CPU Bilgileri
- lshw
- inotify-tools İle Dizin ve Dosya İzleme
- Bir Dosyayı İzlenen Dizine ve Dışına Taşımak
- touch & echo İle Bir Dosya Oluşturmak
- Varolan Dosyanın İçeriğini Değiştirmek
- Dizini Listelediğimizde
- Varolan Dosyayı Sildiğimizde
- Yeni Dizin Oluşturduğumuzda
--parents
Anahtarıyla Dizinler Oluşturduğumuzda- Yerel DEB (repo) Havuzu Oluşturma
- 1. apt-mirror Yöntemiyle
- Apache İle Paketleri Sunmak
- 2. Paket Havuzu Yöntemiyle
- Flat Repository Format *
- apache2 Docker sürümünü kuralım.
- Hata giderme: Packages with multiple instances but no — multiversion specified
- Debian Paketi Hazırlamak
- Çalıştırılabilir Programı Hazırlamak
- Paketi Hazırlamak
- Kullanım Kılavuzu
- DEBIAN/control Dosyasını Hazırlayalım
- Lisans İçin copyright Dosyası Oluşturma
- Debian Paketini Yapılandıralım
- Debian Paketi ve Bağımlılıklarını İndirmek
- Depends (Bağımlılıklar)
- Recommends (Öneriler)
- Suggests
- Enhances
- Pre-Depends
- Depends ve Pre-Depends Farkı
- Debian Paketindeki Bağımlılık İlişkileri
- Ağ Arayüzlerinin Donanım Durumları
- Ağ Arayüzlerinin Ip Adresleri
Linux Dizin Yapısı
- /bin: Bu, temel komutlar için alet kutunuzdur. Mesela
ls
,cat
veyacp
burada bulunur. "Herkesin ihtiyacı olan temel araçlar çekmecesi" gibi düşün. - /sbin:
/bin
’in kardeşi ama sistemle ilgili araçlar için ayrılmıştır.reboot
veyaifconfig
gibi komutlar burada yaşar. Daha çok yönetici kitlesine hitap eder. - /usr/bin:
/bin
’den biraz daha süslü. Kullanıcı tarafından yüklenen veya o kadar kritik olmayan programlar burada. Örneğin,vim
veyagit
. - /etc: Kütüphaneci gibi. Kullanıcı bilgileri için
/etc/passwd
veya DNS için/etc/hosts
gibi ayar dosyalarını burada bulursun. Sistem ayarlarının merkezi burasıdır. - /var: Gazeteci diyebiliriz. Her şeyi kaydeder, yani günlükler burada tutulur. Örneğin,
var/log/syslog
. - /tmp: Dağınık masa. Geçici dosyalar burada durur ama yeniden başlatıldığında temizlenir.
- /home: Kendi kişisel alanın. Her kullanıcının dosyalarını saklaması için bir klasörü vardır. Örneğin,
/home/kullaniciadi
. - /root: Root kullanıcısı için VIP alan.
/home
gibi ama sadece yöneticiye özel. - /proc: Bir tür casus dizin. Gerçek dosyalar değil, çekirdek verilerine arayüz sağlar. Örneğin, işlemci bilgisi için
/proc/cpuinfo
. - /dev: Atölye gibi. Sistemdeki tüm cihazlar (diskler, USB’ler vs.) için bir dosya vardır. Örneğin,
/dev/sda
. - /mnt ve /media: Park alanları.
/mnt
elle bağlamak için,/media
ise otomatik olarak USB gibi cihazları bağlamak için kullanılır. - /opt: Üçüncü taraf yazılımlar için otel. Paket yöneticisi dışında yüklenen şeyler burada tutulur.
- /lib: Programların çalışmasına yardımcı olan kütüphaneler burada.
.so
dosyaları gibi bağımlılıklar buraya kaydedilir. 32-bit kütüphaneler (bazı sistemlerde kullanılmaz). Paket yöneticisi tarafından kurulan uygulamaların kütüphaneleri sistem seviyesinde kullanılan ve paket yöneticisi tarafından yönetilen şu dizinlere gider: /lib, /usr/lib, veya /usr/lib/x86_64-linux-gnu. - /lib64: 64-bit kütüphaneler.
- /usr/local: Kendi “yerel” alanın diyebiliriz; yani, sistemde yapılan özelleştirmeler buraya gelir. Dağıtım paket yöneticilerinden bağımsız olarak yüklenen yazılımlar burada bulunur.
Örneğin, kaynak koddan derleyip yüklediğin bir program/usr/bin
yerine/usr/local/bin
gibi bir yere kurulur. Böylece, sistemin varsayılan dosyalarına karışmadan çalışır. - /usr/local/bin: Kendi yüklediğin kullanıcı programları buraya gelir.
Örnek: Kaynaktan derlediğin bir uygulama (make install
) genelde çalıştırılabilir dosyasını buraya atar.
Örneğin, bir Python betiği buraya eklenebilir ki herkes bu betiği komut olarak çalıştırabilsin. - /usr/local/sbin: Yönetici yetkisi gerektiren özelleştirilmiş araçlar burada durur. Root kullanıcısı için yüklenmiş sistem programları buraya yerleştirilir.
- /usr/local/lib: Kaynaktan yüklenen veya özelleştirilmiş yazılımların bağımlılık dosyaları buraya gelir. Kütüphaneler (örneğin,
.so
dosyaları) burada saklanır. - /usr/local/include: Yazılım geliştirme sırasında kullanılan başlık dosyaları (header files) burada bulunur.
Örnek: C/C++ projelerinde kullanılan.h
dosyaları. - /usr/local/etc: Kendi yüklediğin yazılımların ayar dosyaları buraya gelir.
Örnek: Elle kurulan bir uygulamanın yapılandırması/usr/local/etc/app.conf
gibi bir dosyada tutulabilir. - /usr/local/share: Genel veriler veya paylaşılan dosyalar burada saklanır.
Örnek: Dil dosyaları, ikonlar, yardım belgeleri, dokümantasyon dosyaları. - /usr/local/man: Elle yüklediğin yazılımların kılavuz (man) dosyaları buraya gelir.
Örnek:man
komutu ile çağırabileceğin belgeler,/usr/local/man
içinde bulunur. - /usr/local/src: Kaynak kodlar burada saklanır.
Örnek: Bir yazılımın kaynak kodunu indirip buraya koyabilirsin ve burada derleme yapabilirsin. - /usr/local/games: Kullanıcı tarafından yüklenen oyunlar buraya gelir.
- /usr/local/var: Uygulamaların oluşturduğu değişken/veri dosyaları burada tutulur.
Örnek: Bir manuel kurulan veritabanı sunucusunun kendi veritabanı dosyaları.
rsync İle Dizinler Arasında Senkronizasyon
Ref: *
Kaynak dizin ile hedef dizin arasında dosyaların senkronizasyonunu sağlar.
-r
: recursive (alt dizinlerin içerdiği dosyaları da senkronize eder)-v
: verbose (transfer edilen dosyaları ve eşleştirme özetini görüntüler)-n
: dry-run (dosya geçişini sağlamaz ancak gerçekleşmiş gibi özetler)-a
: arşiv kipi-z
: Veri taşınırken sıkıştırılarak aktarılır
Dizin adını takip eden bölü işaretinin hikmeti:
# dir2'nin sonundaki bölü işareti, dir2'nin içeriğini gönderir
# aksi halde dir1 dizinini kendisiyle birlikte kopyalar$ rsync -anv dir1/ dir2
Ayrıca uzak bilgisayarlar arasında da eşleştirmeyi yapar:
$ rsync -a ~/dir1 kullaniciAdi@uzakMakine:hedef_dizin
-P
Anahtarıyla --partial
ve --progress
anahtarlarının özelliklerini birlikte kullanarak eşleştirmeyi yapar.
$ rsync -a --delete kaynak hedef$ rsync -a --exclude=hariç_tutulacaklar_deseni kaynak hedef$ rsync -a --exclude=HARİÇ*.py --include=DAHİL*.c source destination$ rsync -a --delete --backup --backup-dir=/path/to/backups /path/to/source destination
Sabit ve Sembolik Bağlantılar
Hard Links (Sabit bağlantılar): Sabit bir bağlantıyı, mevcut bir dosya için ek bir ad olarak düşünebilirsiniz. Sabit bağlantılar, iki veya daha fazla dosya adını aynı inode ile ilişkilendirir. Tek bir dosya için bir veya daha fazla sabit bağlantı oluşturabilirsiniz. Farklı bir dosya sistemi veya bölümdeki dizinler ve dosyalar için sabit bağlantılar oluşturulamaz.
Soft Links “symbolic/symlink” (Yumuşak bağlantılar): Windows’taki kısayol gibi bir şeydir. Bir dosya veya dizine dolaylı bir göstericidir. Sabit bağlantıdan farklı olarak, sembolik bir bağlantı, farklı bir dosya sistemi veya bölümdeki bir dosyaya veya dizine işaret edebilir.
$ ln -s tam_fiziki_dosya_yolu sembolik_bağlantı_yolu
Sembolik bağın hedef yolunun üzerine yazmak için -f
(--force
) argümanı kullanılır.
Windows bilgisayarınızdaki kaynak kodlarınızın olduğu dizini WSL içinde Visual Studio Code ile geliştirme yapmak için açarsanız ciddi bir yavaşlıkla karşılaşacaksınız. Bu dizini WSL içinde sembolik bağlantı ile ev dizininize bağlayabilirsiniz.
$ ln -s /mnt/c/projeler/kod_repo ~/kod_dizini
Bağlantıları kaldırmak için bağlantının adını rm
veya unlink
ile kaldırabiliriz.
stdin, stdout, stderr
Her işlemin çalışabileceği üç varsayılan akış vardır. Bunlar stdin
, stdout
ve stderr
’dir.
stdin
akışı, sürecinize gelen girdiyi işliyor. Örneğin düğme basışları veya >
veya |
operatörüyle yönlendirilen çıktıları işler.
stdout
(standart çıktı) akışı, uygulamanızın çıktısı içindir.
stderr
hata mesajları içindir.
Aşağıda ayrıntılı göreceğiz ancak bir değinelim yönlendirilmiş çıktıya.
Bir uygulamanın gerçek sonucundan ayrı olarak hata ve tanılama bilgileriyle çalışmak için yönlendirme (
>
) ve boru (|
) operatörlerini kullanmamıza olanak tanır.>
Bir komutun çıktısını bir dosyaya yönlendirmemize izin verirken,2>
isestderr
çıktısını bir dosyaya yeniden yönlendirmemize izin verir.
// std.js // console.log("log ile stdout çıktısı")
// console.error("error ile stderr çıktısı")process.stdout.write("process.stdout.write log ile stdout çıktısı")
process.stderr.write("process.stderr.write error ile stderr çıktısı")
$ echo "yoksa oluştur ve yaz, varsa üstüne yaz" > cikti.txt
$ cat cikti.txt
yoksa oluştur ve yaz, varsa üstüne yaz$ echo "yoksa oluştur ve yaz, varsa sonuna ekle" >> cikti.txt
$ cat cikti.txt
Yönlendirme operatörleri olan >
ile standart çıktı olan yere yani monitöre değil de cikti.txt
adında bir dosya yoksa yaratarak, varsa üstüne yazıyor metni.
Ancak >>
operatörüyle bu kez dosyanın üstüne yazmıyor sonuna ekliyor.
Çıktının değil de girdinin yönünü vermek istiyorsak bu kez <
karakterini kullanacağız. Aşağıdaki örnekte -s (subject) anahtarı konu bilgisini, sonraki argüman gidecek eposta adresini (To) ve <
operatörüyle NewsFlash dosyası iletiye dosya eki olarak eklenir. Burada stdin değeri NewsFlash içeriği olarak mail uygulamasında değerlendirilir.
Linux üstünde her şey bir dosyayla ilişkilidir. Bir programın giriş/input, çıkış/output ve hata çıktıları(varsayılan olarak standart çıktıya yönlüdür) da dosyalarla ilişkilendirilir. Standart girişleri yaptığımız klavye de bir dosya ile ilişkiliyken standart çıktıyı gördüğümüz monitör de bir dosyayla ilişkilidir.
Bir programın standart çıktısı FD1 ile tanımlı file descriptor 1
dosyasına yani monitörün dosya tanımlayıcısına yönelmiştir.
$ ls olanDizin olmayanDizin > out.txt 2> err.txt$ ls olanDizin olmayanDizin > outVeErr.txt 2>&1
>
başarılı (stdOut) çıktılarımızı bir dosyaya yazmak için kullanıyoruz.
2>
hata (stdErr) çıktılarımızı bir dosyaya yazmak için kullanıyoruz.
2>&1
hata çıktılarımızı başarılı çıktıların dosyasına yazmak için kullanıyoruz.
Biraz Tafsilat…
Hatalı çıktıyla birlikte başarılı çıktıyı verecek şekilde bir komut çalıştıralım:
Önce hata satırını yazdı, sonra başarılı sonuçları. Bir nevi Javascript dilinde kullanılan error first
deseni.
- Standart çıktıyı bir dosyaya yazdıralım
- Hata çıktısını başka bir dosyaya yazdıralım
- Her iki çıktıyı (hem standart çıktıyı hem hata çıktısını) aynı dosyaya yazdıralım. Burada dikkat edeceğimiz nokta şudur:
$ ls olanDizin olmayan_dizin > iki_cikti_tek_dosyada 2>&1
2
ile hata çıktılarını >&
ile 1
çıktılarını yönlendirdiğimiz yere, yani iki_cikti_tek_dosyada
isimli yere yönlendiriyoruz
Son işlemin başarımını veya oluşan hata kodunu görmek için $?
komutunu kullanırız
ls komutu başarıyla sonuçlandığı için 0 sonucunu görürken ls -2
komutu hatalı olduğu için 1 kodunu donuyor.
#!/bin/bash# hata olsun diye ls çektik ve hata mesajını boşluğa gönderdik
# böylece hata sonucu ekran görüntülenmeyecek ve yeni satıra geçecek
ls olmayanDizin 2> /dev/nullif [ $? -eq 0 ]
then
echo "Olmayan dizin/dosya listelenemez"
else
echo "Dosya/dizin varmış" >&2
fi
Eğer hatayı baskılamak istersek
$ cp ./src/*/*.h ./aaa 2>/dev/null || :
log ve error Fonksiyonları
Node.js içinde console.log()
ve console.error()
fonksiyonlarını ele alalım.
Bu ikisi aynı görünse de, aslında sistem tarafından farklı şekilde ele alınırlar. Node.js belgelerinin konsol bölümünü kontrol ederseniz, console.error
stderr
kullanırken console.log
’un stdout
’a yazdırdığını görürsünüz.
console.error([data][, …args])
, Prints tostderr
with newline.
console.log([data][, …args])
, Prints tostdout
with newline.
console.info([data][, …args])
, Theconsole.info()
function is an alias forconsole.log()
.
Bir Günlük Kaydının İçeriği
Buraya kadar uygulamanın 3 akışını da inceledik. Şimdi bir çıktı (günlük, log) nasıl olur onu inceleyelim.
- Timestamp — Günlük kaydına konu işin ne zaman olduğunu bilmek için
- Computer/Server Name — Günlükler farklı makineler/uygulamalardan toplanıyorsa yani dağıtılmış bir sistemde çalıştırmanız durumunda günlük kaydının kaynağını bilmek için
- Process ID — pm2 gibi bir şey kullanarak birden çok düğüm işlemi (process) çalıştırmanız durumunda hangi işlemin bu kaydı oluşturduğunu bilmek için (Örn. bir uygulama 4 thread koşturup veya aynı makinede 4 farklı uygulama günlük kaydı oluşturuyorsa)
- Message — Günlük kaydına sebep olan durumun mesaj olarak içeriği
- Stack Trace —bir hata kaydetmemiz durumunda
- Belki bazı ek değişkenler/bilgiler
debug
Aşağıdaki örnekte etiket isimlerini debug
fonksiyonuna parametre olarak girerek birer nesne alıyoruz.
var debug = require('debug')
// etiket adı: 'modulA:fonkB:log'
const log = debug('modulA:fonkB:log')
Bu nesnelerin .log([…])
metotlarını ya stdOut
veya stdErr
akışına yönlendirmek için console.log
veya console.error
metotlarına bağlıyoruz.
const err = debug('modulA:fonkB:error')
err.log = console.error.bind(console);
Artık günlük kaydını attığımızda stdOut
ve stdErr
akışlarını yönlendirdiğimiz (>
) dosyalarda kayıtlarımızı göreceğiz.
Küresel veya yerel ölçekte bu nesneleri oluşturabiliriz.
Ortam değişkenlerinde günlük seviyesini DEBUG
anahtarı ile belirleyebiliriz.
Nesnelerin hangi seviyede görüntülenmelerini istiyorsak ortam değişkenlerinde DEBUG_DEPTH
anahtarı ile ayarlayabiliriz
pino
// test_pino-debug.js
// DEBUG=* node test_pino-debug.jsconst pino = require('pino');
const logger = pino({
prettyPrint: true,
level: process.env.LOG_LEVEL || 'info'
}, process.stderr);logger.error('PINO: ERROR seviyesi');
logger.info('PINO: INFO seviyesi');
logger.debug('PINO: DEBUG seviyesi');
LOG_LEVEL ortam değişkenlerinde verilerek çeşitli seviyede çıktıları baskılayabiliriz.
Temel bilgileri bizim için çeker (Bilgisayar adı, İşlem ID, Tarih, Log seviyesi vs.).
const pino = require('pino');
const logger = pino({ level: process.env.LOG_LEVEL || 'info' });
// const logger = pino({ level: process.env.LOG_LEVEL || 'debug' });logger.debug('debug seviyesinde görünür olacak');
logger.info('info Seviyesi en alt düzeydir. Üst seviyelerde görünür');
var obje = { ozellik: "değer", sayi: 12, dizi: [1, 2, 3] }
logger.info('String: %s, Object: %o', obje, obje);
Ek olarak günlük kaydının debug paketi gibi bir etiketle görüntülenmesini istersek .child({..})
özelliğini kullanabiliriz.
// test_pino.js
// $ node test_pino.js
// $ LOG_LEVEL=info node test_pino.jsconst pino = require('pino');
const logger = pino({
prettyPrint: true,
level: process.env.LOG_LEVEL || 'info'
}, process.stderr);var obje = {
a: 1, b: {
b: 1,
c: {
c: 2
}
}
}
logger.debug('DEBUG seviyesi. String: %s, Object: %o', obje, obje);function deneme(){
const child = logger.child({ etiket_adi: 'root:deneme' })
child.info('İç günlükleyici INFO seviyesi');
}deneme()
logger.error('ERROR seviyesi');
pino-debug
debug
paketi bir etiket ile günlük kaydı oluşturacak fonksiyonlar yaratır ve ekranda renklendirir.
debug
paketi sayesinde çeşitli seviyelerin gösterilmesini DEBUG=express:*
gibi bir ortam değişkeniyle etiketi express:
ile başlayan günlük kayıtlarını görüntüler. Aşağıdaki örnek süzgeçle sadece üzerinde çalıştığınız modülün (modulA
) ilgili kısmındaki (fonkC
) tüm günlükleri görebiliyorsunuz.
pino-debug
ise pino
paketinde child
metoduyla fazladan girdiğiniz bilgiyi günlük kaydına ekler gibi debug
paketinin etiketlerini de {ns: etiket_adı}
olacak şekilde uygular. Bunu aşağıdaki gibi yapar ve fazladan debug
paketinde bir etiketi console.[error|log|info|trace]
fonksiyonlarına bağlama işini çok daha kolay yapar.
const logger = require('pino')()
logger.info('hi!')// Çıktısı:{"level":30,"time":1531171074631,"msg":"hi!","pid":657,"hostname":"makineAdı"}
Yukarıda normal çıktısını gördüğümüz yapıya fazladan (extra) bilgi ekleyeceğiz ({ns: etiket_adı}
):
const child = logger.child({ ns: 'etiket' })
child.info('hey!')// Çıktısı:{"level":30,"time":1531171082399,"msg":"hey!","pid":657,"hostname":"makineAdı","ns":"etiket"}
Ayrıca hangi etiketli günlüklerin görüntülenmesini ayarlar içinde auto
özelliğini true
yapınca kodunuzdaki gibi, false
yapınca ortam değişkenlerinde DEBUG
anahtarına verilen değere göre yapar:
Hangi parçaları bir araya getirerek nasıl bir sonucu oluşturduğunu aşağıdaki gibi görelim ve tafsilatlı anlatımına geçelim:
Biraz ayrıntı…
// test_pino-debug.js
// DEBUG=* node test_pino-debug.jsconst pino = require('pino');
const logger = pino({
prettyPrint: true,
level: process.env.LOG_LEVEL || 'info'
}, process.stderr);logger.error('PINO: ERROR seviyesi');
logger.info('PINO: INFO seviyesi');
logger.debug('PINO: DEBUG seviyesi');
// ek olarak aşağıdaki kod geliyor
//...var info = require('debug')('root:info');
info("DEBUG: root:INFO etiketi")
var cocukInfo = require('debug')('root:fn:info');
const fn = ()=> cocukInfo("DEBUG: root:fn:INFO etiketi")
fn()
Şimdi pino
’nun child özelliği ile kayıtlara etiketmiş gibi bilgi ekleyelim:
const pino = require('pino');
const logger = pino({
prettyPrint: true,
level: process.env.LOG_LEVEL || 'info'
}, process.stderr);logger.error('PINO: ERROR seviyesi');
logger.info('PINO: INFO seviyesi');
logger.debug('PINO: DEBUG seviyesi');// debug Paketi ile kayıt oluşturmak
var info = require('debug')('root:info');
info("DEBUG: root:INFO etiketi")
var cocukInfo = require('debug')('root:fn:info');
const fn = () => cocukInfo("DEBUG: root:fn:INFO etiketi")
fn();// child İle ek özellik ekleyelim
(function () {
console.log('')
const pinoCocukInfo = logger.child({ etiket: 'anonim fn:pino cocuk:info' })
pinoCocukInfo.info("root:anonimFn:INFO seviyesi")
})()
Şimdi pino-debug
ile debug
paketindeki etiket bilgilerini pino
’nun child ile ek özelliği olarak gösterelim.
Referans:
Grup İşlemleri
Grup Yaratmak (groupadd -g <id değeri> <adı>
)
$ sudo groupadd yazilimcilar
Grupları /etc/group
dosyasında aşağıdaki formda tutuyor.
GrupAdı : x (debian için şifre gizler, freebsd için “şifre yok”) : grupId : gruba üye kullanıcılar (ali,veli, mecnun gibi)
$ grep yazilimcilar /etc/group
yazilimcilar:x:1003:
Sıradaki grup ID değeri 1003 olduğu için otomatik yazilimcilar:x:1003
değeri atanmış.
$ cat /etc/group
root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
adm:x:4:syslog,ubuntu
tty:x:5:
disk:x:6:
mail:x:8:
irc:x:39:
users:x:100:
systemd-journal:x:101:
systemd-timesync:x:102:
systemd-network:x:103:
systemd-resolve:x:104:
ubuntu:x:1001:
rabbitmq:x:118:
mongodb:x:119:mongodb
Not: Grupların hepsini değil, bir kısmını seçtim.
Dikkat!
Mongo, RabbitMQ gibi uygulamalar kendi gruplarını tanımlamış ve hatta mogoDb kendine bir kullanıcı oluşturmuş mongodb adında ve bu gruba eklemiş.Dikkat!
Hattaadm
veusers
gruplarını işletim sistemi oluşturmuş ve içine syslog ve ubuntu kullanıcılarını eklemiş. Bu grupların ID değerleri ne kadar küçük ;)
Kullanıcı Ekleme (userAdd mi, addUser mı?)
Kullanıcının olup olmadığını kontrol etmek için id
komutunu -u
parametresiyle kullanabiliriz:
useradd
, sistemle birlikte derlenen yerel ikili dosyadır (çalıştırılabilir dosya-exe gibi yani-). Ancak adduser
, arka planda useradd
binary uygulamasını (ikilisini dediğimizde binary -derlenmiş uygulama- düşünebilirsiniz) kullanan bir perl
betiğidir. adduser
, arka uç kullanıcı eklentisinden daha kullanıcı dostu ve etkileşimlidir (yani şifre, telefon numarası, bina veya oda numarası gibi ek bilgileri (gecos
) sorabilir). Eğer bir betik içinde (shell script
gibi) kullanacaksanız bu etkileşim işinizi zorlaştırabilir. Örneğin şifre ve diğer bilgileri girmemek için ek parametreler vermeniz gerekir (adduser --disabled-password --gecos "" cem
). Sağlanan özelliklerde hiçbir fark yoktur.
adduser
/deluser
bir perl betiği olduğu için tüm dağıtımlarda bulunmayabilir, (ör. SuSE’de) bu yüzden user[add|del]
gibi ikili komutları kullanmak isteyebilirsiniz. ***
Şimdi yazılımcılar grubuna bir kullanıcı ekleyelim. Ama kullanıcının daha önceden yaratılmış olma ihtimaline karşılık kullanıcıyı silelim (varsa ev dizinini de silerek userdel -r
) sonra ev diziniyle (--create-home
)birlikte kullanıcı yaratalım (useradd -m
) sonra kullanıcıya şifre atayalım (passwd
) ve en sonunda kullanıcının kullanıcı gruplarını güncelleyelim (birden fazla grup işlemi için -G
anahtarı, tek grup işlemi için -g
anahtarını kullanırız: usermod -G
) :
$ sudo userdel -r cemt
$ sudo useradd -m cemt
$ sudo passwd cemt
$ sudo usermod -G users,yazilimcilar cemt
Bir Kullanıcıyı SUDOERs Grubuna Eklemek
Bir kullanıcı yarattınız ama sudo ile kullanamıyorsunuz çünkü kullanıcı sudo grubuna üye değil.
Eğer kullanıcıyı sudo grubuna ekleyerek en üst seviyede (root seviyesinde) yetkilendirmeyi de eklemek istersek :
$ usermod -aG sudo cemt-a : append
-G : group# Kullanıcının üye olduğu grupları listelemek için
$ groups cemt
Kullanıcıya Kabuk Atama
/etc/shells
dosyasında sistemki kabukları görüntüleyebiliriz
/bin/false ve /sbin/nologin Farkı
Bir kullanıcı yaratırken ona kabuk ataması da yapabiliriz. Örneğin kullanıcı giriş yaptığında bash, sh, zsh gibi farklı kabuklar kullanacak şekilde sisteme girişi ayarlanabilir.
Aynı şekilde kullanıcı eğer sisteme giriş yapamaz şekilde ayarlanmak istenirse /sbin/nologin
veya /bin/false
kabuk olarak ayarlanabilir.
/sbin/nologin
kabuk olarak ayarlandığında, o kabuğa sahip kullanıcı oturum açarsa, ‘Bu hesap şu anda kullanılamıyor’ diyen kibar bir mesaj alırlar. Bu mesaj /etc/nologin
dosyası ile değiştirilebilir (ubuntu /etc/nologin
içindeki yazıyı okudu).
This account is currently not available.
Bu kullanıcı için geçerli bir kabuk ayarlanmadığından,
su -l <hesapadi>
veyalogin <hesapadi>
ile oturum açmaya çalıştığınız hesap şu anda kullanılamıyor demektir.
/bin/false
, ikili dosyası ise false
döndürerek hemen çıkan bir ikili dosyadır, bu nedenle, shell
olarak false
olan biri oturum açtığında, false
çıktığında hemen oturumu kapatılır.
/bin/true
olarak kabuğu ayarlamak, birinin oturum açmasına izin vermemekle aynı etkiye sahiptir, ancak false
, kişinin kabuğunun olmadığı kavramını iletmek için çok daha iyi olduğundan, true
yerine bir kural olarak kullanılır.
# docker exec --user cem cubuntu bash
komutu çalıştırıldığında docker bir kullanıcı girişi yapmaz!
Sadece bash komutunu cem kullanıcısıyla çalıştırır.
Kullanıcı girişini: login
, ssh
, mgetty
, gdm
komutlarıyla yapabiliriz.
Bu yüzden login ile kullanıcı girişi yaparak /bin/false
ile hata üretip giriş yapamadığımızı root kullanıcısına düştüğümüzü yukarıdaki ekran çıktısında görebiliriz.
Kullanıcıyı oluştururken hem ev dizinini hem gruplarını verelim
$ sudo useradd -m -G users,yazilimcilar kodcu
Kullanıcı yaratıldığında /etc/passwd ve /etc/group içinde izlerini göreceğiz:
$ grep kodcu /etc/passwd
$ grep kodcu /etc/group
$ su <kullanıcı_adı>
Komutuyla kullanıcı girişi yapalım ve ev dizinine $ cd ~
komutuyla gidelim. Bulunduğumuz klasörü yazdırmak için $ pwd
komutunu kullanalım. Kullanıcımızın kayıtlı olduğu grupları $ groups
komutuyla listeleyelim.
vagrant@ubuntu-xenial:/home$ su kodcu
Password:
kodcu@ubuntu-xenial:/home$kodcu@ubuntu-xenial:/home$ cd ~
kodcu@ubuntu-xenial:~$ pwd
/home/kodcukodcu@ubuntu-xenial:~$ groups
kodcu users yazilimcilar
Bir kullanıcının gruplarını ad veya ID değerleriyle listelemek için $ id -G
komutunu kullanalım.
Referanslar
Konsolda Kullanıcı Değiştirmek
Aktif kullanıcı bilgileri için:
$ echo $HOME$ pwd$ echo $USER
ubuntu$ who
ubuntu tty1 2021-07-29 08:05
ubuntu pts/0 2021-08-11 05:57 (192.168.13.254)
ubuntu pts/2 2021-08-11 06:07 (192.168.13.254)
ubuntu pts/3 2021-08-11 06:48 (10.20.203.140)$ whoami
ubuntu$ who am i
ubuntu pts/3 2021-08-11 06:48 (10.20.203.140)$ w
06:53:25 up 109 days, 17:16, 4 users, load average: 0.08, 1.75, 2.62
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
ubuntu tty1 29Jul21 12days 0.40s 0.20s -bash
ubuntu pts/0 192.168.13.254 05:57 3:51 1.77s 1.77s -bash
ubuntu pts/2 192.168.13.254 06:07 7:29 1.07s 1.07s -bash
ubuntu pts/3 10.20.203.140 06:48 0.00s 0.41s 0.14s wŞu anki kullanıcının bilgilerini döner id:
$ id
uid=1000(ubuntu) gid=1000(ubuntu) groups=1000(ubuntu),0(root),4(adm),20(dialout),24(cdrom),25(floppy),27(sudo),29(audio),30(dip),44(video),46(plugdev),109(netdev),110(lxd)$ id cem$ groups cem
sudo
komutu, root
kullanıcısının kerelik veya sınırlı süreli erişimle komutu çalıştırır. Genellikle, bir yönetici komutunu hızlı bir şekilde çalıştırmak ve ardından kullanıcı hesabının normal izinlerine dönmek için sudo
komutu kullanılır.
Varsayılan olarak, bazı Linux sürümleri (Ubuntu gibi)
root
hesabı devre dışı bırakılır. Bu,root
kullanıcısına atanmış bir parola olmadığı anlamına gelir. Ancaksu -
komutu çalıştırarak ve şu anda oturum açmış olan kullanıcının şifresini girerek root’a geçebilirsiniz.
su
daha eski ancak daha özellikli bir komuttur. su
komutu, geçerli kullanıcıdan başka bir kullanıcıya geçmenizi sağlar. root
Kullanıcısından farklı bir kullanıcı olarak komut çalıştırmanız gerekiyorsa, kullanıcı hesabını belirtmek için --login [kullanıcı adı]
(veya -l
) seçeneğini kullanın. Ek olarak, su, anında farklı bir kabuk yorumlayıcısına geçmek için de kullanılabilir.
$ su -l <geçiş yapılmak istenen kullanıcı adı>
$ login <kullanıcı adı>
--shell (-s) Farklı Kabukta Çalıştırma
--login (-l) Farklı Kullanıcıda Çalıştırma
––preserve–environment (-p) Ortam Değişkenlerini Korumak
root@f4216b28bfe7:/# su -l postgres
postgres@f4216b28bfe7:~$
Process Yok Etmek (killing processes)
Hem top
hem de ps
, bir işlemin hangi kullanıcı altında çalıştığını gösterir. top
durumunda, ikinci sütun kullanıcı adını içerir. ps aux
ile ilk sütun kullanıcı adını içerir.
Normal bir kullanıcıysanız, kendi süreçlerinizi (process) öldürebilirsiniz, ancak diğer kullanıcılara ait olanları öldüremezsiniz. Ancak, bir root
kullanıcısı tüm işlemleri öldürebilir. root
Kullanıcısı olarak çalıştırmak için herhangi bir komuttan önce sudo
ekleyebilir veya su
yazarak komutu çalıştırabilirsiniz.
Linux’ta, bir süreç öldürüldüğünde, sürece bir “sonlandırma sinyali” gönderilir. Temel Linux sinyallerinin hepsinin bir numarası vardır (1–30+). Birçok farklı sinyal türü olmasına rağmen, çoğunlukla “SIGTERM
” ve “SIGKILL
” sinyalleri ile ilgileniyoruz. SIGTERM
sinyali 15
sayısı ile SIGKILL
ise 9
sayısıyla eşleşir.
SIGKILL’in oldukça yıkıcı olduğunu ve süreç sinyalle ne yapmak isterse istesin süreci sonlandıracağını unutmayın.
sleep
komutunu &
ile devam ettiriyoruz çünkü terminal ile işlemimize devam etmek istiyoruz aksi halde terminal süre doluncaya kadar kullanılmaz olacaktı.
Varsayılan olarak, tüm süreç öldürme komutları, programın çıkmadan önce bazı kodları çalıştırmasına ve böylece “barışçıl (gracefully)” sonlandırılmasına izin veren “SIGTERM
” kullanır.
SIGKILL ile sonlandırdığımızda Killed
, SIGTERM ile sonlanınca Terminated
mesajı aldığımıza dikkat!
Zombi Process (Zombi Süreçler)
Zombi süreci, ana süreç, içinde yaratılan süreçten önce çıktığında gerçekleşir.
Aşağıdaki kod içinde ana thread hemen çıkarken, fork ile açılmış yan süreç 60 saniye beklemeye alınır. Dolayısıyla ps
veya top
ile bakıldığında süreç Zombie süreç olarak görünür. Böyle bir süreci öldüremezsiniz çünkü bu sadece tüm süreçler listesindeki bir girdidir ve onunla ilişkili gerçek bir süreci yoktur. Bir süreç sona erdiğinde, linux çekirdeği, bilgiyi etrafta tutmalıdır, böylece ana süreç, alt sürecin görevlerini tamamlayıp tamamlamadığını ve kendi başına sonlandırılıp sonlandırılmadığını veya öldürüldüğünü öğrenebilir. Ebeveyn bunu yapana kadar, bu “zombi” işlemler, işlemler listesinde görünecektir. Böyle bir süreci öldüremezsiniz çünkü bu sadece tüm süreçler listesindeki bir girdidir ve onunla ilişkili gerçek bir süreci yoktur.
Ancak 60 saniye sonra yavru süreç de çıkış yapınca sürecimiz de artık çalışan uygulamalarda görünmez hale gelir.
# cat zombi.c
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>int main ()
{
pid_t child_pid;child_pid = fork ();
if (child_pid > 0) {
sleep (60);
}
else {
exit (0);
}
return 0;
}
$ killall <uygulama adı>Eğer sonlandırma kodunu girmek istersek (-9 : SIGKILL)
$ killall -9 <uygulama adı> 30 dakikadan fazla çalışan çalışan uygulamaları kapatmak:
$ killall -o 30m <uygulama adı>30 saniyeden az çalışan çalışan uygulamaları kapatmak:
$ killall -y 30s <uygulama adı>s: saniye
m: dakika
h: saat
d: gün
w: hafta
M: ay
y: yıl
Aynı işi süreç ID değeriyle yapmak istersek kill
ve pkill
komutlarını kulanabiliriz.
Linux’te Dosya İzinleri
Linux’te Dosya İzinleri
Önce Dosya/Dizin komutlarını öğrenelim:
chmod : yetkilerini değiştirir
$ chmod <yetki> <dosya/dizin>
chown : sahibini değiştirir
$ chown <yeni_sahibin_kullanıcı_adı> <dosya/dizin>
chgrp : yetkili grubu değiştirir
$ chgrp <yeni_sahibin_kullanıcı_adı> <dosya/dizin>
Dosya ve dizinlerdeki yetkiler şunlardır:
- 0 = : izin mizin yok
- 1 = x : Çalıştırma (eXecute)
- 2 = w: Yazma (Write)
- 3 = r : Okuma (Read)
- 4 = r — : Okuma ver diğerlerini kaldır
- 5 = r — x : Okuma ve Çalıştırma ver yazmayı kaldır
- 6 = rw — : Okuma ve Yazma ver Çalıştırmayı kaldır
- 7 = rwx : Hepsini ver
Bu yetkileri şunlara verir veya alırız:
- u = User — dosya sahibine
- g = Gruba
- o = Other — Diğer kişilere
Yetki verme alma işlemini chmod
komutuyla şöyle yaparız:
- chmod g+w filename > Gruba dosyanın üstüne yazma yetkisi(w) + ver
- chmod g-wx filename > Gruptan Write ve eXecute yetkisini — kaldır
- chmod o+w filename > diğerlerine(o) yazma(Write) yetkisi ver
- chmod o-rwx foldername > dizinde diğerlerinin r,w,x yetkilerini kaldır
- chmod -rwx fileName> herkesin r,w,x yetkilerini kaldır
- chmod a-rwx fileName> herkesin r,w,x yetkilerini kaldır
Herkese tam yetki verip, tüm yetkilerini alalım
$ ls cem.txt -l
--------w- 1 vagrant vagrant 18 Jul 15 06:24 cem.txt$ chmod +rwx cem.txt -v
mode of 'cem.txt' changed from 0002 (-------w-) to 0777 (rwxrwxrwx)$ ls cem.txt -l
-rwxrwxrwx 1 vagrant vagrant 18 Jul 15 06:24 cem.txt$ chmod -rwx cem.txt -v
mode of 'cem.txt' changed from 0777 (rwxrwxrwx) to 0002 (-------w-)
chmod: cem.txt: new permissions are -------w-, not ---------$ ls cem.txt -l
--------w- 1 vagrant vagrant 18 Jul 15 06:24 cem.txt
Gelin şimdi sayılarla yapalım:
$ chmod 0777 cem.txt$ ls cem.txt -l
-rwxrwxrwx 1 vagrant vagrant 18 Jul 15 06:24 cem.txt$ chmod 2 cem.txt -v
mode of 'cem.txt' changed from 0777 (rwxrwxrwx) to 0002 (-------w-)$ ls cem.txt -l
--------w- 1 vagrant vagrant 18 Jul 15 06:24 cem.txt$ chmod 777 cem.txt -v
mode of 'cem.txt' changed from 0002 (-------w-) to 0777 (rwxrwxrwx)$ ls cem.txt -l
-rwxrwxrwx 1 vagrant vagrant 18 Jul 15 06:24 cem.txt
chroot (UnixV7) — 1979
Herşey aslında bir toz bulutuydu… “chroot” tanıtıldı ve UNIX sistemlere eklendi. Böylece prosesler için dosya sisteminde özgün konumlar oluşturuldu ve proses izolasyonu için ilk adımlar atılmış oldu. Bu teknoloji ile birlikte bir process ve onun alt proseslerini diğer tüm sistemden izole etmek mümkündü. Bunu yapabilmek için kullanılacak kütüphaneler ayrı bir “root directory” altına taşınır ve bu klasör altında çalışırdı. Böylece global sistem etkilenmeden, bu belirlenen ortamda root gibi davranarak istediğinizi yapabilirdiniz. Bununla beraber root process leri kolayca chroot yapılmış ortamdan çıkabiliyordu. Bu nedenle biraz eksik kalmış bir teknolojiydi. Mart 1982'de Bill Joy chroot u Unix v7.0' a koyulmuştur. *
Öncelikle kaynağın sahibini (Gökhan ALKAN, gokhan@enderunix.org) ve bir gün kaynağından (http://www.enderunix.org/docs/chrootnedir.pdf) ulaşılamazsa bu güzel anlatılmış bilgi yine erişilebilir olsun diye kendime de not almak için buraya yapıştırayım.
1. Motivasyon Bu makalede özellikle sunucu servis yazılımlarının ve uygulamaların chroot ortamında çalıştırılması, kademeli güvenlik anlayışı gibi yaklaşımlardan ziyade basit olarak chroot nedir ve neden chroot kullanmak gerekli sorusuna cevap aranmaya çalışılacaktır. 2. Chroot Nedir? Chroot yazılımlar için yeni bir kök (/) dizini tanımlar. Kısaca çalıştırılacak olan servis ya da uygulama için gerekli kütüphane, yapılandırma, sürücü dosyaları (device file), bu servis için belirlenen kök dizinde bulunan ilgili yollara (path) kopyalanır ve hapsedilmiş olarak çalıştırılır. Peki chroot kullanmanın getirdiği avantajlar ve dezavantajlar nelerdir ve neden kullanmak gerekli sorusunu kendinize sormuş olabilirsiniz. Kısaca bu sorunun cevabı, eğer sistem üzerinde chroot ortamında çalışan bir servis ya da uygulamadan kaynaklanan bir açıklığı kullanarak sisteme sızan bir saldırgan, bütün dosya sistemine ve işletim sistemi kaynaklarına erişim sağlayamayacak ve sadece chroot için belirlenen kök dizine ve burada bulunan kaynaklara erişim sağlayabilecektir. Ayrıca kısıtlı dosya sistemi erişimi sağlaması yanında kısıtlı komutlara erişim ile de sistem üzerinde bulunan komutlar kümesine erişim de kısıtlanmış olacaktır. Aşağıdaki şekilde ( Şekil 1 Chroot Kullanımı İle Yeni Dosya Sistemi Hiyerarşisi ) chroot kullanımı ile dosya sistemine erişim şematize edilmiştir.
3. Chroot Nasıl Çalışır?
Chroot komutu ‘chroot /chroot
[komut seti]’ şeklinde çalıştırıldığında artık yeni kök dizini olarak ‘/chroot’ görülecektir.
NOT: Burada “/chroot
” dizini özellikle belirtilmemiştir. Bu dizin yerine isteğe göre herhangi bir dizin seçilebilir.
# mkdir /chroot
# chroot /yeni_dizin
Bütün bu işlemler için chroot
komutu, chroot
sistem çağrısını kullanır. Kısaca önce belirlenen yeni kök dizini içerisine girilir ve arkasından chroot sistem çağrısı çalıştırılır ve son olarak belirlenen kullanıcı kimliğine bürünülerek root kullanıcı haklarından vazgeçilir.
# chdir(“/chroot”);
# chroot(“/chroot”);
# setuid(500);
NOT: Sistem üzerinde 500 uid’sine sahip bir kullanıcı olduğu varsayılmıştır.
4. Örnek Chroot Ortamının Oluşturulması Daha öncede belirtildiği gibi sadece saldırganın bütün dosya sistemine ve işletim sistemi kaynaklarına erişimi engellenmiş olacaktır. Aşağıda chroot kullanıma basit bir örnek verilmiştir. Bash kabuğu chroot ortamı altında çalıştırılacak ve birkaç örnek komut chroot ortamı altında çalıştırılacaktır.
# mkdir /chroot
# which bash
/bin/bash
#
# cd /chroot
# mkdir /bin
# mkdir /lib
# ldd /bin/bash
linux-gate.so.1 => (0x00712000)
libtermcap.so.2 => /lib/libtermcap.so.2 (0x00c49000)
libdl.so.2 => /lib/libdl.so.2 (0x00c43000)
libc.so.6 => /lib/libc.so.6 (0x00afe000)
/lib/ld-linux.so.2 (0x00ae0000)
#
Bu çıktıya göre bash için gerekli kütüphane dosyaları teker teker belirlenmeli ve ilgili dizinlere kopyalanmalıdır. Hangi kütüphane dosyalarına ihtiyaç olduğu ‘ldd’ komutu aracılığı ile öğrenilebilir.
# cp –p /lib/libtermcap.so.2 /home/ga/chroot/lib
# cp –p /lib/libdl.so.2 /home/ga/chroot/lib
# cp –p /lib/libc.so.6 /home/ga/chroot/lib
# cp –p /lib/ld-linux.so.2 /home/ga/chroot/lib
Ardından chroot komutu ile bash kabuğu chroot olarak belirtilen dizinde çalışmaya başlayacaktır.
Chroot ortamı altında çalıştırılmak istenen komutlar ve bu komutlar için gerekli kütüphane dosyaları ‘ldd
’ komutu yardımı ile bulunarak ilgili dizinlere kopyalanmalıdır.
# cp –p /bin/bash /chroot/bin
# cp –p /bin/pwd /chroot/bin
# chroot /chroot/ /bin/bash
bash-3.2# pwd
/
bash-3.2# exit
Görüldüğü gibi ‘pwd’ komutu çalıştırıldığında ‘/chroot’ dizinini kök (/) dizini olarak
görülmektedir. Chroot ortamından çıkmak için ‘exit
’ komutu kullanılabilir. ‘pwd
’ gibi
çalıştırılmak istenen komutlar gerekli kütüphane dosyaları ile birlikte ilgili dizinlere
kopyalanarak çalıştırılabilirler.
Burada verilen basit bir örnektir. Asıl chroot kullanım amacı dosya sistemi hiyerarşisi
üzerinde dağıtık biçimde erişim sağlayabilen servisler için kullanımı olmalıdır. Bu şekilde
saldırgan, sistem üzerinde çalışan bir servisten ya da uygulamadan kaynaklanan bir açıklık ile
sisteme sızmayı başardığında bütün dosya sistemine erişimi engellenmiş olacaktır.
5. Kaynaklar
- [1] http://www.sun.com
- man chroot
Linux Paket Yöneticileri
- DEB (Debian, Ubuntu, knoppix)
DEB dosyaları, Debian tabanlı dağıtımlar için kurulum dosyalarıdır. Ubuntu, Debian’ın APT ve DPKG’ye dayalı paket yönetimine dayanmaktadır.
Dpkg(Debian Paket Yönetim Sistemi), Debian Linux ailesi için bir temel paket yönetim sistemidir. .deb paketleri hakkında bilgi edinmek, paketleri; yüklemek, kaldırmak için kullanılır.
APT (Advanced Package Tool-Gelişmiş Paket Aracı), .deb dosyalarının yönetimini sağlayan, çok popüler, ücretsiz, güçlü ve daha çok kullanışlı bir komut satırı dpkg paket yönetim sistemi için bir ön uçtur (dpkg paketin bağımlılıklarını yükleyemezken apt yükleyebilir).
Synaptic Paket Yöneticisi, apt’nin komutlarını kullanarak kullanıcı arayüzü üstünden işleri yapabilmeyi sağlar
- RPM (Red Hat Paket Yöneticisi)
RPM dosyaları, Red Hat tabanlı dağıtımlar (Red Hat Enterprise Linux, CentOS ve Fedora) için kurulum dosyalarıdır. APT benzeri YUM (Yellow Dog Update Modifier) paket yöneticisi ile RPM dosyalarının yönetimi sağlanır. - Pacman Paket Yöneticisi — Arch Linux
Arch Linux ve az bilinen bazı Linux dağıtımları için popüler ve güçlü ancak basit bir paket yöneticisidir, diğer ortak paket yöneticilerinin yükleme, otomatik bağımlılık çözünürlüğü, yükseltme, kaldırma ve yazılım indirme gibi temel işlevlerinden bazılarını sağlar. - Zypper Paket Yöneticisi — openSUSE
OpenSUSE Linux’ta bir komut satırı paket yöneticisidir ve libzypp kitaplığını kullanır, ortak işlevleri arasında depo erişimi, paket kurulumu, bağımlılık sorunlarının çözümü ve daha fazlası bulunur. - Portage Paket Yöneticisi — Gentoo
Gentoo için bir paket yöneticisidir. Portage projesinin temel amacı, geriye dönük uyumluluk, otomasyon ve daha pek çok işlevsellik için basit ve sorunsuz bir paket yönetim sistemi oluşturmaktır.
RPM ve DEB biçimlerinin her ikisi de, bazı meta verilerle birlikte kurulum dosyalarını içeren arşiv dosyalarıdır. Hiçbiri yürütülebilir (çalıştırılabilir) dosyalar değilerdir. DEB dosyaları dpkg
, aptitude
, apt-get
ile kullanılır. Rpm dosyaları ise yum
ile birlikte kullanılır.
RPM paketi içindeki spec
dosyasında, uygulamanın hangi sürümünün yükleneceğini ve çalışması için başka hangi küçük uygulamaların yüklenmesi gerektiği yazılıdır.
DEB dosyası da, tıpkı RPM paketinin spec
dosyasına çok benzeyen bir control
kontrol dosyasına sahiptir.
dpkg Komutları
list
ile get-selections
Farkı
--get-selections [<pattern> ...] Get list of selections to stdout.
-l|--list [<pattern> ...] List packages concisely.
Çıktıları arasındaki 5 satır sadece başlık farkıdır.
Yüklü (install) ve kaldırılmak üzere işaretlenmiş (deinstalled) paketleri listeler.
dpkg --get-selections
list
de aynı çıktıyı insanın okumasına daha kolay sunar.
dpkg -l
Sadece bir paketi listelemek istiyorsanız -l
anahtarına tüm paketin adını veya yıldız karakteriyle içinde geçenleri listeleyebiliriz
Birinci sütundaki karakterlerin anlamları:
İlk karakter: İlk karakter, biz (veya bazı kullanıcılar) paketi kurulum için işaretliyormuş gibi istenen durumu belirtir.
- u: Bilinmiyor (bilinmeyen bir durum)
- i: install — Yükle (kurulum için işaretlenmiştir)
- r: remove — Kaldır (kaldırılmak üzere işaretlenmiştir)
- p: purge —Temizleme (temizleme için işaretlenmiştir)
- h: hold — bekle
İkinci Karakter: İkinci karakter kurulu olsun ya da olmasın mevcut durumu ifade eder.
- n: Not installed — Paket kurulu değil
- i: installed — Paket başarıyla kuruldu
- c: Cfg dosyaları — Yapılandırma dosyaları mevcut
- u: unpacked — Paketlenmemiş- Paket açılmamış halde duruyor
- f: Failed to remove-cfg — Yapılandırma dosyaları kaldırılamadı
- h: Half-installed — Paket yalnızca kısmen kurulur
- W: wait — tetik-bekle
- t: Tetik-bekleme
Üçüncü Karakter: Bu, hata durumuna karşılık gelir. Olası değer şunları içerir:
- R: Reinst-required Paket kurulmalıdır.
Paketin Veri İçeriğini Görüntülemek
Şimdi paketin (control, data ve metadata kısımlarından) veri içeriğini görüntülemek için -L
kullanabiliriz:
Yüklü Dosyanın Hangi Pakete Ait Olduğunu Görüntülemek
-S
Anahtarı sayesinde bir dosya veya dizinin hangi paketler tarafından kullanıldığının bilgisini görebiliriz.
Dosyanın hangi pakete ait olduğunu dpkg -S
ile, paketin yüklü, kaldırılacak olarak işaretlenip işaretlenmediğini dpkg -l
veya apt list <paket> --installed
ile görebiliriz
Bir paketi kurmak için dpkg -i <paketin-yeri>
kullanıyoruz ancak paketin tüm bağımlılıklarınında kullanıcı tarafından önceden kurulmuş olması gerekiyor. Paketi uzak sunucudan indiren ve bağımlılıklarını otomatik kuran bir sisteme gerek olduğu için dpkg
işimizi görmüyor ve apt
kullanıyoruz.
apt-get
Kabuk betiğinde kullanıyorsanız
Paketi Belirli Bağımlılıkları Olmadan Kurmak
dpkg --ignore-depends=bar -i foo_1.2.3_amd64.deb
apt-get
ile bağımlılıklar hariç kurulum yapmak için bağımlı olduğu paketin sonuna “-” karakteri koyarak aşağıdaki komutu kullanabiliriz:
apt-get install foo bar-
apt
Kullanıcı etkileşimli kullanıyorsanız tavsiye edilir.
apt Komutları
apt ile paketi sadece indirmek (kurmadan)
- Yöntem bulunduğu dizine indirir
- Yöntem apt’nin cache dizinine indirir
apt download <paket-adı>
$ sudo apt download paketi_adı
Paketi indirdiği dizin: ./
apt install --download-only <paket-adı>
$ sudo apt-get install --download-only paketi_adı
Paketi indirdiği dizin: /var/cache/apt/archives
root@3484284873b1:~# apt download wget
Get:1 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 wget amd64 1.17.1-1ubuntu1.5 [299 kB]
Fetched 299 kB in 0s (491 kB/s)
W: Can't drop privileges for downloading as file '/root/wget_1.17.1-1ubuntu1.5_amd64.deb' couldn't be accessed by user '_apt'. - pkgAcquire::Run (13: Permission denied)
Aldığımız hata root kullanıcısı olmamız rağmen ortaya çıkıyor. Bunun sebebi şu bug. Bu yüzden indirme işini apt
yerine apt-get
üstünden yapıyoruz ancak kurulum yapmak yerine sadece indirme işlemi yapılmış oluyor:
apt-get install --download-only wget
Yükleme tamamlandığında tüm paketler /var/cache/apt/archives
dizininde yer alacaklar.
Ref: https://unix.stackexchange.com/
apt-get remove paketAdı/ apt-get remove --purge paketAdı
remove
remove is identical to install except that packages are removed instead of installed. Note that removing a package leaves its configuration files on the system. If a plus sign is appended to the package name (with no intervening space), the identified package will be installed instead of removed.
purge
purge is identical to remove except that packages are removed and purged (any
configuration files are deleted too). **
apt-get remove paketAdı
remove
, ikili dosyaları kaldırır, ancak paket yapılandırma veya veri dosyalarını kaldırmaz.
apt-get purge paketAdı
, veya apt-get remove --purge paketAdı
Paket adı ile ilgili her şeyi kaldıracak. Özellikle yapılandırmayı bozduğunuz için bir uygulamayla ‘her şeye yeniden başlamak’ istediğinizde kullanışlıdır.
apt search aranan_kelime
“patroni” kelimesini arıyoruz. FULL TEXT SEARCH ile paketlerin tüm metinlerinde arıyor.
systemd
Systemd linux işletim sisteminin en temel öğelerinden biridir. Systemd bir init servisidir. Init kelimesi aslında “initialization” kelimesinden gelmektedir. Bu işlem bilgisayar açılırken başlar ve sistem kapanıncaya kadar çalışmaya devam eder. İşletim sistemi açılırken başlayan ilk işlemdir. Systemd’yi yalnızca bir işlem olarak düşünmek aslında doğru değildir. 2013'de Poettering dediği gibi systemd aslinda bir işlem değil, büyük bir yazılım paketidir ve içinde 69 adet farklı binary bulunur. Systemd Linux’da user space’in ilk işlemidir ve user space’i başlatır. PID olarak 1 alır. Systemd kernel tarafından başlatılır. Şu an günümüzdeki çoğu linux sistemi systemd kullanır. Systemd hakkında ciddi tartışmalar hala devam etmektedir. Bazıları systemd’yi UNIX felsefesine aykırı bulmaktadır.
Systemd’de unit kavramına değinelim şimdi de. Systemd’de unitler sistemin yönetebildiği herhangi bir kaynağa denir. Farklı tip unitler mevcuttur. Genelde bu unitlerin bir kopyası /lib/systemd/system dizininde tutulur fakat sadece bura ile sınırlı değildir. Tüm pathleri görmek için bu komutu çalıştırabilirsiniz:
systemctl show — property=UnitPath
Systemd’in ana görevlerinden biri aslında daemon olmasıdır. Zaten sonunda ki d harfide buradan gelmektedir. Daemon ne dersek ise daemonlar özetle otomatik başlatılan, arka planda çalışıp kullanıcı ile interaktif iletişimde bulunmayan, sürekli çalışan programlardır. Genelde bir olayı beklerler ve o olay olduğunda ona cevap olarak çeşitli işlemler yaparlar.
Systemctl ise systemd servislerini yönetmek, durdurmak, başlatmak ve durumlarını kontrol etmek gibi işlemlerin yapılmasını sağlayan bir komuttur. Systemctl ile systemd servislerini yönetmek çok kolaydır. Makale sonunda temel birkaç systemctl örneğini verdiğim gibi basit kelimeler ile systemd servislerini yönetebilirsiniz.
Systemd ile nasıl linux servisi yaratabiliriz?
O kadar teoriden sonra şimdi de biraz pratik yapma zamanı. Systemd ile nasıl bir linux servisi oluşturabiliriz ona bakalım. Systemd ile servis oluşturmadan önce root kullanıcısına geçmenizi öneririm.
Bu systemd servisim ile bir de docker container’ı çalıştıracağım. Bunun için aşağıdaki docker komutu ile bir docker container’ı olusturalim:
docker run -p=7474:7474 -p=7687:7687 — volume=/home/ user/neo4j/data:/data — name neo4jdocker -d neo4j
Şimdi systemd klasöründe .service uzantılı bir dosya yaratalım.
Bu path’de örnek bir dosya açalım: /etc/systemd/system/neo4j.service
Eğer root yetkileri olmadan normal kullanıcı ile de bu servisi başlatmak istiyorsanız aşağıdakine benzer bir dizinde kullanabilirsiniz.
$HOME/.config/systemd/user/neo4j.service
Örnek service dosyamız:
[Unit]
Description=neo4j Container
Requires=docker.service
After=docker.service[Service]
Restart=always
ExecStart=/usr/bin/docker start -a neo4jdocker
ExecStop=/usr/bin/docker stop -t 3 neo4jdocker[Install]
WantedBy=local.target
Daha sonra bu komut ile servisi başlatalım:
sudo systemctl start neo4j.service
sistem açılışında otomatik başlaması içinse;
sudo systemctl enable neo4j.service
Servisin durumunu görmek için;
sudo systemctl status neo4j.service
Burada önemli olan bir husus her zaman full dizin kullanmalısınız. Yani /usr/bin/docker yerine sadece docker yazamazsınız. Şimdi servis dosyamızda ki her bir bölümü ayrı ayrı inceleyelim.
İlk kısımda unit’in kendisine ait özelliklere ve onun bağımlılıklarına yer veriyoruz. Bu kısımda description ekleyebiliriz. Description’da bu unit’i tanımlayacak bir cümle yazabilirsiniz. Daha sonra “after” geliyor. Burada ise bizim unit’imizin hangi servislerden sonra başlatılacağını belirtiyoruz. Bizim servisimiz docker ile çalıştığı için ön şart olarak docker koyuyoruz. Burada koyabileceğimiz diğer seçenekler ise Requires ve Wants. After ile sadece belirtilen servisin başlayıp başlamadı kontrol edilir eğer belirtilen servis başlamış ise bizim servisimizde başlatılacaktır. Fakat requires ve want seçenekleriyle ayrıyetten bir tetikleme gerçekleştirebiliriz. Bu iki seçenek de belirttiğimiz servisleri otomatik olarak tetikleyecektir. Bu ikisinin farkı ise birinde zorunluluk varken bir diğerinde yoktur. “Requires”da belirttiğimiz servis başlamaz ise bizim servisimizde başlamayacaktır fakat “wants”da soft dependency vardır yani eğer belirttiğimiz servis başarısız dahi olsa yine de bizim servisimiz tetiklenecektir.
Şimdi de servis kısmını açıklayalım. Servis kısmında daha çok unit başladığı anda hangi komutların çalıştırılacağına dair bilgileri koyarız. ExecStart komutu ile servisimiz başladığı anda hangi komutun çalıştıracağını belirtiriz, ExecStartPre veya ExecStartPost seçeneklerini de koyabiliriz, yine bunlara benzer olarak ExecStop ile servis durdurulduğu anda hangi komutun çalıştırılacağı, ExecReload ile servis yenilendiği anda hangi komutun çalıştırılacağını belirtebiliriz.
Bunlara benzer daha bir çok parametre var. Bunların hepsini türkçeye çevirmeye üşendiğim için aşağıda referans olması amacı ile bir makale paylaşacağım. Ayrıca daha detaylı bilgi için aşağıdaki komutu da çalıştırabilirsiniz:
man systemd.service
Systemd targets
Eski init sistemlerde kullanılan runlevel mantığı systemd ile yerini “systemd targets” isimli konsepte bırakmış bulunuyor. Bu “systemd targets”lar .target
uzantılı unit dosyalarında tanımlanır. Bunların yaptığı iş, servisleri gruplandırarak hangi servis unit’lerinin hangi çalışma modunda çalıştığını belirlemektir.
Öntanımlı target’ın hangisi olduğunu görüntülemek:
# systemctl get-default
Sistemdeki tüm target’lerı görüntülemek:
# systemctl list-units --type target
Eğer default target’ı değiştirmek isterseniz aşağıdakine benzer bir komut kullanabilirsiniz:
# systemctl set-default multi-user.target
Örnek systemctl Komutları
enable
ettiğiniz hizmet, bilgisayarı reboot ettiğinizde otomatik başlatıyor olacak. disable
ettiğinizde ise artık bilgisayarı restart ettiğinizde çalışmıyor bulacaksınız.
*.service
Dosyasını bir yerlerde anlattığım hizmet dizinlerinden birinde oluşturduğunuzda hizmetleri listelediğinizde (systemctl list-units --type=service --all
) göremezsiniz. Ancak enable ettiğinizde göreceksiniz. Ama hizmeti başlatmak için start
komutu vermeniz yeterli. Sistemi tekrar başlattığınızda (restart, reboot, halt ne derseniz artık) yine çalışmıyor bulacaksınız (ta ki enable edinceye değin).
Bir servisi başlatmak için;
sudo systemctl start application.service
Bir servisi durdurmak için;
sudo systemctl stop application.service
Bir servisi yeniden başlatmak için;
sudo systemctl restart application.service
Bir servisi etkin hale getirmek ve devre dışı bırakmak için:
sudo systemctl disable application.service
sudo systemctl enable application.service
enable
, belirtilen birimi ilgili yerlere bağlar, böylece otomatik olarak önyükleme sırasında veya ilgili donanım takıldığında veya birim dosyasında belirtilenlere bağlı olarak diğer durumlarda başlar.
MariaDB’yi ilk kurduğunuzda, systemctl’i çalıştırıp mariadb.service
’i etkinleştirmeniz (systemctl enable mariadb.service
) işletim sisteminizin önyüklemesinde servisinizin başlatılmasını sağlar.
MariaDB’yi başlatmak için systemctl start mariadb.service
’i çalıştırmak veya sadece sisteminizi yeniden başlatmak (reboot) isteyebilirsiniz.
Devre dışı bırakmak için artık önyüklemede başlamaması için systemctl’yi disable ile çalıştırın mariadb.service’i devre dışı bırakın.
Bir servisin durumunu kontrol etmek için;
systemctl status application.service
Bütün servisleri listelemek için;
systemctl list-units --type=service --all
Bir servisin ayrıntılarını görmek için;
systemctl cat application.service
veya
systemctl show application.service
Systemd hakkında öğrenilecek ve yazacak çok fazla şey var, daha fazla şey öğrendikçe bu yazımı güncelleyip sizlerle paylaşacağım.
Berk Karabacak’ın artık google önbelleğinden erişilebilen makalesidir.
Okuması faydalı kaynaklar;
https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files
https://wiki.archlinux.org/index.php/systemd
https://www.freedesktop.org/software/systemd/man/systemd.service.html
history İşlemleri
history ile bash üstünde koşturduğumuz komutları listeliyoruz.
Eğer history’den bir komutu çağırmak istersek yukarı/aşağı oku kullanıyoruz. Ama sıra numarasını kullanarak doğrudan komutu çalıştırabiliriz: $ !SıraNo
Eğer listeden atmak istediğimiz bir aralık varsa history -d <sıra numarası>
komutunu çalıştırıyoruz.
$ for line in $(seq 683 700)
> do
> history -d 683
> done
Başka bir örnek:
Türkçe Linux kaynak olarak çok güzel bir hazine: http://www.enderunix.org/docs/
Linux, kernel versiyonunu öğrenmek
hostnamectl
/etc/os-release
İşletim sistemi, versiyonu öğrenmek için:
$ cat /etc/os-release
$ lsb_release -a
Ayrıca bilgisayar adını öğrenmek ve değiştirmek için:
$ hostnamectl
Linux Kernel’in versiyonunu öğrenmek için:
$ uname -r
$ cat /proc/version
CPU Bilgileri
İşlemcimizin mimarisine dair bilgi edinmek için lscpu
komutunu çalıştıralım
$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 1
Core(s) per socket: 1
Socket(s): 16
NUMA node(s): 1
Vendor ID: GenuineIntel
CPU family: 6
Model: 42
Model name: Intel Xeon E312xx (Sandy Bridge, IBRS update)
Stepping: 1
CPU MHz: 1995.174
BogoMIPS: 3990.34
Virtualization: VT-x
Hypervisor vendor: KVM
Virtualization type: full
L1d cache: 32K
L1i cache: 32K
L2 cache: 4096K
L3 cache: 16384K
NUMA node0 CPU(s): 0-15
Flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology tsc_known_freq pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx hypervisor lahf_lm ibrs ibpb kaiser tpr_shadow vnmi flexpriority ept vpid xsaveopt arat
İşlemci bilgilerini tutan dosya /proc
dizini altında cpuinfo
dosyasında saklıdır:
$ ll /proc/cpuinfo
-r--r--r-- 1 root root 0 Jan 15 22:38 /proc/cpuinfo
İçeriğini okumak için:
$ cat /proc/cpuinfo
En basit haliyle 16. işlemci çekirdeğinin bilgilerini aşağıdaki gibi alabiliriz:
processor : 15
vendor_id : GenuineIntel
cpu family : 6
model : 42
model name : Intel Xeon E312xx (Sandy Bridge, IBRS update)
stepping : 1
microcode : 0x1
cpu MHz : 1995.174
cache size : 16384 KB
physical id : 15
siblings : 1
core id : 0
cpu cores : 1
apicid : 15
initial apicid : 15
fpu : yes
fpu_exception : yes
cpuid level : 13
wp : yes
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 ss syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopology tsc_known_freq pni pclmulqdq vmx ssse3 cx16 pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx hypervisor lahf_lm ibrs ibpb kaiser tpr_shadow vnmi flexpriority ept vpid xsaveopt arat
bugs : cpu_meltdown spectre_v1 spectre_v2 spec_store_bypass l1tf mds swapgs itlb_multihit
bogomips : 3990.34
clflush size : 64
cache_alignment : 64
address sizes : 40 bits physical, 48 bits virtual
power management:
Her soketin çekirdekleri için aynı bilgi dönecektir. Eşsiz değerleri elde etmek için uniq
uygulamasına pipe ile bağlıyoruz.
Bilginin belirli bir kısmını çekmek için:
---> üretici bilgisi 16 çekirdek için aynı olduğundan eşsizi çekelim
$ cat /proc/cpuinfo | grep 'vendor' | uniq
vendor_id : GenuineIntel$ cat /proc/cpuinfo | grep 'model name' | uniq
model name : Intel Xeon E312xx (Sandy Bridge, IBRS update)$ cat /proc/cpuinfo | grep processor | wc -l
16$ cat /proc/cpuinfo | grep 'core id'
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
core id : 0
Ayrıntılı işlemci bilgisi:
$ sudo dmidecode --type processor
[sudo] password for jenkins:
# dmidecode 3.0
Getting SMBIOS data from sysfs.
SMBIOS 2.8 present.Handle 0x0400, DMI type 4, 42 bytes
Processor Information
Socket Designation: CPU 0
Type: Central Processor
Family: Other
Manufacturer: QEMU
ID: A1 06 02 00 FF FB 8B 0F
Version: pc-i440fx-zesty
Voltage: Unknown
External Clock: Unknown
Max Speed: 2000 MHz
Current Speed: 2000 MHz
Status: Populated, Enabled
Upgrade: Other
L1 Cache Handle: Not Provided
L2 Cache Handle: Not Provided
L3 Cache Handle: Not Provided
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 1
Core Enabled: 1
Thread Count: 1
Characteristics: NoneHandle 0x0401, DMI type 4, 42 bytes
Processor Information
Socket Designation: CPU 1
Type: Central Processor
....
lshw
lshw
, bir bilgisayarın donanım yapılandırması hakkında derinlemesine bilgi toplamak için minimal bir araçtır. Donanım sınıfını, bu durumda CPU
’yu seçmek için -C
seçeneğini kullanabilirsiniz:
Referans: https://www.tecmint.com/check-linux-cpu-information/
inotify-tools İle Dizin ve Dosya İzleme
inotify-tools paketi kurulduktan sonra betik olarak dizin takip edilebilir. Komut olarak kullanılabilen argümanlardan --monitor
sayesinde sürekli itibarde ilgili dizini takip eder. --daemon
Argümanı da --monitor
gibi çalışır ancak arka planda çalışır.
Süzebileceğiniz olaylar:
Events:
access : dosya/dizin içerikleri okundu
modify : dosya/dizin içerikleri yazıldı
attrib : dosya/dizin özellikleri değiştirildi
close_write : yazılabilir kipte açıldıktan sonra dosya/dizin
kapatıldı
close_nowrite : salt okunur kipte açıldıktan sonra dosya/dizin
kapatıldı
close : dosya/dizin, okuma/yazma kipine bakılmaksızın kapalı
open : dosya veya dizin açıldı
moved_to : dosya veya dizin izlenen dizine taşındı
moved_from : izlenen dizinden taşınan dosya veya dizin
move : izlenen dizine veya dizinden taşınan dosya veya
dizin
create : izlenen dizinde oluşturulan dosya veya dizin
delete : izlenen dizinde silinen dosya veya dizin
delete_self : dosya veya dizin silindi
unmount : bağlanmamış dosya veya dizini içeren dosya sistemi
Bir Dosyayı İzlenen Dizine ve Dışına Taşımak
Başka bir konsoldan cem
dosyasını /tmp
dizinine taşıyoruz: mv /cem /tmp
# inotifywait /tmp
Setting up watches.
Watches established.
/tmp/ MOVED_TO cem
Aynı şekilde /tmp
dizininden cem dosyasını taşıyoruz: mv cem ..
# inotifywait /tmp
Setting up watches.
Watches established.
/tmp/ MOVED_FROM cem
touch & echo İle Bir Dosya Oluşturmak
Başka bir konsolda /tmp# touch deneme
/# inotifywait --monitor /tmp
Setting up watches.
Watches established.
/tmp/ CREATE deneme
/tmp/ OPEN deneme
/tmp/ ATTRIB deneme
/tmp/ CLOSE_WRITE,CLOSE deneme
Başka bir konsolda /tmp# echo aaa > dene
/# inotifywait --monitor /tmp
Setting up watches.
Watches established.
/tmp/ CREATE dene
/tmp/ OPEN dene
/tmp/ MODIFY dene
/tmp/ CLOSE_WRITE,CLOSE dene
Varolan Dosyanın İçeriğini Değiştirmek
/tmp/ MODIFY dene
/tmp/ OPEN dene
/tmp/ MODIFY dene
/tmp/ CLOSE_WRITE,CLOSE dene
echo ile dosya içeriğine ekleme yaptığımızda: /tmp# echo bbb >> dene
/tmp/ OPEN dene
/tmp/ MODIFY dene
/tmp/ CLOSE_WRITE,CLOSE dene
Dizini Listelediğimizde
ls -al
komutuyla listeleyelim:
/tmp/ OPEN,ISDIR
/tmp/ ACCESS,ISDIR
/tmp/ ACCESS,ISDIR
/tmp/ CLOSE_NOWRITE,CLOSE,ISDIR
Varolan Dosyayı Sildiğimizde
/tmp/ DELETE dene
Yeni Dizin Oluşturduğumuzda
mkdir yeni
Komutu çalıştığında çıktı:
/tmp/ CREATE,ISDIR yeni
--parents Anahtarıyla Dizinler Oluşturduğumuzda
mkdir --parents yepis/yeni/bir/dizin
komutuyla:
/tmp/ CREATE,ISDIR yepis
/tmp/ OPEN,ISDIR yepis
/tmp/ CLOSE_NOWRITE,CLOSE,ISDIR yepis
Bash Betiği İle Sürekli Takip Etmek
#!/bin/bashunset IFS # varsayılan olarak boşluk, tab ve yeni satırdır
set IFS = "\t" # \t ile ayıracağız çünkü değişkenlere atamak gerek# sürekli takip için --monitor
# sadece close_write olayını süzüyoruz (dosya içerik işlemi)
# /tmp ve /root dizinlerini izleyeceğiz
inotifywait --monitor -e close_write \
/tmp/ /root/ \
2</dev/null |&# inotify'ın ürettiği satırı değişkenlere böleceğiz
# çıktı: /tmp/ CLOSE_WRITE,CLOSE dene
# \t ile bölerek ilki dizin, ikincisi işlem, sonuncusu dosya olacak
while read -r dir op file
do
echo "ADIM: $step, DIZIN: $dir, DOSYA: $file, ISLEM: ${op}"
[[ "${dir}" == '/tmp/' && "${file}" == *.txt ]] &&
echo "$file $dir $op." [[ "${dir}" == '/root/' && "${file}" == YEDEK*.txt ]] &&
echo "root dizinine yedek dosya geldi gibi" [[ "${dir}" == '/tmp/' && "${file}" == SHUT ]] && break ((step+=1))
done
Komut: /tmp# echo hadi >> metin.txt
Çıktı:
ADIM: 2, DIZIN: /tmp/, DOSYA: metin.txt, ISLEM: CLOSE_WRITE,CLOSE
metin.txt /tmp/ CLOSE_WRITE,CLOSE.
Komut: /tmp# echo hadi >> /root/YEDEKhede.txt
Çıktı:
ADIM: 3, DIZIN: /root/, DOSYA: YEDEKhede.txt, ISLEM: CLOSE_WRITE,CLOSE
root dizinine yedek dosya geldi gibi
Yerel DEB (repo) Havuzu Oluşturma
1. apt-mirror Yöntemiyle
Önce apt-mirror ile bir debian paket havuzunu makinemize çekelim ve diğer sunucularımızın güncellemeler için uzak makinelere gitmesini engelleyip, internet yükümüzü azaltmayı sağlayalım.
Önce apt-mirror paketini indirip ayarlarını yapalım
$ apt install -y apt-mirror
$ sudo vim /etc/apt/mirror.list
Paketlerin yolu olarak /repo/apt-mirror dizinini verelim:
apt-mirror
’ın aynalayacağı debian reposunu ada end config
satırının altına yazıyoruz.
Sonuç olarak mirror.list
dosyamız:
Şimdi apt-mirror’ı çalıştırarak paketleri 20 thread açarak indirmeye başlayalım:
Paketleri Sunmak
Dosya yolu vererek file://
protokolüyle diğer sunucuların bu paket havuzuna ulaşmasını sağlayabiliriz ama Apache internet sunucusu ile bunu sağlayalım
Artık deb repo olarak kendi makinamızı gösterip güncelleyebiliriz:
$ apt update
Bir paket yüklemek istediğimizde
2. Paket Havuzu Yöntemiyle
İkili paketler, .deb
ile biten bağımsız dosyalardır. Her zaman katı bir adlandırma kuralını izlerler: paket-adı_versiyon_mimari.deb
.
- Paket adı yalnızca küçük harf, rakam ve birkaç noktalama karakteri içermelidir. Asla bir alt çizgi içeremez(büyük I karakteri de sorun çıkarabilir).
- Sürüm, yukarı akış kaynağının sürümünü ve Debian paketinin sürümünü bir tire ile ayrılmış olarak gösterir.
- Mimari, işlemci tipini (ve Hurd paketleri için işletim sistemini) gösterir. Paket derlenmiş çalıştırılabilir dosyalar içermiyorsa
all
mimarisine sahip olacaktır. - Debian paketi olan ikili dosya esasen bir arşiv dosyasıdır ve açıldığı vakit 3 temel bileşenden oluştuğu görülür:
- 1. debian-binary
- 2. control.tar.gz paket için “kontrol” bilgisini içeren sıkıştırılmış bir tarball.
- 3. data.tar.gz kök dizine göre paketin içeriğini içeren bir sıkıştırılmış tarball.
Bir Debian deposu birkaç sürüm (release) içerir. Debian sürümleri, “Oyuncak Hikayesi” filmlerinin (wheezy, jessie, stretch, …) karakterlerinden sonra adlandırılır. Kod adlarının suites olarak adlandırılan takma adları vardır (stable -kararlı-, oldstable -eski kararlı-, testing -test etme-, unstable -kararsız). Bir sürüm birkaç bileşene (components) bölünmüştür. Debian’da bunlar main, contrib, non-free olarak adlandırılır ve içerdikleri yazılımın lisans koşullarını belirtir. Bir sürümde ayrıca çeşitli mimariler (amd64, i386, mips, powerpc, s390x, …) ve kaynaklar ve mimariden bağımsız paketler için paketler bulunur.
Sources.list dosyasındaki bir girdinin yapısı
The base can be
http:
,ftp:
orfile:
URI.The distribution is usually
stable
,frozen
orunstable
for official Debian releases, but it can be anything. The distribution may specify multiple directory levels.kararsız dağıtımı, aktif olarak geliştirme sürecinin yaşandığı dağıtımdır. Bu dağıtım genelde, geliştiriciler ve bu çerçeveye dahil olanlar tarafından kullanılmaktadır.
test dağıtımı, henüz kararlı dağıtıma girmemiş paketlerin bulunduğu dağıtımdır. Bu paketler kararlı dağıtıma girmek için beklemektedir. Bu dağıtımı kullanmanın en büyük avantajı ise, yazılımların güncel sürümlerini sunmasıdır. *
The component is usually
main
,contrib
ornon-free
in official Debian releases. Other common components arelocal
(for internal use only) andunofficial
(for distribution). Again, this string can be anything.
Flat Repository Format *
Öncelikle Düz Depo Formatını anlamak için bir özet yaparak inceleyelim ve sonrasında tafsilatlı kurulumuna geçeceğiz
Düz bir depo, dizinlerin dağıtım hiyerarşisini (dists
) kullanmaz ve bunun yerine meta dizin ve endekslerini doğrudan arşiv köküne (veya bunun bir kısmına) yerleştirir. sources.list
Sözdiziminde, aşağıdaki gibi düz bir depo belirtilir:
deb uri directory/
Yani: Apache ile http
veya https
protokolü üzerinden deb
paketlerinin sunumunu sağlamak isteriz. Apache kurulduğunda varsayılan olarak /usr/local/apache2
dizinini sunucunun varsayılan kök dizin olarak httdp.conf
içinde tayin etmiştir.
Apache ayarları içinde istekleri karşılayacak dizin tayini varsayılan olarak şu şekilde yapılmıştır:
DocumentRoot "/usr/local/apache2/htdocs"
<Directory "/usr/local/apache2/htdocs">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
Bu dizin yapısı yerine aşağıdaki dizin yapısını kullanmak için httpd.conf içine şu ekleyemi yapalım:
Buna göre http://localhost/repos/apt/debian isteğini /srv/repos/apt/debian
dizinine yönlendiriyor.
Alias /repos/apt/debian /srv/repos/apt/debian<Directory "/srv/repos/">
Options Indexes FollowSymLinks Multiviews
Require all granted
</Directory>
Artık bu dizin içinde a ve b adında dizinler yaratıp içlerine çeşitli deb paketleri kopyalayarak Packages
dosyasını oluşturmak için dpkg-scanpackages
komutunu çalıştıralım.
Eğer makinanızda dpkg-scanpackages uygulaması yoksa dpkg-dev paketini yüklemeniz gerekiyor
dpkg-scanpackages -m b /dev/null > ./b/Packages
Şimdi istemcide /etc/apt/sources.list dosyasında aşağıdaki değişikliği yapalım ve apt update ile paket bilgilerini çekerek bakalım.
Paketleri sorgulamak için apt list
veya apt show
komutlarını kullanabiliriz:
apache2 Docker sürümünü kuralım.
# apache ayarlarını docker'dan çekerek host makineye aktaralım
# belki üstünde değişiklik yaparak sürekli bu halini kullanırızc:\> docker run --rm httpd:2.4 cat /usr/local/apache2/conf/httpd.conf > httpd.conf# Eğer sitelerin olduğu dizini (htdocs) host makineden bağlamak istersek tıpkı httpd.conf gibi -v anahtarı kullanırız# Docker içinde 80 portunda koşacak ama host 90 portundan bağlanacakc:\> docker run --privileged -dit --name myapache -p 90:80 -v "%cd%":/usr/local/apache2/htdocs/ -v "%cd%"/httpd.conf:/usr/local/apache2/httpd.conf httpd:2.4
Konteynere terminalimizi bağlayarak deb repo oluşturmakta kullanacağımız paketi kuralım:
c:\> docker exec -it myapache bash
root@myapache:/usr/local/apache2# apt-get install dpkg-dev -y
Artık hazırız!
Ana dizinimiz apache’nin web sayfalarını tuttuğu htdocs
dizini. Apache’nin ayar dosyasıyla oynamak istemediğim için bu dizini tercih ettim.
cd /usr/local/apache2/htdocs
Deb
paketlerini, mimarilerine göre (32 bit uygulama paketleri için i386
, 64 bit uygulama paketleri için amd64
isimli dizinleri gibi paketin çalışacağı işlemci mimarisine göre farklı dizinler oluşturacak şekilde) ./debs
dizininde yeni dizinler oluşturup deb
paketlerini bu dizinlere koyacağız.
# pwd
/usr/local/apache2/htdocs/debs# tree
.
|-- amd64
| |-- Packages.gz
| |-- cem.0.8.0.20.400-debug.deb
| |-- cem.0.8.0.20.500-debug.deb
| |-- cem.0.8.0.21.100-debug.deb
| |-- cem.0.8.0.21.200-debug.deb
| |-- cem.0.8.0.21.deb
| `-- wget_1.20.1-1.1_amd64.deb
`-- wget
|-- DEBIAN
| |-- conffiles
| |-- control
| `-- md5sums
|-- etc
| `-- wgetrc
`-- usr
|-- bin
| `-- wget
wget
’in deb dosyasını indirdim ve wget
adında bir dizine açtım.
- Artık control dosyasındaki versiyon bilgilerini değiştirerek aynı paketi sürekli derleyip yeni versiyonlar üretebilirim.
- Bu versiyonları
dpkg-scanpackages --multiversion . /dev/null | gzip -9c > amd64/Packages.gz
komutuyla tarayıp endeks dosyası olan sıkıştırılmışPacakges.gz
dosyası oluşturabilir apt show cem -a
ile listeleyebilirim.
# cd /usr/local/apache2/htdocs/debs/amd64
#apt download wget# cd /usr/local/apache2/htdocs/debs
# dpkg dpkg-deb -R amd64/wget_1.20.1-1.1_amd64.deb wget# nano wget/DEBIAN/control
Paketin adı wget
idi ve onu cem
ile değiştirdim. Sanki yeni versiyonlar oluyormuş gibi sürekli versiyon bilgisini değiştirip wget
dizininden paket oluşturdum.
# dpkg-deb -b ./wget ./amd64/cem.0.8.0.19.800-debug.deb
Şimdi 64 bitlik yazılımların olduğu amd64
dizindeki deb
dosyalarını tarayıp endeks oluşturalım ve yine aynı dizinde Packages.gz
dosyasına bu endeksi yazalım (32 bit uygulamalar için i386
dizinine giderek aşağıdaki komutu ...| gzip -9c > i386/Packages.gz
olacak şekilde çalıştırın):
# cd /usr/local/apache2/htdocs/debs/amd64
# dpkg-scanpackages -m . /dev/null | gzip -9c > amd64/Packages.gz
Yukarıdaki kısımda control dosyasını düzenlemek ve paket oluşturmak, paketlerin endeksini oluşturmak için komutları yazarsak:
# yap versiyon bilgisindeki değişikliği
Package: cem
Version: 0.8.0.230.debug
Architecture: amd64
...
# sonra kaydet, çık$ nano wget/DEBIAN/control
# sonra
# 1. paket haline getir (ismi de farklı olsun ki
# diğer paketlerle aynı dizinde yer alabilsin)
# 2. paketleri tara ve endeks oluştur $ dpkg -b wget amd64/cem.0.8.0.230.debug.deb && dpkg-scanpackages --multiversion ./amd64 /dev/null | gzip -9c > ./amd64/Packages.gz
Artık istemci makinemizde ayar yapabiliriz. İstemciden kastımız paket havuzuna paket yöneticisi komutları (apt-get list
, yum install
vs.) çalıştıracağımız makine.
Önce kurduğumuz paket havuzunun adresini /etc/apt/sources.list
dosyasına ekleyelim. Biraz inceleyelim:
- paket kaynakları çeşitli olabilir (file, cdrom, http, ftp, copy gib) burada http’yi seçiyoruz. Aynı makinede hem paketleri hem apt’yi çalıştıracağımız için
file
da olabilirdi (file:/usr/local/apache2/debs/amd64
gibi).
https
yerinehttp://…
diye istek yapacağımız için[trusted=yes]
diye yazıyoruz,- İstemci olarak, bu ayarı yaptığımız makine 64 bitlik uygulamaları kurabileceğimiz bir makine. Bu yüzden
amd64/
diye sonuna ekliyoruz. - Kılavuzda
deb [ options ] uri suite [component1] [component2] […]
şekliyle seçimli özellikleri köşeli parentez içinde belirtiyoruz. Mimari için[arch=x,y,z]
birden fazla mimariyi seçebiliriz. Örneğin x86–64 mimarilerini destekleyen bir komut kümesine sahip işlemcimiz olabilir.[trusted=yes]
ileRelease
dosyası imzalanmasa veya imza kontrol edilemese bile bu kaynaktan gelen paketlerin her zaman kimlik doğrulamasının yapıldığını gösterecek şekilde ayarlanabilir.
deb [trusted=yes] http://localhost/debs/ amd64/veya hem mimari hem de imzasız paketler için (araya bir boşluk)deb [trusted=yes arch=amd64] http://localhost/debs amd64/
Şimdi repodan son paketleri çekmek için apt update
komutunu çalıştırdığımızda amd64 paketlerinin listesini çekecek. Sonra paketimizi hem show
hem list
argümanlarıyla sorgulayalım.
# apt update
# apt show wget
# apt show cem -a
# apt list cem -a
En son 0.8.0.19.800-debug
versiyonunu oluşturduk ve versiyon sıralamasına göre en altta gösterdi.
Tüm işlemleri hızlıca görelim:
# yap versiyon bilgisindeki değişikliği
Package: cem
Version: 0.8.0.230.debug
Architecture: amd64
...
# sonra kaydet, çık$ nano wget/DEBIAN/control# sonra
# 1. paket haline getir (ismi de farklı olsun ki
# diğer paketlerle aynı dizinde yer alabilsin)
# 2. paketleri tara ve endeks oluştur
# 3. Hem deb sunucu hem istemci olarak aynı makine kabul edelim
# ve paket listesini güncelleyip, paketi arayalım$ dpkg -b wget amd64/cem.0.8.0.230.debug.deb && dpkg-scanpackages --multiversion ./amd64 /dev/null | gzip -9c > ./amd64/Packages.gz && apt update && apt list cem -a
Ref: *
Hata giderme: Packages with multiple instances but no --multiversion specified
Ref: **
cem
İsimli paketten birden fazla versiyon (sürüm) mevcut ve eğer -m
veya --multiversion
anahtarları ile taramayı gerçekleştirmezsek sadece bir paketi girdi olarak görebiliriz:
6 Sürüm cem
paketi ve 1 sürüm wget
paketini sadece 2 girdi olacak şekilde paketler dosyası oluşturdu. Paketleri listelemek istediğimizde sadece 1 tane sürümünü görebileceğiz:
Ama -m
anahatarıyla tüm sürümleri paketledi:
# dpkg-scanpackages -m . /dev/null | gzip -9c > amd64/Packages.gz
Şimdi tüm sürümlerini listede görebiliriz:
Ref: https://www.percona.com/blog/2020/01/02/how-to-create-your-own-repositories-for-packages/
Debian Paketi Hazırlamak
Hazır bir debian paketi sıkıştırılmış dosyadır ve içini görüntlediğimizde şu bölümlerden oluştuğunu görürüz:
- debian-binary, paket bilgisini barındırır
- control.tar.gz, paketin üst bilgilerini ve konfigürasyon ve bakım betik dosyalarını barındırır
- data.tar.gz, dosya sisteminde olacak dosyaları içerir
Önce ar programının olduğu binutils paketini kuralım:
$ apt install binutils
Şimdi deb uzantılı dosyamızı açalım:
$ ar t zlib1g-dev_1.2.8.dfsg-2ubuntu4.3_amd64.deb
dpkg -I
veya --info
komutuyla paketin bilgilerini görelim:
.changes Dosyasıyla Ne Yapmak Nereye Varmak İstemektedir
Debian Package Upload Tool (dput) İle Paket Yükleme
Çalıştırılabilir Programı Hazırlamak
“Merhaba Mars” programını C dilinde yazalım derleyelim ve debian paketi haline getirip dağıtalım.
src/c/merhabamars
dizinlerini oluşturmak için
# mkdir -p src/c/merhabamars
# cd src/c/merhabamars
# vim merhabamars.c
Kodumuzu yazalım:
#include <stdio.h>
int main (void) {
puts("Merhaba Mars");
return 0;
}
Şimdi derleyip çıktılarımızı üretelim. -Wall
ile tüm uyarıları görelim ve -o
ile çıktı dosyasının adını verelim. Eğer -o
anahtarını kullanmazsak a.out adında bir dosya üretecek.
# gcc -Wall merhabamars.c -o merhabamars
# ls
merhabamars merhabamars.c
Şimdi programımızı çalıştıralım:
# ./merhabamars
Merhaba Mars
Strip komutu, daha çok, hafif olması için gerekli minimum bilgileri içeren bir üretim kalitesinde nesne dosyası üretmek istediğiniz durumlarda kullanılır. Yürütülebilir dosyanızın veya nesne dosyanızın tersine mühendislik yapılmasını istemiyorsanız da kullanabilirsiniz. Aşağıdaki komutu çalıştırdıktan sonra çalıştırılabilir dosyanızın daha küçüldüğünü göreceksiniz.
# strip merhabamars
Paketi Hazırlamak
/usr/bin
dizininde çalıştırılabilir dosyamız
/usr/man/man1
dizininde programın nasıl kullanıldığını gösteren manuel dosyamız
/DEBIAN
dizininde kurulum betiklerini ve paket bilgisini içeren dosyalarımız
Oluşturmak için:
# mkdir -p paket/{DEBIAN,usr/bin, usr/man/man1,usr/share/doc/merhabamars}
Çalıştırılabilir dosyamızı paket/usr/bin
dizinine kopyalayalım:
Kullanım Kılavuzu (man)
.\" HEADER anlaminda TH
.\" merhabamars uygulamasinin birinci bolumu
.\" olusturma tarihi
.\" Surum numarasi
.TH merhabamars 1 "23.07.2021" "1.0-0" "merhabamars kullanim kilavuzu"
.\" SECTION HEADER anlaminda SH
.\" SH NAME icin merhabamars kullaniyoruz
.SH NAME
merhabamars \- "Merhaba Mars" yazisini goruntuler
.\" Komutun kullanimina dair kisa aciklama icin SYNOPSIS
.SH SYNOPSIS
$ merhabamars , komutu basarili tamamlandiginda 0 sonuc koduyla cikis yapar.
.\" Daha uzun cok satirli aciklama icin DESCRIPTION bolumu kullanilir
.SH DESCRIPTION
MerhabaMars uygulamamiz cok derin bir mevzuda calistirilmak icin hummali calismalarin sonucunda
kolerali gunlerden gecilerek hazirlanmis ve nice cadilarin yakildigi orta cag karanligindan
yeni cagin acilmasina kadar tum karanliklari aydinlatmistir.
.\" Eger uygulama secenek kabul ediyorsa burada yazilir ama bizim yok
.SH OPTIONS
Bu uygulamanin secenegi yoktur.
.\" Uygulamanin bagli oldugu diger komutlari buraya yaziyoruz. Ornek olsun diye puts komutunu yazalim
.SH SEE ALSO
puts
.SH AUTHOR
Milletimin Yildizi (o@benim.milletimin.yildizidir.parlayacak)
man
Paketi (yüklü değilse: apt install man
) ile bakalım:
Sıkıştıralım dosyamızı:
DEBIAN/control Dosyasını Hazırlayalım
Package: merhabamars
Version: 1.0.0
Section: misc
Priority: optional
Architecture: amd64
Depends: libc6
Maintainer: Cem Topkaya (cem.topkaya@hotmail.com)
Description: Marsin karanlık tarafina sert inen Turk
Debian paketleme sistemlerinin desteklediği linux mimarilerin listesini dökmek için (dpkg-architecture -L
):
dpkg’nin geliştirmede kullanılan tüm sürümlerini yüklemek için dpkg-dev
paketini kurmamız gerekir:
Lisans İçin copyright Dosyası Oluşturma
Önce lisans dosyalarının dizinlerini oluşturalım
Apache 2.0 Lisansı için sayfanın sonundaki metni kopyalayıp, copyright dosyamıza yapıştıralım:
Debian Paketini Yapılandıralım
Temel kural olarak debian paketi haline getireceğimiz dizindeki tüm dosyaları (-R
anahtarıyla) root
kullanıcısı ve root
grubunun yetkisine vermemiz gerekiyor:
# chown -R root.root paket/
Derlediğimiz paketi kurduğumzuda çalıştığını göreceğiz. which merhabamars
ile uygulamanın /usr/bin/merhabamars
yolunda olduğunu, uygulamanın kullanım kılavuzundaki açıklamasını what merhabamars
ile görebiliyoruz.
Debian Paketi ve Bağımlılıklarını İndirmek
$ apt-get --print-uris --yes install <my_package_name> | grep ^\' | cut -d\' -f2 > downloads.list$ wget --input-file downloads.list
Ref: stackoverflow
Debian Paketindeki Bağımlılık İlişkileri
İzin verilen ilişkiler sırasıyla
- << kesinlikle daha önceki,
- <= eşit veya daha önceki,
- = tam olarak bu sürüm numarasına denk,
- >= daha sonraki veya eşit,
- >> kesinlikle daha sonraki sürüm numaraları.
Bir debian paketi aşağıdaki gibi tanımlanabilir *:
Package: 0ad-data
Version: 0.0.23.1-1
Installed-Size: 2044173
Maintainer: Debian Games Team <pkg-games-devel@lists.alioth.debian.org>
Architecture: all
Pre-Depends: dpkg (>= 1.15.6~)
Suggests: 0ad
Description: Real-time strategy game of ancient warfare (data files)
Homepage: http://play0ad.com/
Description-md5: 26581e685027d5ae84824362a4ba59ee
Tag: role::app-data
Section: games
Priority: optional
Filename: pool/main/0/0ad-data/0ad-data_0.0.23.1-1_all.deb
Size: 701878080
MD5sum: 48a0f2d3af77e4cf01638e4429bddbd8
SHA256: 0fa3fb9ef1999054d041f2425b677312e4d4e7bf43ac499665f7f69a21f8b0a9
5 Farklı bağımlılık tip tanımını debian paketi içinde yapabiliriz *:
- Depends
- Recommends
- Suggests
- Enhances
- Pre-Depends
Depends (Bağımlılıklar)
Mutlak bağımlılıkları gösterir. Depends (Bağımlılar) alanında listelenen tüm paketler doğru şekilde yapılandırılmadıkça paket yapılandırılmayacaktır. Mesela bir kütüphaneyi kullanıyorsa deb paketiniz bağımlı olduğunuz kütüphane paketini depends
alanında tanımlamalıyız. postinst
ile kurulum yaptığınızda çalıştıracağınız betiği veya prerm
ile uygulamayı kaldırdığınızda çalışmasını istediğiniz betiği belirtirsiniz. Bu iki komut dosyaları çalıştığında eğer kurulması gereken ön bağımlı paketleri kullanacaksa depends
alanında bu paketler tanımlanmalıdır. Postinst
configure durumunda, bağımlı paketler önce paketten çıkarılır ve yapılandırılır. Prerm
veya diğer postinst
eylemler durumunda, paket bağımlılıkları normalde en azından paketten çıkarılır, ancak bağımlılığın önceki bir yükseltmesi başarısız olursa yalnızca “Yarı Yüklü” olabilir. Son olarak, bağımlı paketin postrm
komut dosyası tarafından paket kaldırıldıktan sonra tamamen temizlenmesi gerekiyorsa Bağımlılar alanı kullanılmalıdır. Postrm
çalıştırıldığında paket bağımlılıklarının kullanılabilir olacağına dair bir garanti yoktur, ancak bağımlı paketin bir bağımlılık bildirmesi durumunda (özellikle postrm
kaldırma durumunda) mevcut olma olasılığı daha yüksektir. Postrm
komut dosyası, bağımlılık mevcut değilse, bağımlılık gerektiren eylemleri nazikçe atlamalıdır.
Recommends (Öneriler)
Güçlü ancak mutlak olmayan bir bağımlılık ilan eder. Öneriler alanı, olağandışı kurulumlar dışında tümünde bununla birlikte bulunabilecek paketleri listelemelidir.
Suggests
Paketin bir veya daha fazla başka paket için daha yararlı olabileceğini bildirmek için kullanılır. Bu alanı kullanmak, paketleme sistemine ve kullanıcıya, listelenen paketlerin bununla ilgili olduğunu ve belki de kullanışlılığını artırabileceğini, ancak bunlar olmadan da kurulabilir.
Enhances
Bu alan Suggests (öneriler’e) benzer ancak ters yönde çalışır. Bir paketin başka bir paketin işlevselliğini geliştirebileceğini bildirmek için kullanılır.
Pre-Depends
Bu alan Depends
gibidir, ancak dpkg’yi önceden bağımlılığı bildiren paketin kurulumuna bile başlamadan önce adı geçen paketlerin kurulumunu tamamlamaya zorlaması dışında, bir ön bağımlılık bildiren bir paket yaklaşık olduğunda bu şekilde çalışır. paketten çıkarılmalı, bağımlı paket tamamen yapılandırılmışsa veya bağlı paket (ler) yalnızca paketten çıkarılmışsa veya yapılandırılmış olmaları koşuluyla “Yarı Yapılandırılmış” durumda olsa bile ön bağımlılık karşılanabilir geçmişte bir noktada doğru bir şekilde (ve o zamandan beri kaldırılmamış veya kısmen kaldırılmamış).
Depends ve Pre-Depends Farkı
depends
ve pre-depends
de esas paketin kurulumundan önce ihtiyaç duyduğu bağımlılıklardan bahseder, ancak pre-depends
, depends
içinde belirtilen paketlerden önce bağımlılık paketlerinin kurulumunu ve yapılandırmasını zorlar. dpkg, tüm pre-depends
paketler ele alınana kadar ana paketi bile açmayacaktır. Depends
ile, bağımlılık paketlerinin ve asıl paketin sırası önemli değildir. pre-depends
de tanımlı paketlerin yapılandırılıp yapılandırılmadığının, kurulup kurulmadığının doğrulanmasını dikkate alır. Bu olmadan, ana paket açılmayacak, yapılandırılmayacak veya kurulmayacaktır. Ana paketle çalışma sürecine başlamadan önce bağımlılıkların kurulu olması gerekir. pre-depends
normalde paketin kararlılığının önemli olduğu ve sistemi veya programı çok kötü bir şekilde etkilemeyeceği durumlarda kullanılır
Ağ Yığını (Network Stack)
Özetle; “fiziki ağ arayüzü” + “yönlendirme (routing)” + “IP” den oluşan yığındır. Yani OSI katmanındaki 1, 2 ve 3 katmanlarını içerir (2. katmanda ARP ve ROUTING tabloları oluşur). Linux üstünde bu katmanların bilgilerini 1 için ip link
, 2 için ip route
, 3 için ip addr
komutlarını kullanırız.
OSI Katmanları için: https://bit.ly/3dhkArC
Verinin iletimi üst katmandan alt katmana doğru olur. Diğer bilgisayarda ise önce fiziki katman ile karşılanan veri üst katmanlara doğru hareket eder.
4- Taşıma (Transport) Katmanı [data => segment]
Veri (data) halinde alınan bilgi, taşıma katmanında kesim (segment) adı verilen birimlere ayrılır. Bu şekilde veri alıcı makinede tekrar biraraya getirilirken doğru sıralanması sağlanmış olur.
3- Ağ (Network) Katmanı [segment => packet]
Ağ katmanına kesimler (segment) halinde gelen verilere bu katmanda kaynak ve hedef adres bilgileri eklenir ve kesimler pakete dönüşür (segment > packet). IPv4 olan adreslerin MAC adreslerine dönşümünde ARP kullanılırken, IPv6 adresleri “Neighbour Discovery Protocol” ile dönüştürülür *. Bu katmanda artık veriler ağlar arasında dolaşmaya hazırlanmaya başlar. Artık verimiz routerdan çıkarak istenilen cihaz adresine gönderilmek üzere paketlenir. Verinin hedef adresi. ağ içerisindeki bir cihaz adresi de olabilir ağ dışında ise, paket NAT işlemine tabi tutulur.
2- Veri Bağlantı (Data Link) Katmanı [packet => frame] *
Veri-bağlantı katmanında paketlere MAC adresleri eklenerek çerçeve (frame) adını verdiğimiz yapı oluşur.
1- Fiziki (Physical) Katman [frame=>bit array]
En son aşama olarak fiziki katmana gelen çerçeveler burada bir bit dizisine dönüştürülerek iletime hazır hale getirilir. Fiziki katman, donanım bazında verilerin CPU ile ayarlanıp internet donanımına ya da kablosuz ağ ile ilgili donanıma transferi ile ilgili protokollerle bağdaştırılır.
Ağ Arayüzlerinin Donanım Durumları
Kullanılabilir ağ arayüzlerinin donanım temelinde durumlarını görüntülemek için ip link
komutunu çalıştırırız.
lo: Linux Host Itself (Loopback arayüzü)
# Ağ Arayüzünü Etkinleştir ve Devre Dışı Bırak
$ ip link set wlan0 <up|down># Bilgisayarınıza bir IP adresi atamak/silmek için
$ ip addr <add|del> 192.168.1.8/24 dev wlan0
# veya
$ ip a <add|del> 192.168.1.8/255.255.255.0 dev wlan0# IP adresini atadıktan sonra, değişiklikleri görüntüleyin:
$ ip addr show wlan0# Yönlendirme tablonuzda ayarlandığı gibi ağınızda alacağı rota paketlerini görmek için IP komutunun route nesnesini kullanabilirsiniz. Sistemin yönlendirme tablosu bilgilerini kontrol etmek için aşağıdaki komutu çalıştırın.
$ ip route show# Varsayılan rotayı değiştirmek veya silmek için IP komutu aşağıdaki gibi kullanılabilir.
$ ip route <add|del> default via 192.168.1.1# IP komutu, çeşitli ağ arayüzlerinin istatistiklerini göstermek için de kullanılabilir. Bunu yapmak için -s seçeneğiyle IP komutunu kullanabilir ve ardından ağ cihazını belirtebilirsiniz.
$ ip -s link# Belirli bir ağ arabirimi hakkında bilgi almanız gerekiyorsa, ls seçeneğini ve ardından ağ arabiriminin adını (wlan0) ekleyin. Bu, özellikle ağ bağlantısındaki hataları giderirken çok yararlı olabilir. Bunu yapmak için aşağıdaki komutu çalıştırın:
$ ip -s link ls wlan0# Adres Çözümleme Protokolü (ARP), bir IP adresini, genellikle MAC adresi olarak bilinen ilgili fiziksel adresine çevirmek için kullanılır. ip komutu ile komşu veya komşu seçeneğini kullanarak LAN'ınıza bağlı cihazların MAC adresini görüntüleyebilirsiniz.
$ ip neighbour
Ref: https://lintut.com/how-to-use-linux-ip-command/
Ağ Arayüzlerinin IP Adresleri
Ağ arayüzlerinin adreslerini almak için ip addr
komutu çalıştırılır.
IP Adresinin bırakıp tekrar almak için (release , renew) sudo dhclient
komutu çalıştırılır.
Ağ İsim Uzayları *
Ağ isim alanı, özellikle ağ yığınını sanallaştırır. Her ağ isim alanı, ağ arabirimleri, IP adresleri, yönlendirme tabloları, tüneller, güvenlik duvarları vb. gibi kendi kaynak kümesine sahiptir. Örneğin, bir ağ isim alanına eklenen iptables kuralları yalnızca bu isim alanına giren ve çıkan trafiği etkiler.
/proc/[pid]/ns/cgroup (since Linux 4.6)
/proc/[pid]/ns/ipc (since Linux 3.0)
/proc/[pid]/ns/mnt (since Linux 3.8)
/proc/[pid]/ns/net (since Linux 3.0)
/proc/[pid]/ns/pid (since Linux 3.8)
/proc/[pid]/ns/pid_for_children (since Linux 4.12)
/proc/[pid]/ns/time (since Linux 5.6)
/proc/[pid]/ns/time_for_children (since Linux 5.6)
/proc/[pid]/ns/user (since Linux 3.8)
/proc/[pid]/ns/uts (since Linux 3.0)
Bir ağ isim uzayı içerisinde ağ yığınının tüm bileşenleri bulunur (routing, ip, fiziki ağ arayüzü vs.). Linux varsayılan olarak her prosesi “root network namespace” e atar böylece uygulamaların internete erişmesi sağlanır. Komut satırında ip link
komutunu çalıştırdığımızda “root network namespace” üstündeki ağ arayüzlerini, ip addr
komutuyla IP adreslerini görüntüleriz.
ip link
ip addr
ip route
iptables -L
netns İle Ağ Yalıtımı
3 Tip ağ yapısı kuralım:
- peer (çift) türünde
- bridge (köprü) türünde
Aşağıda okuyacaklarınız şu sırayla yapılıyor:
- Network Namespace’i tanıyalım
- Linux makinasında ağ yığınını görelim
- Linux makinasında ağ isim uzayı yaratalım ve bu uzaya ait ağ arabirimlerini görelim
- Başka bir isim uzayı yaratalım ve her 2 isim uzayına ağ arabirimi tanımlayıp,
- Bu ağ arabirimlerinin birbirilerini yani iki ağ isim uzayının iletişimini sağlayacak şekilde eşleştirelim (peer)
Bir ağ isim uzayıyla prosesin ağ erişim kaynaklarını diğerlerinden ayırabilir eriştirmeyebiliriz. Proseslerin PID bilgilerini farklı bir ağ isim uzayında çalışacak şekilde ekleyerek bu yalıtımı sağlarız.
Usage: ip netns list
ip netns add NAME
ip netns attach NAME PID
ip netns set NAME NETNSID
ip [-all] netns delete [NAME]
ip netns identify [PID]
ip netns pids NAME
ip [-all] netns exec [NAME] cmd …
ip netns monitor
ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]
NETNSID := auto | POSITIVE-INT
İsimli ve yalıtılmış ağ yaratmak için netns komutunu kullanıyoruz.
# Oluşturulmuş ağ isim uzaylarını listelemek için 2 yöntem:
# komut veya herşeyin dosya olduğu linux'te dizini listeleyerek
$ ip netns
$ ls /var/run/netns# isim uzayı eklemek
$ ip netns add web-konteyneri$ ip netns
web-konteyneri$ ls /var/run/netns
web-konteyneri
İsim uzayı içinde komut çalıştırabiliriz. Sanki bir bilgisayarın ağ arayüzlerinin durumlarını görüntüler gibi. Bu komut docker exec <konteynerID> <komut>
, kubectl exec..
komutlarına çok benziyor ip netns exec <nsAdı> <komut>
:
$ ip netns exec web-konteyneri ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default ...
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default..
link/sit 0.0.0.0 brd 0.0.0.0$ ip netns exec web-konteyneri ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT gr...
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: sit0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN mode DEFAU...
link/sit 0.0.0.0 brd 0.0.0.0
2 Ağ arabirimi oluşmuş ve DOWN durumdalar. Loopback ağ arayüzüne odaklanalım; faal görünmüyor (DOWN) ve IP almamış.
Yeni ağ isim uzayımızdaki loopback arabiriminin durumunu UP yapalım exec
komutuyla:
“Root network namespace” üstüne ağ arabirimi yaratmak için ip link add
komutunu kullanacağız. Ağ arayüzlerinin alabileceği türler:
bridge - Ethernet Bridge device
bond - Bonding device
dummy - Dummy network interface
hsr - High-availability Seamless Redundancy device
ifb - Intermediate Functional Block device
ipoib - IP over Infiniband device
macvlan - Virtual interface base on link layer address (MAC)
macvtap - Virtual interface based on link layer address (MAC) and TAP.
vcan - Virtual Controller Area Network interface
vxcan - Virtual Controller Area Network tunnel interface
veth - Virtual ethernet interface
vlan - 802.1q tagged virtual LAN interface
vxlan - Virtual eXtended LAN
ip6tnl - Virtual tunnel interface IPv4|IPv6 over IPv6
ipip - Virtual tunnel interface IPv4 over IPv4
sit - Virtual tunnel interface IPv6 over IPv4
gre - Virtual tunnel interface GRE over IPv4
gretap - Virtual L2 tunnel interface GRE over IPv4
erspan - Encapsulated Remote SPAN over GRE and IPv4
ip6gre - Virtual tunnel interface GRE over IPv6
ip6gretap - Virtual L2 tunnel interface GRE over IPv6
ip6erspan - Encapsulated Remote SPAN over GRE and IPv6
vti - Virtual tunnel interface
nlmon - Netlink monitoring device
ipvlan - Interface for L3 (IPv6/IPv4) based VLANs
ipvtap - Interface for L3 (IPv6/IPv4) based VLANs and TAP
lowpan - Interface for 6LoWPAN (IPv6) over IEEE 802.15.4 / Bluetooth
geneve - GEneric NEtwork Virtualization Encapsulation
macsec - Interface for IEEE 802.1AE MAC Security (MACsec)
vrf - Interface for L3 VRF domains
netdevsim - Interface for netdev API tests
rmnet - Qualcomm rmnet device
xfrm - Virtual xfrm interface
Linux host’a birbirleriyle eş (peer
) iki sanal ağ arayüzü (veth
) tanımlayalım:
$ man ip link # Okuma ve yazmasını kolaylaştırmak içinÖrnek komutta
- BÜYÜK HARFle yazılanları biz gireceğiz
- {.|.} süslü parantez arasında seçenekler var
- [..] köşeli parantez mecburi değil:
$ ip link add DEVICE type { veth | vxcan } [ peer name NAME ]Bizim komutumuz:
$ ip link add \
dev \ # aygıt olarak tanımla. Yazmasak da olur.
arabirimA \ # ilk ağ arayüzünün adı
type veth \ # Virtual ethernet interface türünde olacak
peer name arabirimB \ # eth0-b adında 2. ağ arayüzüyle eş olsun
Linux hostumuza iki sanal ağ yaratıp görüntüleyelim. Daha sonra bu 2 ağ arabirimini yaratacağımız network namespace ile ilişkilendirecek ve artık linux host üstünde göremeyeceğiz:
Şimdi ağ isim arayüzlerini ve onların ağ yığınlarını görüntüleyelim:
- Tanımlı ağ isim uzaylarını listele
- db-konteyneri ağ isim uzayını ekle
- Ağ isim uzaylarını 2 türlü listele
- veth Tipindeki ağları görüntüle
- arabirimA ve arabirimB
Her birinin 2 ağ arabirimi var ve
hepsinin durumu DOWN - web-konteynerinde tanımlı arayüzlerin 3 (IP), 2 (MAC) ve 1. katman (Fiziki) bilgilerini çekiyoruz.
- Aynı şekilde db-konteyneri ağ isim uzayının ağ yığın bilgilerini görüntülüyoruz.
Şimdi bir veth tipindeki arayüzü host makinadan alıp web-konteyneri
ağ isim uzayına ekleyelim.
Ağ türlerinden “sanal ağ arayüzünü” (veth
) yarattığımız ağ isim uzayına (web-konteyneri
’ne) ekleyelim
$ ip link set dev arabirimA netns web-konteyneri
$ ip link show type veth
28: arabirimB@if29: <BROADCAST,MULTICAST> mtu 1500 .. state DOWN..
link/ether 9e:01:be:d8:d4:59 brd ff:ff:ff:ff:ff:ff link-netns web-konteyneri$ ip netns exec web-konteyneri ip a
1: lo: <LOOPBACK> mtu 65536 .. state DOWN ..
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
2: sit0@NONE: <NOARP> mtu 1480 .. state DOWN ..
link/sit 0.0.0.0 brd 0.0.0.0
29: arabirimA@if28: <BROADCAST,MULTICAST> mtu..state DOWN ..link-netns db-konteyneri
Aynı akışla db-konteyneri
oluşturalım ve arabirimB
yi bu ağ isim uzayına ekleyelim:
$ ip netns add db-konteyneri
$ ip link set dev arabirimB netns db-konteyneri
$ ip addr
$ ip netns exec db-konteyneri ip addr
1: lo: <LOOPBACK>...
2: sit0@NONE: <NOARP>...
28: arabirimB@if29: <BROADCAST,MULTICAST>...-netns web-konteyneri
Şimdi IP adresi (3. katman) eklemek için ip address add <IP> dev <arayüz>
Şimdi yine MAC katmanı (ARP ve ROUTING tabloları 2. katmanın işidir) ağ yönlendirmesinden sorumludur. Bakalım routing tablosuna ip route
:
$ ip netns exec db-konteyneri ip route
10.11.12.0/24 dev arabirimB proto kernel scope link src 10.11.12.22 linkdown
Neden linkdown
görünüyor? Acaba arabirimB
arayüzü mü DOWN
? LOWERLAYERDOWN Ne demek?
$ ip netns exec db-konteyneri ip addr show type veth
28: arabirimB@if29: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
link/ether 9e:01:be:d8:d4:59 brd ff:ff:ff:ff:ff:ff link-netns web-konteyneri
inet 10.11.12.22/24 scope global arabirimB
valid_lft forever preferred_lft forever
veth
Arayüzünün karşısındaki eş (peer network) ağ arabirimi (arabirimA) DOWN
durumda olmalı ki LOWERLAYERDOWN
durumuna gelinsin. Yani eşler arasında iletişimin olması için her iki ağ arayüzünün de UP
durumda olması gerekiyor (yani elektrik 1 ağ arayüzünde var diğerinde yoksa state LOWERLAYERDOWN
olacaktır).
O halde her iki ağ isim uzayındaki ağ arabirimlerini UP hale getirip tekrar bakalım:
db-konteyneri
’nin ağ arayüzü arabirimB
UP
durumda ancak karşısındaki ağ arayüzü arabirimA
DOWN
durumda olduğu için NO-CARRIER
ve LOWERLAYERDOWN
olarak görünüyor (ayrıntı için).
$ ip netns exec db-konteyneri ip addr show type veth
28: arabirimB@if29: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
link/ether 9e:01:be:d8:d4:59 brd ff:ff:ff:ff:ff:ff link-netns web-konteyneri
inet 10.11.12.22/24 scope global arabirimB
valid_lft forever preferred_lft forever$ ip netns exec web-konteyneri ip addr show type veth
29: arabirimA@if28: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
link/ether a2:b4:61:27:7e:3b brd ff:ff:ff:ff:ff:ff link-netns db-konteyneri
Ve arabirimA
'yı UP
hale getirince elektrik siyalleşmesi başlıyor:
$ ip netns exec web-konteyneri ip link set arabirimA up$ ip netns exec web-konteyneri ip addr show type veth
29: arabirimA@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether a2:b4:61:27:7e:3b brd ff:ff:ff:ff:ff:ff link-netns db-konteyneri
inet6 fe80::a0b4:61ff:fe27:7e3b/64 scope link
valid_lft forever preferred_lft forever
Tekrar fiziki katmanlar arasına baktığımızda artık NO-CARRIER
durumunun kalktığını ve fiziki katmanda bir sinyalleşme olduğunu (LOWER_UP
) görebiliyoruz:
$ ip netns exec db-konteyneri ip addr show type veth
28: arabirimB@if29: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 9e:01:be:d8:d4:59 brd ff:ff:ff:ff:ff:ff link-netns web-konteyneri
inet 10.11.12.22/24 scope global arabirimB
valid_lft forever preferred_lft forever
inet6 fe80::9c01:beff:fed8:d459/64 scope link
valid_lft forever preferred_lft forever
LOWER_UP, fiziksel bir katman bağlantı bayrağıdır (IP’nin genellikle bulunduğu ağ katmanının altındaki katman). LOWER_UP, bir Ethernet kablosunun takılı olduğunu ve cihazın ağa bağlı olduğunu gösterir. LOWER_UP, ek olarak ağ arayüzünün etkinleştirildiğini gösteren UP’dan farklıdır.
NOT: Renklendirme için ip link | GREP_COLOR=’01;36' grep -P ‘^[[:digit:]]:’ | GREP_COLOR=’02;36' grep -P ‘<.*>’ | GREP_COLOR=’04;36' -P ‘state\s.*(?=\smode)’
Buraya kadar toplu ekran görüntüleriyle gelelim:
$ ip netns exec web-konteyneri ip address add 10.11.13.11/24 dev arabirimA
$ ip netns exec db-konteyneri ip address add 10.11.13.22/24 dev arabirimB$ for ns in "web-konteyneri" "db-konteyneri"; do echo $ns; ip netns exec $ns ip addr show type veth | head -1; done
web-konteyneri
7: arabirimA@if6: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
db-konteyneri
6: arabirimB@if7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000$ ip netns exec web-konteyneri ip link set dev arabirimA up
$ ip netns exec db-konteyneri ip link set dev arabirimB up$ for ns in "web-konteyneri" "db-konteyneri"; do echo $ns; ip netns exec $ns ip addr show type veth | head -1; done
web-konteyneri
7: arabirimA@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
db-konteyneri
6: arabirimB@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000$ ip netns exec web-konteyneri ping 10.11.13.22
PING 10.11.13.22 (10.11.13.22) 56(84) bytes of data.
64 bytes from 10.11.13.22: icmp_seq=1 ttl=64 time=0.054 ms
64 bytes from 10.11.13.22: icmp_seq=2 ttl=64 time=0.023 ms
^C
--- 10.11.13.22 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 3170ms
rtt min/avg/max/mdev = 0.023/0.033/0.054/0.012 ms$ ip netns exec db-konteyneri ping 10.11.13.11
PING 10.11.13.11 (10.11.13.11) 56(84) bytes of data.
64 bytes from 10.11.13.11: icmp_seq=1 ttl=64 time=0.037 ms
64 bytes from 10.11.13.11: icmp_seq=2 ttl=64 time=0.022 ms
^C
--- 10.11.13.11 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1054ms
rtt min/avg/max/mdev = 0.022/0.029/0.037/0.007 ms
İki ad alanı da aynı subnet mask içinde oldukları için routing yapmamız gerekmedi.
Ağ arayüzlerini silelim:
$ ip netns exec web-konteyneri ip link delete arabirimA
Peer olarak oluşturulan arabirimA
ve arabirimB
arayüzlerinden birinin silinmesiyle diğeri de otomatik silinir.
arabirimB
’nin Otomatik silindiğini görmek için:
$ ip netns exec db-konteyneri ip link
Şimdi Köprü türünde bir bağlantıyla konteynerlerimizi bağlayalım
- Switch gibi kullanacağımız bridge ağında gateway için bridge tipinde 1 ağ arayüzü,
- Ve 2 Konteyner için 1'er ağ arayüzü ancak bunların her birini bir nevi switch üstündeki portlara bağlayacağımız için yine peer olacak şekilde ayrıca 2 ağ arabirimiyle birlikte oluşturalım
$ ip link add dev kopru1 type bridge
$ ip link add dev veth-web type veth peer name veth-kopru2
$ ip link add dev veth-db type veth peer name veth-kopru3
Gateway olarak çalışacak kopru1
arayüzüne IP değeri verip UP yapalım:
$ ip address add 10.11.13.1/24 dev kopru1
$ ip link set dev kopru1 up
Şimdi sanal ağ çiftlerinin birini ağ isim alanına bağlayalım, diğerinin gateway’ini kopru1 olacak şekilde ayarlayalım
$ ip link set dev veth-web netns web-konteyneri
$ ip link set dev veth-db netns db-konteyneri
$ ip link set veth-kopru2 up
$ ip link set veth-kopru3 up
$ ip link set veth-kopru2 master kopru1
$ ip link set veth-kopru3 master kopru1$ ip netns exec web-konteyneri ip link set dev veth-web up
$ ip netns exec web-konteyneri ip address add 10.11.13.11/24 dev veth-web
$ ip netns exec web-konteyneri ip route add default via 10.11.13.1
$ ip netns exec web-konteyneri ip route$ ip netns exec db-konteyneri ip link set dev veth-db up
$ ip netns exec db-konteyneri ip address add 10.11.13.22/24 dev veth-db
$ ip netns exec db-konteyneri ip route add default via 10.11.13.1
$ ip netns exec db-konteyneri ip route
$ ip address show kopru1
12: kopru1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 0e:22:50:a3:f4:d0 brd ff:ff:ff:ff:ff:ff
inet 10.11.13.1/24 scope global kopru1
valid_lft forever preferred_lft forever
inet6 fe80::b82b:2cff:fe5e:83a4/64 scope link
valid_lft forever preferred_lft forever$ ip address show veth-kopru2
8: veth-kopru2@if9: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master kopru1 state UP group default qlen 1000
link/ether ee:14:8e:63:0a:38 brd ff:ff:ff:ff:ff:ff link-netns web-konteyneri
inet6 fe80::ec14:8eff:fe63:a38/64 scope link
valid_lft forever preferred_lft forever$ ip address show veth-kopru3
10: veth-kopru3@if11: <BROADCAST,MULTICAST> mtu 1500 qdisc noop master kopru1 state DOWN group default qlen 1000
link/ether 0e:22:50:a3:f4:d0 brd ff:ff:ff:ff:ff:ff link-netns db-konteyneri
Şimdi ping ile kontrol edelim bağlanmışlar mı diye
$ ip netns exec web-konteyneri ping 10.11.13.22 -c 2
$ ip netns exec db-konteyneri ping 10.11.13.11 -c 2