28.12.2022

bind-chroot veya named-chroot

Bind DNS sunucusu kurmak için normal şartlar altında bind paketine ihtiyacımız var. Debian/Ubuntu için /etc/bind/ altındaki yapılandırmaları tamamlayıp zone dosyalarını da uygun yere (örneğin /etc/bind/zones) [Fedora/CentOS için ise /etc/named.conf dosyasını yapılandırıp /var/named/ altına zone dosyalarımızı] ekledikten sonra named-checkconf ve named-checkzone (bind-utils paketi ile gelen) ile yapılandırmaları kontrol edip

$ named-checkconf /etc/bind/named.conf.local

$ named-checkzone ozmener.net /etc/bind/zone/ozmener.net.db

named hizmetini başlattıktan sonra DNS sunucumuz hazır. Çalıştığından emin olmak için host, dig ve nslookup kullanabiliriz.

Ama her an internete bağlı bir DNS sunucusunun güvenliği ile ilgili endişe edenler için farklı bir seçenek daha var; bind-chroot. DNS hizmetini veren sürecin yetkilerini kısıtlayarak dosya sistemindeki erişimini bir chroot ortamı ile kısıtlamaya yarayan özel bir yapılandırma.

Fedora üzerinden işlem yaptığımızı varsayarsak öncelikle sisteme bind-chroot'u kurmamız gerek.

$ sudo dnf install bind-chroot bind-utils

bind'ı kurduktan sonra sistemdeki bütün isimleri named olacak. Alan adlarımızı chroot olmayan bind içinde çalışır hale getirdikten sonra öncelikle bu hizmeti durdurup devre dışı bırakalım.

$ sudo systemctl stop named

$ sudo systemctl disable named

Bu aşamada hem named hem de named-chroot hizmetleri devre dışı olmalı. Şimdi chroot ortamımızı hazırlayalım (bu adım öncesinde /var/named/chroot/ altında sadece named pki klasörleri olmalı).

$ /usr/libexec/setup-named-chroot.sh /var/named/chroot/ on

Bu adımdan sonra /etc/named.conf dosyasına /var/named/chroot/etc/named.conf yolundan, /var/named/forward.zone dosyasına ise /var/named/chroot/var/named/forward.zone yolundan erişeceğiz.

Bundan sonra named-chroot hizmetini başlatıp etkinleştirebiliriz.

$ sudo systemctl start named-chroot

$ sudo systemctl enable named-chroot

Güvenlik duvarımız etkindi. DNS için yeni kural ekleyep ayarları uygulayalım:

$ sudo firewall-cmd --permanent --add-service=dns

$ sudo firewall-cmd --reload

İşlem tamam.

---

Linux Bind kurulumu

9.12.2022

Powershell ile Windows'da IPv6'yı devre dışı bırakmak

Grafik arayüzden yapmak da bir yöntem ama Powershell varken Powershell'den yapmak lazım.

Bilgisayardaki ağ adaptörleri ile ilişkilendirilen birkaç "bileşen" var, aşağıdaki resimde görülebileceği gibi.

Grafik arayüz yöntemi ile yukarıdaki "İnternet Protokolü Sürüm 6 (TCP/IPv6)" öğesinin solundaki seçimi kaldırmak yeterli. Bunu powershell ile yapmak için önce Get-NetAdapterBinding cmdlet'ini kullanabiliriz. Bunun sonucunda bilgisayardaki tüm ağ adaptörleri (kablolu, kablosuz, sanal, Docker, VPN vs.)  ile ilişkilendirilen bütün bileşenlerin listesi gelir. Bunların içinden sadece konumuz ile ilgili olarak IPv6'ları görmek için -ComponentID argumanı ile birlikte ms_tcpip6 kimliğini kullanmalıyız.

PS> Get-NetAdapterBinding -ComponentID ms_tcpip6

Bunun sonucunda da bütün ağ adaptörlerinin IPv6 eşleştirmesi gelir. Amacımız bütün ağ adaptörlerinin IPv6 bileşeni ilişkisini kesmekse doğrudan bu komutun çıktısını Disable-NetAdapterBinding cmdlet'ine gönderebiliriz.

PS> Get-NetAdapterBinding -ComponentID ms_tcpip6 | Disable-NetAdapterBinding

Ama amacımız sadece, örneğin kablolu bağlantının (diyelim ki Ethernet) ilişkisini kesmek ise 

PS> Get-NetAdapterBinding -ComponentID ms_tcpip6 -Name Ethernet | Disable-NetAdapterBinding

kullanabiliriz. Daha kısa olsun, diye Get-NetAdapterBinding'i atlayıp direk bağlantıyı kesen cmdlet olan Disable-NetAdapterBinding'i de kullanabiliriz.

PS>Disable-NetAdapterBinding -ComponentID ms_tcpip6 -Name Ethernet

ama önce Get-NetAdapterBinding kullanmak işlemi hangi adaptör ve bileşenler üzerinde yaptığımızdan emin olmamızı sağlar.

2023-01-13 Ek: Farkettim ki ağ arayüzündeki ilişkileri kaldırmak IPv6'yı tamamen devre dışı bırakmıyormuş. Tamamen devre dışı bırakmak için şurada (Microsoft Exchange CSSRhoderic Milne blog) yazıldığı gibi HKLM\System\CurrentControlSet\Services\Tcpipv6\Parameters altına DWord olarak DisabledComponents değerini oluşturmak ve değerini Hex olarak FF (veya onluk düzende 255) vermek gerek.

PS> New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Tcpip6\Parameters" -Name "DisabledComponent" -Value 255 

Anahtarımız Local Machine olduğu için yukarıdaki satırı yaratmak için powershell terminalini yönetici yetkileriyle açmamız gerekecek. Ayrıca bu işlemlerden sonra bilgisayarı yeniden başlatmak da gerek.

26.11.2022

fedora-repos-archive

Bilgisayarımda bir sorun var. dnf update ile yaptığım güncellemelerin bazılarında işlem yarıda kalıyor, oturum kapanıyor ve kaldığı yerden devam ettiremiyorum. dnf history undo ve dnf history rollback kullanmayı denedim ama DNF <paket-adi> bulunamadı gibi bir hata verdi.

Şu adreste buldum ki fedora-repos-archive deposunu etkinleştirince bu hatalardan kurtulabiliyorum.

Önce fedora-repos-archive'i kuralım:

# sudo dnf install fedora-repos-archive

arkasından

# sudo dnf history undo 17

gibi bir işlemle 17. işlemi geri alabilir, ya da 

# sudo dnf history rollback 16

gibi bir işlemle sorunlu işlem olan 17'den önceki duruma dönebiliriz. Ama --allowerasing veya --skip-broken anahtarlarını kullanmak da gerekebilir.

İşimiz bittikten sonra /etc/yum.repos.d/fedora-updates-archive.repo dosyasındaki

enabled=1

satırını

enabled=0

olarak değiştirmek, bundan sonra dnf update sırasında fedora-repos-archive'i atlayarak güncelleme işlemlerini hızlandıracaktır.

3.11.2022

Powershell muhtelif konular

woshub.com sitesinde bulduğum birkaç güzel powershell bilgisini paylaşmak istedim.

SMB paylaşımları

Birincisi SMB sunucu ve istemcilerle uğraşmak için.

Örneğin bir dosya sunucumuz var. Bu sunucunun yapılandırma bilgilerini görmek için

PS> Get-SmbServerConfiguration

komutunu kullanabiliriz. Burada yazan parametreleri değiştirmek için, örneğin SMBv1'i kapatmak için

PS> Set-SmbServerConfiguration -EnableSMB1Protocol $false -Force

kullanabiliriz. Paylaşılan klasörleri görmek için

PS> Get-SMBShare

paylaşımlardan birini kaldırmak için

PS> Remove-SMBShare paylasim

ve hatta paylaşımda olan açık dosyaları görmek için

PS> Get-SmbOpenFile

kullanabiliriz. Bir istemcide bağlanılmış ağ sürücüleri var mı diye bakmak için

PS> Get-SmbMapping

Yeni bir ağ sürücüsü oluşturmak için, örneğin SUNUCU üzerinde paylaşılan DOSYALAR paylaşımını Z: sürücüsü olarak bir istemciye bağlamak için

PS> New-SmbMapping -Localpath Z: -RemotePath \\SUNUCU\DOSYALAR -Username <kullanici.adi> -Password ***** -Persistent $true -SaveCredential

kullanabiliriz.

Güvenlik Duvarı

Güvenlik duvarını powershell ile yönetmek için de güzel bilgiler var. Örneğin önce hangi ağ profilinde olduğumuzu, ve bu profile göre firewall durumumuzu inceleyelim:

PS> Get-NetConnectionProfile

Burada bilgisayarımızdaki tüm ağ cihazları için (kablolu/kablosuz vs) bilgiler görüntülenir. Bunların içinden bizim hedefimiz olan ağ arayüzüne bakıp "name" alanını kaydedelim. Benim bilgisayarımda Public çıktı. Bundan sonra da firewall'da Public profiline bakalım:

PS> Get-NetFirewallProfile -Name Public

Enabled olarak True görüyorsak bu profilde güvenlik duvarımız etkindir. Değilse etkinleştirmek için

PS> Set-NetFirewallProfile -All -Enabled True

ile bütün profilleri etkinleştirebiliriz.

Varsayılan öyledir ama bir sebeple değişmişse bilgisayarımdaki gelen trafik için herhangi bir kurala uymayan paketleri engellemeyi yaplandıralım:

PS> Set-NetFirewallProfile –Name Public –DefaultInboundAction Block

Uzak masaüstü bağlantısını etkinleştirebilmek için ilgili kural grubunu etkinleştirelim:

PS> Enable-NetFirewallRule -DisplayGroup "Uzak Masaüstü"

Bu kural grubuna dahil olan kuralları görüntülemek için

PS> Get-NetFirewallRule -DisplayGroup "Uzak Masaüstü" | select Name

yazdığımda benim makinemde 3 kural geldi.

Name
----
RemoteDesktop-UserMode-In-TCP
RemoteDesktop-UserMode-In-UDP
RemoteDesktop-Shadow-In-TCP

Grubu etkinleştirdiğimizde 3'ünü de etkinleştirmiş olduk. Bu kuralların eylemleri "İzin ver". Yani bu kurallar gelen trafiğe izin vermek için yaratılıyorlar. Var olmalarının sebebi engellemek değil, izin vermek.

Varsayılan olarak güvenlik duvarı log tutmaz. Engellenen bağlantılar için log tutmayı etkinleştirmek için

PS> Set-NetFireWallProfile -Profile Domain -LogBlocked True -LogMaxSize 20000
        -LogFileName ‘%systemroot%\system32\LogFiles\Firewall\pfirewall.log’

yapabilir, yeni bir kural yaratmak için ise

PS> New-NetFirewallRule -DisplayName 'HTTP-Inbound' -Profile @('Domain', 'Private')
        -Direction Inbound -Action Allow -Protocol TCP -LocalPort @('80', '443')

gibi bir yazım kullanabiliriz.

Var olan bir kuralı değiştirmek için ise Set-NetFirewallRule kullanabiliriz. Örneğin RemoteDesktop-UserMode-In-UDP kuralını devre dışı bırakmak için

PS> Set-NetFirewallRule -Name RemoteDesktop-UserMode-In-UDP -Enabled False

yapmak yeterli. Protokole veya port numarasına göre kural aramak için Get-NetFirewallPortFilter kullanılabilir. Örneğin

PS> Get-NetFirewallPortFilter | where {$_.LocalPort -eq 3389} | ft -Autosize

İle yerel port numarasında 3389 yazan (hem TCP hem UDP) tanımlar gelir. Ama bunlar kural mı, hayır. Kurallarla ilişkisi ne? InstanceID paramteresi ile. Get-NetFirewallPortFilter'ın döndüğü InstanceID parametresini kullanarak kurallar içinde arama yapabiliriz.

PS> Get-NetFirewallRule | where {$_.InstanceID -eq "RemoteDesktop-UserMode-In-UDP"}

Benzer şekilde 

Get-NetFirewallAddressFilter

Get-NetFirewallServiceFilter

Get-NetFirewallApplicationFilter

gibi cmdlet'ler de var.

Tekrarlanan dosyaları bulmak

Her duruma karşılaşılabilecek bir konu da tekrarlanan dosyalar. Bunları bulmak ve temizlemek için bir sürü başka program var elbet, ama powershell ile yapmak başka bir güzel. Bir hedef klasörümüz olsun; örneğin D:\dosyalar gibi. Bu klasörün altındaki diğer alt klasörlerdeki tekrarlanan dosyaları bulmaya çalışalım. Bir dosyanın başka bir dosya ile birebir aynı olduğunu anlamak için dosya özeti (file hash) hesaplamasını kullanabiliriz. Daha sonra da aynı özete sahip dosyaları süzerek sonuçları görebiliriz. Bu işin adımlarını inceleyelim. Önce D:\dosyalar klasörünün altındaki bütün dosyaları listeleyelim:

PS> Get-ChildItem -Path D:\dosyalar -Recursive

Daha sonra bütün dosyaların özetlerini hesaplayalım.

PS> Get-ChildItem -Path D:\dosyalar -Recursive | Get-FileHash

Benzersiz kopyaları değil, sadece tekrarlanan dosyaları listeleyelim. Bunun için Group-Object ile aynı özete sahip hesaplamaları gruplayıp sadece grupta 1'den fazla olan kayıtları görüntüleyelim.

PS> Get-ChildItem -Path D:\dosyalar -Recursive | Get-FileHash | Group-Object -Property hash | Where-Object {$_.count -gt 1} | Foreach-Object {$_.group | Select-Object Path, Hash}

Bu şekilde sadece tekrarlanan dosyaları listeyeleyebildik. Eğer D:\dosyalar klasöründa boyutu 50 MB'tan büyük çok sayıda dosya varsa bu yöntem uzun sürebilir, zira varsayılan SHA256 özetini hesaplamak için yoğun işlem gücü gerek. Bu konu bir iyileştirme önce dosya boyutunu karşılaştırıp sadece aynı boyuta sahip dosyalar için dosya özeti hesaplamaya giderek yapılabilir:

PS> Get-ChildItem -Path D:\dosyalar -Recursive | Group-Object -Property Length | Where-Object {$_.Count -gt 1} | Select-Object -Expand Group | Get-FileHash | Group-Object -Property hash | Where-Object {$_.count -gt 1} | Foreach-Object {$_.group | Select-Object Path, Hash}

Bunun sonucunda çok sayıda tekrarlayan dosya dönüyorsa bunları listenin içinden seçip tam yolunu kopyalayıp silmek zor olabilir. Onun için bu komutun çıktısını Out-GridView'a yönlendirmek, orada çoklu seçimi etkinleştirerek, seçilenleri de silmek önerilmiş. Silme işlemi için -WhatIf kullanılmış, güvenlik gereği. Gerçekten silmek için onu kaldırmak gerek. Tekrar aynı şeyi yazmayayım; yukarıdaki komutun çıktısını $tekrarlanan değişkenine atadığımızı varsayalım.

PS>  $tekrarlanan | Out-Gridview -Title "Silinecek dosyalari secin" -OutputMode Multiple | Remove-Item -Verbose -WhatIf

Sayfada -OutputMode ile -PassThru aynı anda kullanılmış; bu hataya sebep olduğu için ben çıkardım.


18.10.2022

Powershel ile ağ ayarlarını değiştirme

Ağ adresi yapılandırmasını powershell ile yapmaya alışamadım. Çok komut var, hangisi ne iş yapıyor bir türlü kafamda oturtamadım. Grafik arayüze ihtiyaç duymadan IP adresini powershell ile girme yolundaki çabalarımından birini daha paylaşıyorum.

Öncelikle bilgisayarımızda hangi ağ kartları var, bir bakalım.

PS> Get-NetAdapter

Name      InterfaceDescription                       ifIndex Status MacAddress        LinkSpeed
----      --------------------                       ------- ------ ----------        ---------
Ethernet0 Intel(R) 82574L Gigabit Network Connection      10 Up     xx-xx-xx-xx-xx-xx    1 Gbps

Buradan aklımızda kalması gereken, hedef ağ arayüzümüzün endeksi 10. Bunun yerine Get-NetIPInterface'i de kullanabiliriz.

DOS komutu ipconfig'e benzeyen bir komut ise Get-NetIPConfiguration. Bu cmdlet'i -Detailed parametresi ile de kullanmak isteyebiliriz. Bu durumda şöyle bir ayrıntılı çıktı üretir:

ComputerName                          : DESKTOP-6HMFMLR
InterfaceAlias                        : Ethernet0
InterfaceIndex                        : 10
InterfaceDescription                  : Intel(R) 82574L Gigabit Network Connection
NetCompartment.CompartmentId          : 1
NetCompartment.CompartmentDescription : Default Compartment
NetAdapter.LinkLayerAddress           : XX-XX-XX-
XX-XX-XX
NetAdapter.Status                     : Up
NetProfile.Name                       : Ağ
NetProfile.NetworkCategory            : Public
NetProfile.IPv6Connectivity           : NoTraffic
NetProfile.IPv4Connectivity           : Internet
IPv6LinkLocalAddress                  : fe80::458e:8efe:1c9c:c32f%10
IPv4Address                           : 192.168.239.134
IPv6DefaultGateway                    :
IPv4DefaultGateway                    : 192.168.239.2
NetIPv6Interface.NlMTU                : 1500
NetIPv4Interface.NlMTU                : 1500
NetIPv6Interface.DHCP                 : Enabled
NetIPv4Interface.DHCP                 : Enabled
DNSServer                             : 192.168.239.2

Burada büyük bir eksik var: DHCP adresi. Bazen bu çok gerekli olabiliyor. Bunu öğrenmek için WMI/CIM sorgularına ihtiyacımız var:

PS> Get-CimInstance Win32_NetworkAdapterConfiguration -Filter "DHCPEnabled=$true" | Select DHCPServer

Get-NetIPAddress ile TCP ayarlarımızı görüntüleyebiliyoruz. Bilgisayarımızda birden fazla ağ arayüzü (kablolu, kablosuz vs) varsa ve birden fazla IP sürümü (IPv4 ve IPv6)  varsa ve hatta birden fazla IP ataması yapılmışsa liste modunda uzun bir liste çıkar karşımıza. Liste değil de tablo şeklinde yazmak, biraz da alan kısıtlaması yapmak için

PS> Get-NetIPAddress | ft ifIndex, IPAddress, InterfaceAlias, PrefixLength, PrefixOrigin

kullanabiliriz.

Bu adımdan önce bilgisayarımızdaki ağ arayüzlerinin listesini görmek için Get-NetAdapter kullanabiliriz.

Birince senaryomuzda ağ kartımızda DHCP seçili olsun. Yani IP adresimizi bir çeşit sunucudan alıyoruz. Bu durumda yukarıdaki komut şuna benzer bir çıktı üretir:

ifIndex ifAlias IPAddress                    PrefixLength PrefixOrigin
------- ------- ---------                    ------------ ------------
     10         fe80::458e:8efe:1c9c:c32f%10           64    WellKnown
      1         ::1                                   128    WellKnown
     10         192.168.239.134                        24         Dhcp
      1         127.0.0.1                               8    WellKnown

İlk satır, ethernet kartımızın IPv6 kaydı. Altındaki IPv6 için looopback adresi. Üçüncü satır ağımızdaki DHCP sistemi tarafından bize ataması yapılan C sınıfı ağ adresini kullanan ethernet kartımıza ait kayıt. En sondaki de IPv4 loopback kaydımız. Prefix length altağ maskesi (subnet mask). CIDR notasyonu; burada prefix'in 24 olması, altağ maskesinin 255.255.255.0 demek. En son sütunda görüldüğü gibi bu adresi ağımızdaki DHCP bize vermiş.

Ağ kartımızı DHCP'den vazgeçip elle IP adresi ataması yapmaya karar verirsek Set ile başlayan bir cmdlet kullanmadan önce New-NetIPAddress kullanmalıyız:

PS> New-NetIPAddress -ifIndex -10 -IPAddress 192.168.77.7 -PrefixLength 24 -DefaultGateway 192.168.77.2

Burada IP adresimiz, prefix uzunluğumuzu (altağ maskesi) ve varsayılan ağ geçicimizi (default gateway) belirttik. DNS sunucu bilgisi kaldı. Onu da Set-DNSClientServerAddress ile yapacağız.

PS> Set-DNSClientServerAddress -Server 192.168.7.2, 192.168.7.3 -InterfaceIndex 10

Eğer amacımız varolan bir DNS sunucu girişini silmek olsaydı

PS> Set-DNSClientServerAddress -InterfaceIndex 10 -ResetServerAddress

kullanabilirdik. Bu da ikinci senaryomuz; IP adresi ataması yapılmış bir ağ arayüzünün yapılandırmasını görmek için tekrar Get-NetIPAddress cmdlet'ini çalıştıralım:

Get-NetIPAddress | ft ifIndex, IPAddress, InterfaceAlias, PrefixLength, PrefixOrigin

ifIndex IPAddress                    InterfaceAlias              PrefixLength PrefixOrigin
------- ---------                    --------------              ------------ ------------
     10 fe80::458e:8efe:1c9c:c32f%10 Ethernet0                             64    WellKnown
      1 ::1                          Loopback Pseudo-Interface 1          128    WellKnown
     10 192.168.77.7                 Ethernet0                             24       Manual
      1 127.0.0.1                    Loopback Pseudo-Interface 1            8    WellKnown

Görüldüğü gibi elle atadığımız IP adresinin yanında artık "Dhcp" değil, "Manual" yazıyor.

Bu aşamadan sonra eğer varolan atamayla ilgili bir değişiklik yapacaksak Set-NetIPAddress cmdlet'ini kullanabiliriz. Örneğin PrefixLength'i değiştirmek için

PS> Set-NetIPAddress -ifIndex 10 -IPAddress 192.168.77.7 -PrefixLength 16

yapabiliriz. Ama varolan IP adresini değiştirmek mümkün değil. Bunun için varolan atamayı Remove-NetIPAddress kullanarak silmek, daha sonra yine Net-NetIPAddress kullanarak yeniden bir atama yapmak gerek. Var olan IP atamasını silmek için

PS> Remove-NetIPAddress -IPAddress 192.168.77.7

Şu şekilde de olabilirdi:

PS> Get-NetIPAddress -IPAddress 192.168.77.7 | Remove-NetIPAddress

Şu ağ arayüzümüzün üzerindeki IP adresi ataması silindi, ama varsayılan ağ geçidi bilgisi hala duruyor. Onu da silmek için:

PS> Get-NetIPAddress -ifIndex 10 | Remove-NetRoute

Bu durumdan sonra ağ kartımızın 169.254.0.0/16 aralığında bir APIPA adresi ataması olacak:

PS> Get-NetIPConfiguration

InterfaceAlias       : Ethernet0
InterfaceIndex       : 10
InterfaceDescription : Intel(R) 82574L Gigabit Network Connection
NetProfile.Name      : Tanımlanmayan ağ
IPv4Address          : 169.254.195.47
IPv6DefaultGateway   :
IPv4DefaultGateway   :
DNSServer            : 8.8.8.8
                       8.8.4.4

Get-NetIPAddress ile baktığımızda ise

Get-NetIPAddress | ft ifIndex, IPAddress, InterfaceAlias, PrefixLength, PrefixOrigin

ifIndex IPAddress                    InterfaceAlias              PrefixLength PrefixOrigin
------- ---------                    --------------              ------------ ------------
     10 fe80::458e:8efe:1c9c:c32f%10 Ethernet0                             11    WellKnown
      1 ::1                          Loopback Pseudo-Interface 1          128    WellKnown
     10 169.254.195.47               Ethernet0                             16    WellKnown
      1 127.0.0.1                    Loopback Pseudo-Interface 1            8    WellKnown

Vurgulamak istediğim, PrefixOrigin sütunundaki Wellknown alanıydı.

Son durumda bu ağ kartını tekrar DHCP'den IP adresi alacak şekilde ayarlamak kaldı. Bunu yapmanın ön koşuşu tüm IP adresi atamasını temizlemek. Ondan sonra ise

PS> Get-NetAdapter | Set-NetIPInterface -Dhcp Enabled

Bu komutu verdikten hemen sonra ağ kartımı kontrol ettiğimde DHCP'den bir IP adresi ataması almadığını gördüm. Şu sitede son aşamada bir kez daha Remove-NetRoute'ı çalıştırmak önerilmiş. Bu oldu; ama benim tercihim ağ kartını disable edip tekrar etkinleştirmek (Restart-NetAdapter ?) oldu:

PS> Get-NetAdapter | Disable-NetAdapter

PS> Get-NetAdapter | Enable-NetAdapter

Tamamen Powershell dünyasında kalma amacımıza hizmet edecek başka iki cmdlet daha DNS önbelleğini görüntüleme ve/veya silme için aşağıdakiler olabilir

PS> Get-DNSClientCache

PS> Clear-DNSClientCache


Windows 11 için uzaktan sunucu yönetim araçlarını yükleme

Uzaktan sunucu yönetim araçları (Remote Server Administration Tools, RSAT) Windows iş istasyonlarından sunucuları yönetmek için kullanılan araçlar. Eskiden bunları yüklemek için Microsoft'un sitesinden indirilen bir paketi kurardık. Artık farklı.

İki kurulum yöntemi var, birincisi grafik arayüzden. Başlat menüsündeki aramaya "İsteğe Bağlı Özellikler" (Optional Features) yazalım. Açılan pencerede üstteki "Özellikleri görüntüle" düğmesine basalım. Tüm özelliklerin içinde RSAT ile ilgili olanları süzmek için ise üstteki arama kutusuna da RSAT yazalım. Benim sistemimde 21 bileşen listelendi. Bunların yanındaki kutuları işaretleyerek istenenlerl kurabiliriz. Hepsi için 21 kutunun işaretlenmesi gerek.

İkinci yol, Powershell. Yönetici yetkileriyle açılmış bir powershell penceresinden aşağıdaki gibi bir komutla isteğe bağlı özelliklerin arasında isminde RSAT geçenleri listeleyebiliriz:

PS> Get-WindowsCapability -Name RSAT* -Online

Evet, Powershell'de Optional Features yerine Windows Capability terimi kullanılmış.

Bunların tümünü kurmak için yukarıdaki komutun çıktısını Add-WindowsCapability cmdlet'ine göndermemiz gerek.

PS>  Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online

Hem Get-WindowsCapability hem de Add-WindowsCapability cmdlet'inde kullanılan -Online parametresi, çalışan işletim sistemi üzerinde işlem yapılmasından dolayı.

Powershell çözümü 21 ayrı pakete tıkalmak zorunda kalmamak için daha mı pratik?

11.10.2022

Powershell ve yazıcılar

Bir bilgisayardaki yazıcıları listelemek için

PS> Get-Printer

kullanılabilir. Listelenen yazıcılardan birini paylaştırmak için ise

PS> Set-Printer -Name "HP Laserjet 1300" -Shared $True -ShareName "HPLJ1300"

gibi bir komut iş görür.

Paylaşılan bir yazıcıyı da (başka bir bilgisayara) eklemek için

$yazici = "\\sunucu\HPLJ1300"

Invoke-Command -ComputerName UZAKBILGISAYAR -ScriptBlock {
(New-Object -Com Wscript.Network).AddWindowsPrinterConnection($Using:$yazici)
}

yeterli.

Powershell'de yerel betik veya değişkenleri uzak betiklerde kullanmak

Diyelim yerel bilgisayarda bir değişkenimiz var:

PS> $yol = "D:\logs"

Normal şartlar altında yerel bilgisayarda tanımlanan değişkenlerin kapsamları yerel bilgisayardaki betik ortamında kalır. Uzaktaki bilgisayarda çalıştırılan aşağıdaki gibi bir kod hata vermese de beklenen çıktıyı üretmez:

PS> Invoke-Command -Computername UZAKPC -ScriptBlock { Get-ChildItem -Path $yol }

Yerel değikenin kapsamıını uzaktaki bilgisayarı da içine alacak şekilde genişletmek için şu iki yöntemden birini kullanabiliriz:

PS> Invoke-Command -Computername UZAKPC -ScriptBlock { Get-ChildItem -Path $Using:yol } 

PS> Invoke-Command -Computername UZAKPC -ScriptBlock { Get-ChildItem -Path $yol } -ArgumentList $yol

Birden fazla değişken varsa şöyle bir kullanım da mümkün:

PS> Invoke-Command -Computername UZAKPC -Scriptblock { Add-Content -Path $arg[0] -Value $arg[1] } -Argumentlist "D:\test.txt",16

Değişkene ilave olarak yerel bilgisayarda oluşturduğumuz yerelfonksiyon() gibi bir fonksiyon varsa ve bunu uzak bilgisayarda çalıştırmak istiyorsak bu durumda da aşağıdaki gibi yol izleyebiliriz:

PS> Invoke-Command -Computername UZAKPC -ScriptBlock ${Function:yerelfonksiyon}

Yerel fonksiyonları uzak bilgisayarda kullanmanın bir ön koşulu, fonksiyonun Function: sürücüsünde görülebilir olması. Bir modülden falan yüklenecekse Import-Module kullanmak veya bir dosyada ise öncesinde bir kez kullanarak çalışma ortamımıza almak gerek. Alternatif yöntem olarak ArgumentList parametresini de kullanabiliriz. Bu yöntemle karşı tarafa aktarılan foksiyonun "string" veri tipinde aktarıldığı sayfanın altındaki kaynakta belirtilmiş. Bunun çözümü olarak Create() yordamının kullanılması önerilmiş. Yerel bilgisayardaki fonksiyon isminin içinde tire (-) karakteri gibi değişken isimlerinde kullanılmaması gereken karakterler varsa param() kullanarak bu fonksiyonu başka bir değişken ismine dönüştürmek mümkün (uf = uzak fonksiyon kısaltması):

PS> Invoke-Command -Computername UZAKPC -ScriptBlock { param($uf ); [ScriptBlock]::Create($uf).Invoke()} -ArgumentList ${function:yerelfonksiyon}

2023-02-24 ek: Invoke() yerine şu ifade de gayet mantıklı (alias'lar kullanılmıştır):

PS> icm -cn UZAKPC -script {param($uf); iex $uf} -Argumentlist ${function:yerelfonksiyon}

Benzer şekilde bu fonksiyona parametre olarak yine yerel bilgisayarda tanımlanmış değişkenler göndereceksek

PS> Invoke-Command -Computername UZAKPC -ScriptBlock {param($uf,$d1,$d2); [ScriptBlock]::Create($uf).Invoke($d1,$d2)} -ArgumentList ${function:yerelfonksiyon},$deger1,$deger2

---

https://stackoverflow.com/questions/30304366/powershell-passing-function-to-remote-command

5.09.2022

Powershell ile dosyaların sahibini değiştirme

Grafik arayüz bir yöntem; ama biz Powershell ile yapmak istiyoruz.

Hedefimiz $hedef değişkeninde olsun. Dosyamızın yeni sahibi de BILGISAYAR\kullanıcı hesabı olsun.

Önce bir acl değişkeni oluşturalım:

PS> $acl = Get-Acl -Path $hedef

Daha sonra da bir hesap nesnesi oluşturalım.

PS>  $hesap = New-Object-TypeName System.Security.Principal.NTAccount -ArgumentList "BILGISAYAR\kullanici"

Daha sonra $acl nesnesinin içinde yer alan Owner'ı değiştirelim.

PS> $acl.SetOwner($hesap)

Daha sonra da bunu Set-Acl ile dosya sistemine yansıtalım.

PS> Set-Acl -Path $hedef -AclObject $acl

Güzel.

---

[1] https://stackoverflow.com/questions/22988384/powershell-change-owner-of-files-and-folders

[2] https://learn-powershell.net/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/

16.08.2022

Nirsoft araçları ve güvenlik

Uzun bir süredir Nirsoft.net sitesinde yayınlanan ücretsiz (ama kapalı kaynak kodlarına sahip) bazı araçların varlığından haberdarım ve zaman zaman kullanıyorum. Örneğin Sysinternals araçlarından biri olan TCP View'un benzeri olan ama gerek IP adresi gerek protokol bazında listeyi filtreleme özelliğine sahip CurrPorts, çok sayıda hedefi gerek ICMP gerekse TCP üzerinden pingleyebilen PingInfoView. Bunlarla da sınırlı değil, bir sürü güzel minik tatlı progam var sitede genel kullanıma açık.

Ama birçok antivirüs ve güvenlik sisteminde yıllardır bu programların bir kısmı "zararlı kod" olarak sınıflandırılıyor. Nirsoft sitesinde bu konuya özel bir sayfa var. Burada deniyor ki; bazı antivirüs yazılımları, araçlarımız ile ilgili "yanlış alarm" (false positive) verebilir, bu gerçeği yansıtan bir durum değil. Başka sitelerde Nirsoft araçları ile ilgili PUA (Potentially Unwanted Application - Muhtemel İstenmeyen Program) sınıflandırması yapılmış. Yani araçlardan birkaçı internet tarayıcılarında kaydedilmiş şifreleri görmeye izin verdiğinden, ya da ağ cihazlarının izlenmesine, ekran görüntülerinin alınmasına sebep olabileceği ve kullanıcıların istekleri dışında kullanım amacına sahip olmasından dolayı varsayılan olarak karantiya alınması gerektiğine dair bir sınıflandırma yapılmış ([1], [2], [3]).

Sadece bu sebeple güvenlik yazılımlarının yıllardır ısrarla bu "zararsız" programları bu kategoriye alması ilginç geldiği için biraz daha araştırdım ve şu Youtube videosuna ve orada bahsedilen şu yazıya denk geldim. Bu yazı da başka bir uzman ile vardıkları sonucu şöyle özetlemiş; Nirsoft araçlarının içinde doğrudan kötü olmayan ama kötüye kullanıma çok açık, hatta önüne geçilmezse işletim sisteminde istenmeyen bazı sonuçlara yol açabilecek kodlar var.

Bu iki arkadaş, Nirsoft geliştiricisi olarak sitede ismi geçen kişiye durumu bildirdiklerini, ama geliştiricinin bu konuyla ilgili bir çabasını göremediklerini, hatta kendilerine cevap bile vermediğinini ifade etmişler. Eğer konu burada kapansaydı Nirsoft geliştiricisinin kötü niyetli bir insan olduğu çok net olurdu sanırım. Ama yorumlarda geliştiriciye ulaşma yöntemleri eleştirilmiş. Daha "doğrudan" yöntemlerin neden kullanılmadığı sorulmuş.

Konu yine ortada kaldı. Ama ben bu aşamada Nirsoft araçlarına daha az güvenmem gerektiğ sonucunu çıkardım.

---

[1] https://superuser.com/questions/1508706/does-nirsoft-utilities-have-a-virus

[2] https://www.bleepingcomputer.com/forums/t/448129/is-nirsofts-software-safe/

[3] https://www.reddit.com/r/Hacking_Tutorials/comments/f6813s/nirsoftnet_software_are_safe/

3.08.2022

zsh

Linux kabuğu (shell) olarak zsh'i denemek istedim. Fedora kullandığım makineye şu satırla kurulum yaptım:

$ sudo dnf install zsh util-linux-user

util-linux-user paketi, varsayılan kabuğu zsh olarak kullanmamızı sağlayacak chsh'e sahip. Bu arada şu anda kullanılan shell'i öğrenmek istersek

$ echo $0

veya

$ echo $SHELL

kullanılabilir. Şu aşamada açtığımız ilk terminal hala varsayılan kabuğu (çoğu durumda bash) kullanıyor olacaktır. zsh'e geçmek için ya terminalde zsh yazıp elle giriş yapmamız lazım, ya da terminal'i açar açmaz zsh'in gelmesi için chsh'i kullanmamız lazım:

$ chsh -s $(which zsh)

Bunu sudo/root ile çalıştırmaya falan gerek yok. Sadece kendi kabuğumuzu değiştiriyoruz. Dolayısıyla mevcut kullanıcının parolasını girmemizi isteyecek. Bundan sonra bir kez oturumu kapatıp tekrar açmak gerek.

chsh kullanmayan başka bir yöntem ise usermod'u kullanmak:

$ sudo usermod -s $(which zsh) $(whoami)

Bir sonraki oturum açılışında artık varsayılan kabuğumuz zsh olacak. İlk açılışta da bir yapılandırma ekranı bizi karşılayacak.

zsh, aynı bash gibi profilin altında .zshrc adındaki bir yapılandırma dosyasına ihtiyaç duyar. Bu ekran, bu yapılandırma dosyasının olmaması durumunda çıkıyor. zsh'i yanlışlıkla çalıştıranlar ve henüz bir .zshrc dosyası oluşturmadan çıkmak isteyenler için (q) seçeneği makul. Eğer boş bir yapılandırma dosyası oluşturup devam etmesini istiyorsak (0)ı, ya da tam gaz yapılandırmaya geçmek için (1)i seçmemiz gerek. Bu durumda sıradaki ekranımız şöyle olacak:

Ben bu ekranda (1) ile komut geçmişi, (2) ile komut tamamlama sistemi, (3) ile tuşların işlervlerini yapılandırabilir ve (4)e basarak diğer bazı ayarları (1), (2), (3) ve (5)'i (s)ye basarak ayarlıyorum. Her ekrandan da (0)a basarak ayarlarımı hatırlamasını ve nihayetinde yukarıdaki ekrana döndüğümde de (0) seçeneği için açıklama "boş bir .zshrc dosyası oluşturup çıkmak" yerine "ayarları kaydederek çık"a dönüştüğünde bu seçenek ile ayarları kaydedip çıkmayı seçiyorum.

İşler bittiğinde yukarıdaki gibi bir ekran ile karşılaşıyorum. Aslında prompt'ta sadece değişen $ karakterinin yerine % karakterinin gelmiş olmasının dışında bir fark gözükmüyor.

Bu arada yukarıda yazan birkaç açıklamaya vurgu yapalım; bu çalışan karşılama ekranını tekrar çalıştırmak için

$ autoload -Uz zsh-newuser-install
$ zsh-newuser-install -f

yazabiliriz. Ayrıca .zshrc yapılandırma dosyasında 

# Lines configured by zsh-newuser-install
# End of lines configured by zsh-newuser-install

satırları arasına müdahale etmememiz, yapaacğımız değişiklikleri bu satırlar dışına eklememiz önerilmiş.

Bu noktada sade bir zsh'ımız oldu. Hiçbir ek bileşene ihtiyaç duymadan prompt'umuzu özelleştirmek mümkün. Ev klasörümüzde yer alan .zshrc dosyasını açık için şu satırları yazalım:

autoload -Uz promptinit
promptinit
prompt bart

Autoload, zsh ile gelen bir betik çalıştırıcı. Bu satırlarda prompt'umuz için mevcut temalardan bart'ı seçmiş olduk. Tüm temaları görmek için

$ prompt -l

(her promptun örneğini görmek için -p de olur) veya mevcut temayı görmek için

$ prompt -c

kullanabiliriz. Karşılaştığım sorunlardan biri ctrl+ok tuşlarının kelime atlama yapmaması. ctrl+ok tuşları ile bir önceki kelime başına veya bir sonraki kelime başına atlamak istersem terminale ";5D" ve ";5C" yazılıyor. Bunu düzeltmek için .zshrc dosyasına aşağıdaki satırları ekleyerek çözebildim:

bindkey ";5D" backward-word
bindkey ";5C" forward-word
bindkey "^W" backward-delete-word

Benzer şekilde Home tuşuyla satırın başına, End tuşuyla sonuna gitmek ve Del tuşu ile silebilmek için

bindkey "^[[H" beginning-of-line
bindkey "^[[F" end-of-line
bindkey "^[[3~" delete-char

Son satır Ctrl+w kısayolu ile önceki sola doğru bir kelime silmek için.

Biraz daha renklendirmek için oh-my-zsh kurmayı tercih ediyorum. curl kullanarak

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

ya da git clone ile

$ git clone git://github.com/robbyrussell/oh-my-zsh.git ~/.oh-my-zsh

ilgili dosyaları aldıktan sonra profil klasörümüzün altında .oh-my-zsh gizli klasörü oluşacak. oh-my-zsh bize hazır bazı temalar getirecek. Curl yöntemini seçtiysek .zshrc dosyasına varsayılan tema da girilmiş olacak. git clone yaptıysak bu işi el ile yapmamız gerekecek. Mevcut temalara göz atmak için projenin github sayfasına bakabiliriz. Bir tema seçtikten sonra .zshrc dosyasına 

ZSH_THEME="duellj"

gibi bir tema adı yazmak, temamızı her açtığımızda rastgele değişecek şekilde belirlemek için

ZSH_THEME="random"

ya da belli birkaç temanın içinden rastgele seçmek için

ZSH_THEME_RANDOM_CANDIDATES=( "duellj" "agnoster" )

yapılabiliyor.

zsh'i güzel yapan şeylerden biri de eklentileri. Çok kullanılan 2 güzel eklenti Fedora'nın depolarında mevcut. Kurmak için

$ sudo dnf install zsh-autosuggestions zsh-syntax-highlighting

yazmak yeterli. Kurulum sonrası bu iki eklentiyi yapılandırmamıza dahil etmek için yine .zshrc dosyasını açıp son satıra şu satırları eklemek gerek:

# plugins
source /usr/share/zsh-autosuggestions/zsh-autosuggestions.zsh
source /usr/share/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh

Bu eklentilere ek olarak zsh-Z, fsf de kullanılabilir. Bu şekilde source komutu ile eklentileri .zshrc'ye dahil etmek, oh-my-zsh öncesi yöntem. oh-my-zsh kullanırken daha kolay bir yöntem var; eklentilerin ~/.oh-my-zsh/plugins klasörünün altına yerleştirildiğini varsayarsak bu plugin'lerin isimlerini plugins=(...) satırında parantes içine boşlukla ayrılmış dizi şeklinde yazabiliriz. Örneğin zsh-autosuggestions'ın nereye kurulduğuna bakmak için

$ rpm -ql zsh-autosuggestions

yazdığımda /usr/share/zsh-autosuggestions klasörne kurulduğunu gördüm. Şunun gibi yaparak bu plugin'i oh-my-zsh'in plugin klasörüne kopyalayabiliriz:

$ cp /usr/share/zsh-autosuggestions ~/.oh-my-zsh/plugins -r

Bu noktadan sonra şu mümkün:

plugins=(zsh-autosuggestions)

Oh-my-zsh ile gelen plugin'ler de faydalı olabilir. Herhangi bir plugin'i etkinleştirmek için .zshrc dosyasına

plugins=(rails git ruby)

gibi isimlerini yazmak gerek.

oh-my-zsh ile birlikte gelen temaları terminalden görmek istersek (2023-04-07)

$ omz theme list

ve hatta bu temalardan birini kullanmaya başlamak için ise

$ omz theme set duellj

yazılabilir. Ayrıca plugin'leri etkinleştirmek için de

$ omz plugin enable

Bu komutlar sadece mevcut oturumda prompt'u değiştirmekle kalmaz, .zshrc dosyasında da gerekli değişiklikleri yaparak sonraki oturumlarda da geçerli olmasını sağlar.

Görselliğe seviye atlatacak powerlevel10k temasını yüklemek için ise

$ git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ~/powerlevel10k
$ echo 'source ~/powerlevel10k/powerlevel10k.zsh-theme' >>~/.zshrc

yazabiliriz. En son satırdaki echo ile source'u .zshrc'ye ilave etmek yerine aşağıdakini de yapabiliriz

ZSH_THEME="powerlevel10k/powerlevel10k"

Niye 2 kere powerlevel10k yazdık? Çünkü profil klasörümüzün içinde powerline10k klasörünün içindeki powerlevel10k dosyasını göstermeye çalışıyoruz.

Powerlevel10k'in github sayfasında özel bir fonta ihtiyaç duymadığı, ama ek karakterlere sahip bir font ailesinin avantajlarını kullanabileceği yazılmış. Dolayısıyla şu fontlardan birini kullanmak isteyebiliriz:

Nerd Fonts,  

Source Code Pro,  

Font Awesome

Powerline

Powerlevel10k'yı etkinleştirdikten sonraki ilk açılışta aşağıdaki gibi bir ekran ile karşılaşacağız.

Görülebileceği gibi seçili fontlar ile bazı karakterleri göstermeyi deniyor ve bunların uygun şekilde gözüküp gözükmediği konusunda kullanıcıdan bir geri dönüş bekliyor. Diamond için hadi neyse, ama bir sonraki ekrandaki asma kilit sembolü için Fedora'nın varsayılan sabit genişlikli fontu monospace yeterli olmadı. Şu sayfada anlatıldığı gibi powerlevel10k-media reposundaki fontları indirdim.

 
$ cd $HOME/Downloads
$ wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf
$ wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold.ttf
$ wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Italic.ttf
$ wget https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Bold%20Italic.ttf

Kurmak için Gnome fonts uygulaması ile açtıktan sonra sağ üst köşedeki Kur düğmesine bastım. Kurultuktan sonra bu düğme pasif hale geldi.


powerlevel10k'i tekrar yapılandırmak istersek

$ p10k configure

çalıştırmak gerek.

---

https://github.com/rothgar/mastering-zsh/blob/master/docs/config/general.md

https://dev.to/voracious/a-guide-to-customizing-the-zsh-shell-prompt-2an6

2.06.2022

Linux'ta Forticlient ile VPN ve internet

 Linux'ta fortisslvpn ile VPN yapaken internete bağlanamıyordum.

$ ip r

ile route tablomu incelediğimde 

default dev ppp0 proto static scope link metric 50

gibi fazladan bir satır gördüm. Bu, herşeyi VPN sanal arayüzüne göndermesini söylüyor. Windows'da forticlient böyle çalışmıyor; trafiğin sadece gereken kısmı VPN tüneline gidiyor, diğer kısmı varsayılan ağ geçidimize yönlendiriliyor. Linux'ta da aynısını yapalım, bu satırı silelim:

$ sudo ip route del default dev ppp0

4.05.2022

Manjaro'da düşük güç kipine giriş ve çıkış kayıtları

Hibernate ve suspend durumlarına ait kayıtları incelemek için bulduğum yöntemler şunlar:

$ journalctl -u systemd-hibernate.service --output=short-iso

$ journalctl -t systemd-sleep --output=short-iso

 Ayrıca beklenmeyen kapanmalarla ilgili şu bilgiler de faydalı olabilir.

12.04.2022

Eventlog ve provider listeleri

Türkçesi olay günlüğü ve sağlayıcı/tedarikçi listeleri. Windows işletim sistemlerinde oluşan olayları arka planda kaydeden bir olay günlüğü mekanizması vardır. Vista öncesi sistemlerde standart olarak Sistem (System), Güvenlik (Security) ve Uygulama (Application) gibi olay günlüklerine daha sonra Uygulama ve Hizmet Günlükleri (Application and Service Logs) altındaki diğer günlükler eklendi.

Powershell'in olay günlükleri ile ilgili ilk cmdlet'i Get-EventLog idi. Bu cmdlet, standart olay günlükleriyle çalışmakta yeterliydi. Örneğin bir makinedeki olay günlüklerinin listesini alabilmek için:

> Get-EventLog -List 

kullanabiliriz. Vista öncesi sistemlerde olay günlüklerine kayıt düşen bileşenlere kaynak (source) denirdi. Sisteme yeni kurulan bir sürücü, yeni bir yazılım, istediği olay günlüğüne kendi uygun gördüğü kaynak ismiyle kayıt düşerdi. Örnek olarak aşağıdaki olay kaydına bakalım:

Bir hizmetin durumu hakkında bizi bilgilendiren bu olay kaydını Sistem olay günlüğüne yazan kaynağın adı "Service Control Manager". Alışkanlıklar daha sonra biraz değişiti. Vista ile birlikte "Uygulama ve Hizmet Günlükleri"ni okumak için hem Get-Eventlog'dan başka bir cmdlet'e ihtiyaç duyuldu, hem de Kaynak (Source) teriminin yerine Sağlayıcı (Provider) geldi.

Yeni cmdlet Get-WinEvent oldu. Vista sonrası sistemlerde var olan yeni logların listesini alabilmek için de önceki örneğe eşdeğer olarak

> Get-WinEvent -ListLog *

geldi. Bu şekilde hiçbir ölçüt belirtmeden sadece * kullanara sorgularsak çok uzun bir liste ile karşılaşabilriz. Bunun yerine örneğin içinde powershell geçen olay günlükleri için

> Get-WinEvent -ListLog *powershell*

yazabiliriz.

Get-EventLog'da olmayan, ama Get-WinEvent ile gelen -ListProvider parametresi de bir önceki paragrafa konu sağlayıcıların listesini alabilmek için:

> Get-WinEvent -ListProvider *

Bu komut da benzer şekilde uzun bir liste verecek. Onun yerine örneğin içinde içinde sadece Sysmon geçen sağlayıcıları görebilmek için

> Get-WinEvent -ListProvider *sysmon*

yazabiliriz.

Get-Eventlog cmdlet'i için benzer bir -ListProvider parametresi yoktu. Bunun yerine kullanılabilecek yöntem şu olabilirdi:

> Get-WmiObject -Class Win32_NTEventLOgFile | Select-Object FileName, Sources

Bu şekilde her olay günlüğüne kaydedilmiş sağlayıcı (ya da kaynakları) ayrı ayrı görebiliriz.




11.03.2022

Powershell'de alias aramak

Get-Alias komutunun varsayılan araması bir alias'ın hangi cmdlet'e karşılık geldiğini bulmaya yönelik. Örneğin

PS> Get-Alias sls

CommandType     Name                           Version    Source
-----------     ----                           -------    ------
Alias           sls -> Select-String

Bazen ihtiyacım tam tersi oluyor; yani select-string'in alias'ı nedir, bunu bilmek istiyorum. Ama Get-Alias'ın böyle bir araması hata ile sonuçlanıyor:

PS> Get-Alias Select-String

Get-Alias : This command cannot find a matching alias because an alias with the name 'select-string' does not exist.
At line:1 char:1

Get-Alias komutunun ne gibi bir çıktı ürettiğini görmek için Get-Member (gm) cmdlet'ini kullanarak çıktı alanlarını inceledim.

PS> Get-Alias sls | gm

HelpUri             : https://go.microsoft.com/fwlink/?LinkID=113388
ResolvedCommandName : Select-String
DisplayName         : sls -> Select-String
ReferencedCommand   : Select-String
ResolvedCommand     : Select-String
Definition          : Select-String
Options             : None
Description         :
OutputType          : {Microsoft.PowerShell.Commands.MatchInfo, System.Boolean}
Name                : sls
CommandType         : Alias
Source              :
Version             :
Visibility          : Public
ModuleName          :
Module              :
RemotingCapability  : PowerShell
Parameters          : {[InputObject, System.Management.Automation.ParameterMetadata], [Pattern, System.Management.Automation.ParameterMetadata], [
                      Path, System.Management.Automation.ParameterMetadata], [LiteralPath, System.Management.Automation.ParameterMetadata]...}
ParameterSets       :

Yukarıdaki alanların içinde kırmızı ile belirttiğim Definition aradığım alan. Get-Alias'ın parametrelerinin içinde de böyle bir bölüm vardı. Bunu kullanarak:

PS> Get-Alias -Definition Select-String

CommandType     Name                          Version    Source
-----------     ----                          -------    ------
Alias           group -> Group-Object

sonuca ulaştım.

Dosyaların içinde geçen bir kelimeyi saymak

Sıkça olarak anahtar kelime araması yapmak için powershell Select-String'i (sls) kullanıyorum:

PS> sls anahtar_kelime D:\logs\*.log

Bu şekilde çok sayıda dosyanın içinde geçen anahtar_kelime satırı listeleniyor, powershell penceresinde satırlar akıp gidiyor. Bazı durumlarda anahtar kelimenin geçtiği satırdan çok hangi dosyada kaç kere geçtiği, veya en çok hangi dosyada geçtiği önem kazanır. Bu durumlarda Group-Object ile sayım yapıyorum:

PS> sls anahtar_kelime D:\logs\*.log | group path

Bu sonucu biraz güzelleştirmek için verileri count alanına göre sıralamak ve bir tablo şeklinde görüntülemek faydalı oluyor:

PS> sls anahtar_kelime D:\logs\*.log | group path | sort count -desc |ft * -Autosize

Her durumda powershell!

10.03.2022

Windows oturum açma geçmişi

Bir kullanıcı bir Windows bilgisayarda oturum açtığında 4624 olay kaydı oluşur. Ancak ağ üzerinden bağlanma, uzak masaüstü bağlantısı ve kilitli bilgisayarı açmak da dahil olmak üzere birçok durumda yine 4624 olayı kaydedilir. Oturum açma çeşitleri (Logon Type) olarak şu tabloya bakılabilir:


Logon Type Logon Title Description
0 System Sadece "System" hesabı için kullanılır.
2 Interactive Gerçek oturum açma olayı. RunAs de olabilir. [1]
3 Network Ağ üzerinden oturum açma. Paylaşımlara erişme, IIS (integrated auth), Powershell Remoting [1]
4 Batch Genellikle zamanlanmış görevlere aittir.
5 Service Service Control Manager tarafından başlatılan bir hizmete ait kayıt.
7 Unlock Kilitli bilgisayarın kilidinin açılmasına ait kayıt.
8 NetworkCleartext Bir kullanıcı ağ üzerinden oturum açmış, ama parola hash olarak değil, açık şekilde gönderilmiş.
9 NewCredentials Oturum açılırken üretilen token tekrar kullanıldı ama yeni oturum açma bilgileri (kullanıcı adı ve parola) belirtti. RunAs /NetOnly [1]
10 RemoteInteractive Uzak masaüstü, uzaktan yardım, terminal hizmetleri.
11 CachedInteractive Oturum açma sırasında parolayı doğrulamak için etki alanı sunucusuna (DC) danışılmadı, yerel kayıt bilgileri (cache) kullanıldı.
12 CachedRemoteInteractive RemoteInteractive ile aynı, iç izleme için denmiş (?)
13 CachedUnlock Sanıyorum kilit açarken DC'ye danışmadan yerel kayıt bilgilerinin (cache) kullanılması durumu.

Etki alanı olmayan bir bilgisayara yapılan oturum açmaları arıyorsak 2 veya 7'ye bakmalıyız. Etki alanına üye bir bilgisayar için ise 2, 11 ve 13 olabilir.

Get-WinEvent ile şu şekilde yapılan bir sorgu ile olay gövdesindeki bütün bilgileri görmek yüksek olasılıkla mümkün olmayacaktır:

PS> Get-WinEvent -Filterhashtable @{LogName="Security";Id=4624}

TimeCreated                      Id LevelDisplayName Message
-----------                      -- ---------------- -------
2022-03-10 20:49:38            4624 Bilgi            Bir hesapta başarılı bir şekilde oturum açıldı....

Bunun yerine hem oturum açma tipini hesaba katıp, hem de EventProperty nesnesi ile daha güzel bir çıktı üretmek mümkün. 4624 olayı için EventProperty üyeleri şöyle:

0 : Subject User SID
1 : Subject Username
2 : Subject Domain Name
3 : Subject Logon Id
4 : Target User SID
5 : Target Username
6 : Target Domain Name
7 : Target Logon Id
8 : Logon Type
9 : Logon Process Name
10: Authentication Package Name
11: Workstation Name
12: Logon GUID
13: Transmitted Services
14: LmPackageName
15: Keylength
16: ProcessId
17: ProcessName
18: IP Address
19: IP Port
20: Impersonation Level
21: Restricted Admin Mode
22: Target Outbound Username
23: Target Outbound Domain Name
24: Virtual Account
25: Target Linked Logon Id
26: Elevated Token

4771 Pre-Authentication failed hatasının EventProperty nesnesi içindeki 4 numaralı üye Status için şu ayrıntılar verilmiş:

StatusKerberos RFC tanımı Açıklama
0x1 Client's entry in database has expired  
0x2 Server's entry in database has expired  
0x3 Requested protocol version # not supported  
0x4 Client's key encrypted in old master key  
0x5 Server's key encrypted in old master key  
0x6 Client not found in Kerberos database Bad user name, or new computer/user account has not replicated to DC yet
0x7 Server not found in Kerberos database New computer account has not replicated yet or computer is pre-w2k
0x8 Multiple principal entries in database  
0x9 The client or server has a null key administrator should reset the password on the account
0xA Ticket not eligible for postdating  
0xB Requested start time is later than end time  
0xC KDC policy rejects request Workstation restriction
0xD KDC cannot accommodate requested option  
0xE KDC has no support for encryption type  
0xF KDC has no support for checksum type  
0x10 KDC has no support for padata type  
0x11 KDC has no support for transited type
0x12 Clients credentials have been revoked Hesap devre dışı, süresi dolmuş, kilitlenmiş veya oturum açma saatleri dışında.
0x13 Credentials for server have been revoked  
0x14 TGT has been revoked  
0x15 Client not yet valid - try again later  
0x16 Server not yet valid - try again later  
0x17 Password has expired Parolanın süresi dolmuş
0x18 Pre-authentication information was invalid Genellikle yanlış parola
0x19 Additional pre-authentication required*  
0x1F Integrity check on decrypted field failed  
0x20 Ticket expired Frequently logged by computer accounts
0x21 Ticket not yet valid  
0x21 Ticket not yet valid  
0x22 Request is a replay  
0x23 The ticket isn't for us  
0x24 Ticket and authenticator don't match  
0x25 Clock skew too great Workstation’s clock too far out of sync with the DC’s
0x26 Incorrect net address IP address change?
0x27 Protocol version mismatch  
0x28 Invalid msg type  
0x29 Message stream modified  
0x2A Message out of order  
0x2C Specified version of key is not available  
0x2D Service key not available  
0x2E Mutual authentication failed may be a memory allocation failure
0x2F Incorrect message direction  
0x30 Alternative authentication method required*  
0x31 Incorrect sequence number in message  
0x32 Inappropriate type of checksum in message  
0x3C Generic error (description in e-text)  
0x3D Field is too long for this implementation  

Bunları kullanarak daha şekilli bir çıktı için şöyle bir komut mümkün:

PS> Get-WinEvent -FilterHashtable @{LogName="Security";Id=4624} | 

Where-Object {$_.properties[8].Value -eq 2} |

Select-Object TimeCreated, Id, @{Name="Username";Expression={$_.properties[5].Value}}, @{Name="LogonProcName";Expression={$_.properties[9].Value}}, @{Name="AuthPkgName";Expression={$_.properties[10].Value}}, @{Name="IPAddress";Expression={$_.properties[18].Value}}

Bunun sonucunda çıktı şöyle olur:

TimeCreated           Id Username LogonProcName AuthPkgName IPAddress
-----------           -- -------- ------------- ----------- ---------
2022-03-10 19:53:21 4624 user1    Advapi        Negotiate   -
2022-03-10 19:53:21 4624 user2    Advapi        Negotiate   -
2022-03-10 19:53:21 4624 user2    Advapi        Negotiate   -
2022-03-10 19:53:14 4624 user4    User32        Negotiate   127.0.0.1
2022-03-10 19:53:14 4624 user5    User32        Negotiate   127.0.0.1

2023-12-09 Düzeltme: Burada 

Where-Object {$_.properties[8].Value -eq 2}

ile aslında bütün kullanıcıların yerel olduğunu varsaydım. Ama Windows 8 ve sonrasında artık kullanıcı hesapları Hotmail/Outlook gibi internet tabanlı olabildiği için bu kısıtlama onları göstermeyecektir. Ayrıca UMFD (user mode font driver) ve DWM (desktop window manager) hesaplarını da listelemek kafa karıştırabilir. Bunun için belki Where koşulu Authentication Package Name'e göre (Properties[9]) yapılabilir (alan sonunda bir boşluk karakteri var, bu sebeple -like işleci kullandım):

Where-Object {$_.properties[9].Value -like "User32*"}

Oturum kapatma olayı 4634, oturum açma hatası (yanlış parola/kullanıcı adı) 4625 olayları ile sorgulanabilir. Oturum kapatma için EventProperties nesnesinde 5 alan vardır. 4625'te ise 4624'tekine benzer sayı ve nitelikte alanlar vardır.

---

[1] https://medium.com/@pentesttas/windows-events-sysmon-visualization-using-neo4j-part-2-d4c2fd3c9413

26.02.2022

Linux os-prober

Grub'ın disk(ler)deki diğer işletim sistemlerini bulmak için kullandığı os-prober'ı biliyordum ama komut satırından çalıştırıldığında çıktılarını gösterebildiğini yeni öğrendim:

$ sudo os-prober

Bunun sonucunda da diğer işletim sistemleri grub menüsündeki sırasıyla listelenir.

20.01.2022

Uzak bilgisayardaki açık dosyaları listelemek

Yerel bilgisayarda açık dosyaların listesini değişik şekillerde alınabiliyor. Resource Monitor, Process Monitor veya komut satırından handles.exe ile bunu yapmak mümkün. Ama uzak bilgisayardaki açık dosyalar için aynı şeyi yapmak zor. Her seferinde uzak masaüstünden bağlanıp bunu yapmak da istemiyorum. Önce psexec ile handles'i uzak bilgisayarda çalıştırmayı düşündüm ama hem çok yavaş sonuç döndü, hem de dönen sonuçlarda görmeyi istediğim açılan dosya ile bu dosyayı açan proses aynı satırda yer almadığı için find.exe veys findstr.exe ile süzmek mümkün olmadı.

Sonra bugün öğrendiğim başka bir araç buldum: openfiles.exe

Bugüne kadar kullanmamış olmama şaşırmakla birlikte aynı anda şu adreste gösterilen şekilde powershell ile birlikte kullanmak çok hoşuma gitti.

PS> openfiles /Query /S SERVER01 /FO CSV /V | ConvertFrom-Csv | Out-GridView

Bu şekilde gelen grid nesnesinin içinde kelime araması yapmak da mümkün.

Bunu bir powershell fonksiyonu yaparak sadece bilgisayar adını değiştirerek çağırmak da güzel oldu:

function Get-OpenFiles
{
   [CmdletBinding()]
   param(
      [string]$Computername=$env:COMPUTERNAME,
      [string]$Output
   )

   if ($Output -eq "table")
   {
      openfiles /Query /S $Computername /FO TABLE /V
   }
   elseif ($Output -eq "csv")
   {
      openfiles /Query /S $Computername /FO CSV /V
   }
      elseif ($Output -eq "list")
   {
      openfiles /Query /S $Computername /FO LIST /V
   }
   else
   {
      openfiles /Query /S $Computername /FO CSV /V | ConvertFrom-Csv | Out-GridView
   }
}

Bu şekilde hiçbir Output parametresi verilmezse grid yeni bir pencerede grid nesnesinde görüntülenecek. Diğer seçeneklerde de console host içinde tablo, liste ve csv formatında çıktı almak mümkün.

Ek 2022-11-04: Sadece SMB paylaşımında kullanımda olan dosyaları görmek için kullanıyorsak SmbShare modülü ile birlikte gelen Get-SmbOpenFile cmdlet'i de kullanılabilir.

18.01.2022

Powershell ile diskleri yönetmek

Yeni bir disk geldi. Bilgisayara bağlantısını yaptıktan sonra ilk açılışta elbette gözükmeyecek. Öncelikle diski initialize (Diski Başlat) edip disk bölümleri oluşturmalıyız. Bunu grafik arayüz yerine powershell'den yapalım.

Önce bilgisayarda takılı diskleri listeyelelim

> Get-Disk

Number Friendly Name               HealthStatus   OperationalStatus   Total Size Partition Style
------ -------------               ------------   -----------------   ---------- ----------
0      Samsung SSD 860 PRO 512GB   Healthy        Online               476.94 GB GPT
1      TOSHIBA HDWL120             Healthy        Online                 1.82 TB RAW

Son satırda Partition Style olarak RAW gözüken disk, yeni takılan diskimiz. Bunun üzerinde yeni bölümler oluşturmadan önce bu diski initialize etmemiz gerek.

> Get-Disk -Number 1 | Initialize-Disk -PartitionStyle GPT

Initialize-Disk cmdlet'inin varsayılan partition style'ı GPT, yani yazmaya gerek yok aslında. MBR yapmak için açıkça belirtmek gerek.

Bu işlemden sonra diskimiz bir GPT disk olarak bölümlendirmeye hazır. Yeni bir disk bölümü oluşturalım:

> Get-Disk -Number 1 | New-Partition -Size 500GB -Driveletter P -Offset 500GB

Bu komut ile önce disk listesinde görülen 1 numaralı diski seçip new-partition cmdlet'ine gönderdim. Bu cmdlet ile de üzerinde 500 GB'lık bir disk bölümü oluşturup P: sürücü harfi ile erişilmesini istedim. Offset parametresinin varlığını göstermek istediğim için kullandım. Disk bölümünü boş diskin başında değil de ortasında yaratmak istersek bunu kullanabiliriz. Boyut olarak bütün diski kullanmasını istersek -UserMaximumSize parametresini kullanabiliriz.

Son aşamada bu sürücüyü biçimlendirmemiz gerek.

> Format-Volume -Driveletter P -Filesystem NTFS -AllocationUnitsize 8192

Bu komut ile de P: sürücümüzü NTFS dosya sistemi kullanarak biçimlendirip her disk biriminin (segment) 8192 Byte boyutunda olmasını sağladık.

Daha sonra bu disk bölümünün boyutunu değiştirmek istediğimizi varsayalım. Yanlış disk/bölüm üzerinde işlem yapmamak için önce Get-* cmdlet'leriyle seçimizi yapıp sonrasında bu seçimi boru "|" karakteriyle işlemi yapacak cmdlet'e gönderelim:

> Get-Disk -Number 1 | Get-Partition -PartitionNumber 2 | Set-Partition -size 512GB

Daha kısa bir şekilde

> Get-Partition -Driveletter P | Resize-Partition -Size 512GB

da diyebilirdik.

Var olan bir disk bölümünden kurtulmak için

> Get-Partition -Driveletter P | Remove-Partition

Bir diskteki bütün disk bölüm yapısını silmek için

> Clear-Disk -Number 1

Offline bir diski online yapmak için

> Get-Disk -Number 1 | Set-Disk -IsOffline $False