8.09.2023

Powershell ve UserAgent tanımlayıcısı

Örneğin şu şekilde Powershell'den yapılan bir web sorgusu

PS> Invoke-WebRequest -Uri "https://whatmyuseragent.com"

aynen bir web tarayıcının göndereceği gibi sunucuya, UserAgent String olarak bilinen tarayıcı bilgisi gönderir. Powershell için bu şuna benzer bir dizedir:

Mozilla/5.0 (Windows NT; Windows NT 10.0; tr-TR) WindowsPowerShell/5.1.22621.1778

Powershell 5.0 ve Türkçe Windows 10/11 bilgisayardan bağlantıyı gösteriyor. Bunu özelleştirebiliriz. Microsoft.PowerShell.Commands.PSUserAgent sınıfını kullanarak şu tarayıcıları taklit etmek mümkün:

PS> iwr -UserAgent ([Microsoft.PowerShell.Commands.PSUserAgent]::InternetExplorer) -Uri "https://whatmyuseragent.com"

Bu gibi bir komut, şu sayfadaki tabloya göre Interet Explorer 9.0 bilgisi gönderir. Sınıfın içindeki seçenekler biraz eski:

ChromeUseragent string for Chrome (7.0).
FireFoxUseragent string for Firefox (4.0).
InternetExplorerUseragent string for InternetExplorer (9.0).
OperaUseragent string for Opera (9.0).
SafariUseragent string for Safari (5.0).

Bunun dışında elbette elle seçilmiş değerler de kullanılabilir.

PS> iwr -useragent "merhaba" -uri "https://whatmyuseragent.com"


18.08.2023

Powershell yürütme işleci

Execute operator'ün Türkçesi. Şu sayfadan basit bir örnek:

PS> $mysb = {$b = 456 ; Echo $b }

PS> & $mysb

456

Benden bir örnek:

PS> $myip = {(iwr "http://whatismyip.akamai.com").Content}

PS> $myip

Yine ss64.com'dan bir örnek daha; Script Block'un içinde param koyarak bir fonksiyon gibi kullanabiliriz:

PS> $alert = { param ($message) "$message" } 

PS> & $alert -message "Merhaba"

Merhaba


17.08.2023

Powershell veri biçimlendirme

Türkçe yerel ayarları olan bir bilgisayarda Powershell kullanırken ondalık sayıları yazarken ondalık ayraç nokta "." ama ekrana bastırırken virgüldür ","

$veri = 1222333.456789 # ondalık sayı

"{0:f}"  -f $veri # 1222333,57
"{0:f3}" -f $veri # 1222333,568
"{0:e}"  -f $veri # 1,222334e+006
"{0:E}"  -f $veri # 1,222334E+006
"{0:n}"  -f $veri # 1.222.333,57

$veri = 1299.99 # para birimi

"{0:c}" -f $veri # ₺1.299,99

$veri = 1234 # tamsayı

"{0:n}"    -f $veri # 1.234,00
"{0:d8}"   -f $veri # 00001234 (sola sıfır ekler)
"{0,8:n0}" -f $veri # ___1.234 (sayıdan önce 3 boşluk olur)

$veri = 255 # 16'lık düzen

"{0:x}"  -f $veri # ff
"{0:X4}" -f $veri # 00FF

#veri = 0.25 # yüzde

"{0:p}"  -f $veri # %25,00
"{0:p1}" -f $veri # %25,0
"{0:p0}" -f $veri # %25

# veri = Get-Date # tarih

"{0:d}"  -f $veri # 17.08.2023
"{0:D}"  -f $veri # 17 Ağustos 2023 Perşembe
"{0:f}"  -f $veri # 17 Ağustos 2023 Perşembe 15:17
"{0:F}"  -f $veri # 17 Ağustos 2023 Perşembe 15:17:41
"{0:g}"  -f $veri # 17.08.2023 15:17
"{0:g}"  -f $veri #
17.08.2023 15:17:42
"{0:r}"  -f $veri # Thu, 17 Aug 2023 15:17:41 GMT
"{0:o}"  -f $veri # 2023-08-17T15:17:41.0556971+03:00
"{0:yy-MM-dd}"  -f $veri # 23-08-17

Burada

d: kısa tarih
D: uzun tarih
f: uzun tarih, kısa saat
F: uzun tarih, uzun saat
t: kısa saat
T: uzun saat
g: kısa genel tarih biçimi
G: uzun genel tarih biçimi
yy: yılın son 2 hanesi (23 gibi)
yyyy: tam yıl biçimi (2023 gibi)
M: İçinde bulunulan ay, mümkünse tek haneli sayı
MM: İçinde bulunulan ay, çift haneli (tek ise önüne sıfır ekler)
MMM: İçinde bulunulan ay, 3 karakterli kısaltma
MMMM: İçinde bulunulan ay, tam adı
d : Ayın günü, tek haneli
dd: Ayın günü, çift haneli
hh: Saat, 12 saatlik düzende
HH: Saat, 24 saatlik düzende
mm: Dakika
ss: Saniye 

Select-Object ile hesaplanmış bir alan oluşturuken bu işi kısaca formatstring ile de yapabiliriz:

PS> Get-Process | Select-Object Name, Id, @{N="VM";E={$_.VM/1MB};formatstring="N2"}

Tarih için ayrıca Get-Date ile -Format parametresi de benzer iş görür.

PS> Get-Date -Format "yyyy-MM-dd HH:mm:ss"

2023-08-17 15:17:41

Get-Date'in bir de -UFormat parametresi var:

Get-Date -UFormat %V # yılın haftasını verir (1-52)

10'luk düzende bir sayıyı 16'lık düzende görmek için yukarıdaki gibi

PS> "{0:x}" -f 252   # fc

kullanılabilir. Ama daha genel olarak bir sayıyı herhangi bir düzende yazmak için

PS> [Convert]::ToString(252,2)
11111100

kullanılabilir.

16'lık düzendeki bir sayıyı girmek için başına 0x koymak yeterli:

0xfc    # onluk düzende 252'ye karşılık gelir

Veya ikilik düzendeki bir sayıyı girmek için başına 0b koymak gerek:

0b11111100    # bu da 252

Veya şu şekilde dönüştürmek de işimize yarayabilir:

[Convert]::ToInt32("11111100",2)
252

Burada kullanılan ikinci parametre olarak 2, sayının tabanını belirtiyor. 110 gibi bir sayı ikilik tabanda da olabilir, başka bir tabanda da. Verilen sayı onaltılık tabandaysa benzer bir şekilde (başına 0x ekleyerek veya eklemeden)

[Convert]::ToInt32("40",16)
64

hatta bu değerin karakter karşılığı için

[char][Convert]::ToInt32("11111100",2)
@


kullanılabilir. Bir dosyanın içeriğini hex olarak görmek için


PS> $icerik = cat '.\file.txt' -Encoding Byte -Raw
PS> [System.BitConverter]::ToString($icerik).Replace("-","") 

Daha kolay bir yol, belki, Format-Hex kullanmak:

PS> Format-Hex -Path '.\file.txt'

Tek satırda/cümlede birden fazla veri biçimlendirme:

PS> $veri1=1199; $veri2=5231; $veri3=3199.99
PS> "ilk sayımız {0:d8}, sonraki {1:e2} ve nihayet {2:f4}" -f $veri1, $veri2, $veri3
ilk sayımız 00001199, sonrajş 5,23e+003, ve nihayet 3199,9900

Şu sayfadan güzel birkaç örnek:

PS> "|{0,-10}| |{1,10}|" -f "hello", "world"
|hello     ||     world|

PS> "{0:###-##-##}" -f 1234567
123-45-67

Sonuna 3 haneli tamsayılar eklenmiş Name001, Name002,... gibi 100 isim üretmek:

PS> 1..100 | % { 'Name{0:d3}' -f $_ }

Bir karakterin 16'lık düzendeki karşılığı

PS> '0x' + "{0:x}" -f [int][char]'A'
0x41



3.08.2023

Windows'da dosya ve klasörlerin son değiştirme zamanlarını değiştirmek

NTFS dosya sistemi her dosya ve klasör için 3 farklı zaman bilgisi saklar; oluşturma, son değiştirme ve erişim.

PS> dir file1.txt | select Name, CreationTime, LastWriteTime, LastAccessTime

Name      CreationTime        LastWriteTime       LastAccessTime
----      ------------        -------------       --------------
file1.txt 2023-07-31 08:01:00 2023-08-01 14:05:00 2023-08-03 11:55:48

Bu tarihlerden herhangi birini değiştirmek için şöyle bir kullanım yeterli:

PS> (dir file1.txt).CreationTime=("1999-12-31 23:59:00")
PS> (dir file1.txt).LastWriteTime=("1999-12-31 23:59:00")
PS> (dir file1.txt).LastAccessTime=("1999-12-31 23:59:00")

Hatta bir klasördeki tüm dosyaların zamanlarını değitirmek için

$files =  Get-ChildItem -force | Where-Object {! $_.PSIsContainer}
foreach($object in $files)
{
     $object.CreationTime=("10 November 2016 12:00:00")
}

önerilmiş.

31.07.2023

Linux'ta güncellemeleri otomatik denetlemeyi iptal etmek

Genellikle linux bilgisayarlarda ilk yaptığım, açılışta güncellemeleri kontrol etmek olur. Ama ben bunu yaparken zamanlanmış görevlerden biri de aynı işlemi yapıyor olur. Bu durumda önce devam eden görevin bitmesini beklemem gerekir. Ben kullandığım bilgisayarlarda otomatik güncelleme denetlemesini faydalı bulmadığım için devre dışı bırakmak istiyorum. Fedora GNOME için bu:

sudo systemctl disable dnf-makecache.timer
sudo systemctl disable dnf-makecache.service
sudo systemctl disable packagekit

komutlarıyla mümkün. Ubuntu GNOME için ise bunlara ek olarak

sudo systemctl disable apt-daily.timer
sudo systemctl disable apt-daily-upgrade.timer
sudo systemctl disable apt-daily.service
sudo systemctl disable apt-daily-upgrade.service

yapılması ve /etc/apt/apt.conf.d/20auto-upgrades dosyasının ilk satırındaki

APT::Periodic::Update-Package-Lists "1";

satırının sonundaki 1'in 0 yapılarak şu hale getirilmesi gerekiyor:

APT::Periodic::Update-Package-Lists "0";

systemctl disable işlemine ek olarak systemctl stop işlemleri de mevcut oturum için gerekli olabilir. Seçimlik.

Fedora XFCE için ise dnfdragora'nın her açılışta sistem tepsisinde görünmesini ve bildirimler vermesini engellemek için /etc/xdg/autostart konumundaki ilgili dosyanın etkisiz hale getirilmesi (silinerek, başka yere taşınarak veya dosyanın düzenlenmesi aracılığıyla) gerekiyor.

17.07.2023

LVM - LV genişletme

Bir RockyLinux sunucum vardı. Varsayılan kurulumda disk bölümlendirmesini bırakarak gitmenin cezasını 1 TB'lık bir diskte 900 GB home bölümü ve 70 GB'lık bir root bölümü oluşturması şeklinde ödedim. Root doldu. Home'u küçültüp, root'a yer açmak gerek. Ama bütün Redhat, CentOS ve RockyLinux kurulumlarında varsayılan dosya sistemi XFS olduğu için ve XFS de küçültme işlemini desteklemediği için bu disk bölümünü silip tekrar oluşturmak zorundayım. Bu amaçla sanal makineyi ISO disk kalıbı ile açmak (ilk ekranda "Troubleshooting", sonra "Rescue a Rocky Linux system", sonrasında da 3'e basarak "Skip to shell" diyerek) bir seçenek. Ama LVM ve XFS üzerinde çalışırken diski unmount etmemize gerek yok. /home disk bölümü içine erişen bir uygulama yoksa (ya da onu geçici olarak durdurabiliyorsak) sunucuyu root ile açıp işlemlerimize devam edebiliriz.

Başlamadan önce sunucumuzda xfsdump ve xfsprogs paketlerinin yüklü olduğunu doğrulamak gerek:

# dnf list installed xfsdump xfsprogs

Her şeyin durumunu görebilmek için mevcut volume gruop (VG) yapısını listeleyerek başlayalım:

# vgs

VG        #PV        #LV        #SN    VSize        VFree
rl        1            3          0    <1022.41G    0

Bundan sonra da mantıksal bölümleri (logical volume, LV) inceleyelim:

# lvs
LV      VG    LSize
home    rl    948.46g
root    rl     70.00g
swap    rl     <3.95g

İlk iş, home'un yedeğini almak. Bunun için xfs araçlarından xfsdump ve xfsrestore'u kullanabiliriz. Bu aşamada /home mount edilmiş olmalı.

# mkdir /backup

# xfsdump -l 0 -f /backup/home_backup.dump /home

Sonrasında .dump dosyasının durumunu kontrol etmek için

# ls -lh

# xfsdump -I

# xfsrestore -t -f /backup/home_backup.dump

kullanılabilir. Bu aşamada artık /dev/rl/home'u silip yeniden oluşturabiliriz. Silmeden önce unmount etmeliyiz.

# umount /home

Eğer /home bağlantı noktasının meşgul olduğuna dair bir hata ile karşılaşırsak lsof /home ile bakabilir, PID'leri kontrol ettikten sonra kill -9 <PID> ile sonlandırıp tekrar unmount etmeyi deneyebiliriz.

Şimdi home mantıksal bölümünü silebiliriz:

# lvremove /dev/rl/home

home'u sildikten sonra VG içinde boş yer açılmış olmalı:

# vgs
VG    #PV    #LV    #SN    VSize        VFree
rl    1        2      0    1022.41g    948.46g

#LV bir azaldı, VFree alanı da sildiğimiz mantıksal bölüm boyutunca arttı. Şimdi tekrar, daha küçük bir home mantıksal birimi oluşturalım. 20G yeter de artar bile.

# lvcreate -L 20G -n home rl

Bu komut sonunda

WARNING: xfs signature detected on /dev/rl/home at offset 0 Wipe it? [y/n]:

gibi bir uyarı verdi. Oluşturduğumuz yerde eski bir xfs bölümü kalıntısı bulmuş. Bu bilgiyi kullanabileceğim bir yer bulamadım. Sanıyorum veri kurtarma teknikleri ile yanlışlıkla silinmiş bir mantıksal bölümü geri getirmek için. Bizim amacımız bu değil; y'ye basarak işleme devam edebiliriz. Sonrasında sırasıyla yeni oluşturulan bölümü biçimlendirip, mount edip, yedekten geri yükleyeceğiz:

# mkfs.xfs /dev/rl/home

# mount /dev/rl/home /home

# xfsrestore -f /backup/home_backup.dump /home

Bu sayede çok ilginç bir şey daha öğrendim; eğer bir sunucu için /home klasörü ve içindekiler, bir kişisel bilgisayarın /home klasörüne kıyasla daha vazgeçilebilir ise veya yedeklemeyi unuttuysak /home klasörümüzü ve diğer birkaç varsayılan dosyayı yaratmak için şurada bahsedildiği gibi aşağıdaki komutu kullanabiliriz:

# mkhomedir_helper kullanici_adi

Nihayet /dev/rl/root mantıksal birimini genişletebiliriz. Önce mevcut VG'deki boş yeri kontrol edelim:

# vgs

VG    #PV    #LV    #SN    VSize        VFree
rl    1        3      0    1022.41g    928.46g

Evet, 928 GB yer hala mevcut. root mantıksal birimini VG içindeki tüm boş alanı kapsayacak şekilde (-l +100%FREE) genişletelim:

# lvextend -l +100%FREE /dev/rl/root

LV'nin genişlediğini doğrulayalım:

# vgs

VG    #PV    #LV    #SN    VSize        VFree
rl    1        3      0    1022.41g        0

ve

# lvs 

LV      VG    LSize
home    rl     20.00g
root    rl    998.46g
swap    rl     <3.95g

LV genişledi, ama içindeki xfs dosya sisteminin boyutu hala eski boyutlarında:

#df -hT

Filesystem           Type  Size   Used    Avail  Use%    Mounted on
/dev/mapper/rl-root  xfs   70G    50G    20G     72%     /
/dev/mapper/rl-home  xfs   20G    176M   20G      1%     /home
/dev/sda1            vfat  599M    7.0M  592M     2%     /boot/efi
/dev/sda2            xfs  1014M   316M   699M    32%     /boot


Sıra root mantıksal biriminin içindeki xfs dosya sistemini genişletmeye geldi:

# xfs_growfs /dev/rl/root

Nihayet o da genişledi

# df -hT

Filesystem           Type    Size    Used   Avail  Use%   Mounted on
/dev/mapper/rl-root  xfs     999G    57G    942G    72%   /

Eğer herşey tamamsa /backup/home_backup.dump'ı silebiliriz.

10.07.2023

chrony

Yerel ağda çevrimdışı çalışan linux çalışan bir makinede zaman eşitleme sorunu olduğunu farkettim. Yerel ağımızdaki tüm Windows bilgisayalarlar, zaman eşitlemesi için etki alanı sunucumuzu kullanıyorlar. Ama linux makine için bu yapılandırma atlanmış.

Önce timedatectl ile mevcut zaman eşitlemesi yapılandırmasını kontrol ettim:

# timedatectl

               Local time: Pzt 2023-07-10 08:38:03 +03
           Universal time: Pzt 2023-07-10 05:38:03 UTC
                 RTC time: Pzt 2023-07-10 05:38:03
                Time zone: Europe/Istanbul (+03, +0300)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no

Zaman dilimi bilgisi doğru ve NTP eşitlemesi etkin gözüküyor. Zaman eşitleme alt bileşeni olarak ntpd, systemd-timesyncd veya chronyd kullanılıyor olabilir. systemctl status ile var olan hizmetlere baktım, sadece chronyd'nin aktif olduğunu gördüm. chrony'nin yapılandırma dosyası /etc/chronyd.conf'u açtıım

# vim /etc/chronyd.conf

Tek yaptığım ilk satırda pool direktifinin yanında yer alan eski NTP sunucusu 2.fedora.pool.ntp.org'u kaldırıp yerine yerel ağdaki sunucumun IP adresini girdim. Aslında pool kullanıldığı için yanına da ekleyebilirdim ama cihaz çoğunlukla çevrimdışı çalışacağından gerek görmedim. Daha sonra chronyd hizmetini yeniden başlattım:

# systemctl restart chronyd.service

chrony yerine ntp kurulu olsaydı onun yapılandırma dosyası da /etc/ntp.conf olacaktı. systemd-timesyncd için de yapılandırma dosyası /etc/systemd/systemd-timesyncd.conf olurdu.

Hizmetin tekrar başlatılması sonucunda zaman eşitlemesi yapılacak. Ben tcpdump ile durumu takip etmek istedim:

# tcpdump udp port 123 -i eth0

Buna alternatif olarak chronyc komut dosyası ile durumu takip edebilirim:

# chronyc sources

# chronyc tracking

Ek 2024-03-20: Alternatif bir zaman senkronizasyonu bileşeni kullanmak için chronyd hizmetini durdurup diğer hizmeti devreye almak yeterli olurdu. Örneğin systemd ile gelen timesyncd hizmetini kullanmak için aşağıdaki komutları çalıştırıp

# systemctl disable chronyd

# systemctl stop chronyd

# systemctl enable systemd-timesyncd

# systemctl start systemd-timesyncd

Sonrasında timesyncd hizmetinin /etc/systemd/timesyncd.conf konumundaki yapılandırma dosyasına bir göz atmak faydalı olurdu. Örneğin referans zaman sunucusu ile yerel saat arasında farkın çok fazla olması sebebiyle zaman eşitlenemezse journal loglarına 

Server has too large root distance. Disconnecting.

mesajı düşebilir. Bu durumda söz konusu yapılandırma dosyasındaki 

RootDistanceMaxSec

değerini saniye cinsinden aradaki farktan büyük bir değere eşitlemek gerekirdi.

---

[1] https://www.redhat.com/sysadmin/chrony-time-services-linux

[2] https://www.golinuxcloud.com/configure-chrony-ntp-server-client-force-sync/