2019-09-16

Linux komut satırı araçları

uptime
Bilgisayar ne kadar süredir açık görmek için. Yanında ek bilgiler de var.
$ uptime
16:07:00 up 50 min,  1 user,  load average: 0,05, 0,02, 0,00
Burada mavi ile verilen ilk bölüm mevcut yerel saati gösteriyor. Kırmızı ile verilen ikinci bölüm ne kadar süredir açık olduğunu, sonraki yeşil bölüm kaç kullanıcının oturum açtığını, en son turuncu bölüm ise son 1, 5 ve 10 dakikalık zaman dilimindeki iş yükü ortalamasını gösteriyor, yüzdesel olarak.

Üçüncü bölümde yeşil olarak verilen şu anda oturum açmış kullanıcıların kimler olduğunu görmek için kullanılabilecek birkaç komut var. İlki en basit şekliyle kaç kullanıcının ne zaman oturum açtığını gösteren who:
$ who
usern    tty1         2019-09-08 21:43 (:0)
Bu komuttan biraz daha fazla bilgi veren w komutu var, bir miktar uptime ile birleştirilmiş who gibi:
$ w
21:59:28 up 16 min,  1 users,  load average: 0,79, 1,00, 0,78
USER     TTY       LOGIN@   IDLE   JCPU   PCPU   WHAT
usern    tty1      21:43    16:18  1:02   0.02s  /bin/bash
Ya da ps komutunu u parameteresiyle kullanabiliriz. Bunun avantajı, eğer oturumunu sonlandırmayı istediğimiz bir kullanıcı varsa bu komut aracılığıyla PID sütunundaki kimlik numarası kullanarak yapabiliriz.
$ ps u
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
usern      1447  0.0  0.0  10444  4524 pts/2    Ss   21:43   0:00 /bin/bash
Örneğin tek kullanıcımız usern'in oturumunu
$ kill 1447
ile sonlandırabiliriz.

last
Bilgisayar ilk kurulduğu günden beri açılış ve oturum açma işlemlerini listeler.
$ last
usern    tty1         :0               Fri Sep  6 15:18   still logged in
usern    :0                            Fri Sep  6 15:18   still logged in
reboot   system boot  5.2.5-200.fc30.x Fri Sep  6 15:16   still running
usern    tty1         :0               Thu Aug  8 16:16 - 18:03  (01:46)
usern    :0                            Thu Aug  8 16:16 - down   (01:48)
reboot   system boot  5.1.18-300.fc30. Thu Aug  8 16:05 - 18:05  (02:00)
Çok geriye gitmeden son birkaç satırı aldım. İşletim sisteminin açılışı reboot ile başlayan satırlarda belirtiliyor:
reboot   system boot  5.2.5-200.fc30.x Fri Sep  6 15:16   still running
Bu gibi satırlarda 2. sütunda hep system boot yazıyor. 3. sütunda ise yükleme işleminden sorumlu çekirdek sürüm numarası var. Son sütunda ise sistemin açılış tarihi ve saati ile kapanış saati ve parantez içinde de sistemin açık kalma süresi var.

Kullanıcı adıyla (usern) başlayan satırlar kullanıcının şifresini girerek oturum açması ile ilgili olan satırlar.
usern    :0                            Fri Sep  6 15:18   still logged in
Burada tty1 (veya genel olarak tty*) yerel olarak terminal etkileşimini, pts0 (veya pts*) uzaktan ssh gibi yöntemlerle terminal etkileşimini gösterir. Bu satırların sonunda ise kullanıcının oturumu açık olarak kaldığı süre gösterilir.

Sadece sistemin başlatma olaylarını listelemek için
$ last reboot
sadece belli bir kullanıcının oturum açma olaylarını listelemek için de
$ last usern
Kapanma olaylarını ve çalışma seviyesi (runlevel) değişikliklerini görebilmek için -x kullanılır.
$ last -x
kullanılabilir. Belli bir tarihten sonra gerçekleşen olayların listesi için -s anahtarı (since), bir tarihe kadar olan bir olayları görmek için -t (until) veya son 10 sayıda olayı görmek için -n 10 gibi anahtarlar kullanılabilir.
$ last -s 2019-03-01 -t 2019-05-31
$ last -n 10
Belirtilen bir tarihteki olayları görmek için -p (present)
$ last -p 2019-05-19
awk
Çok faydalı bir araç. İsmini geliştiricilerinin soyisimlerinin başharflerinden alıyor. Örneğin last komutu ile 01.05.2019 tarihinden sonra kimler giriş yapmış, kullanıcı adlarını görüntülemek için şöyle bir komut kullanılabilir:
$ last -s 2019-05-01 | awk '{print $1}'
reboot yazılan satırlar sistem açılışları, gerçek kullanıcı değil. Varsayılan olarak boşluk karakterlerini alan ayraçı olarak kullanır. Bunu değiştirmek için -F anahtarı kullanılır. Örneğin /etc/passwd dosyasındaki kullanıcı isimlerini ve tire "-" karakteri ile ayrılan açıklamalarını yazmak için şöyle bir komut kullanılabilir:
$ awk -F: '{print $1 " - " $5}' /etc/passwd
Örnek olarak aşağıdaki gibi notlar.txt dosyamız olsun.

Arda 80
Batu 60
Deniz 40
Caner 30

Bu verilere göre 50 geçer notun üzerinde not alan öğrencilerin geçtiğini açıklamak istiyoruz. Şöyle bir satır işimizi görür:
$ awk '{if ($2>50) print $1 " geçti"}' notlar.txt
Arda geçti
Batu geçti
Bir sonraki aşama, notlar.txt dosyasında her satırda isim ve 2 sınav notu yer alıyor.

Arda 80 60
Batu 60 70
Deniz 40 80
Caner 30 50


Bu 2 notun ortalamasını ekrana yazmak istiyoruz.
$ awk '{
total = 0
for (i=2; i<4; i++)
{ total += $i }
avg = total/(i-2)
print $1 ": " avg
}' notlar.txt
Şöyle bir sonuç verecek:

Arda: 70
Batu: 65
Deniz: 60
Caner: 40


Notlar dosyasında sadece Deniz'in ilk sınav notunu merak ettik diyelim. Bunu yapmanın başka yolları var elbette, ama awk örneği olsun diye böyle yapalım.
$ awk ' /'Deniz'/ {print $2}' notlar.txt
40
Başka bir örnek; adı sayilar.txt ve her satırında 10, 20, 30 ve 40 olan bir metin dosyasındaki tüm sayıların toplamını hesaplamak için
cat sayilar.txt | awk '{toplam+=$1} END {print toplam}' 
Veya kısa bir oran hesaplaması yapmak için
cat sayilar.txt | awk 'BEGIN {adet=0} {toplam+=$1; adet++} END {print toplam " / " adet " = " toplam/adet}'
Daha fazla ayrıntı için [1] ve [2] ye bakılabilir.

sed
Stream EDitor kısaltması. Bu aracın da ilginç kullanım alanları var. Örneğin bir dosyamız olsun, aşağıdaki gibi.

Bu birinci satır
Sonra gelir ikinci
Sondan bir önceki üçüncü
En sonda da dördüncü

Bu dosyanın örneğin 2. satırını silmek istiyoruz
$ sed '2d' ornek.txt
Bu birinci satır
Sondan bir önceki üçüncü
En sonda da dördüncü
Ya da en son satırını
$ sed '$d' ornek.txt
Bu birinci satır
Sonra gelir ikinci
Sondan bir önceki üçüncü
2. ve 4. satırlar arasını da silebiliriz
$ sed '2,4d' ornek.txt
Bu birinci satır
Dosyanın sadece 2. satırını yazdırmak istersek
$ sed -n 2p ornek.txt
Sonra gelir ikinci
Dosyanın içinde "önceki" kelimesini "evvelki" ile değiştirmek için
$ sed 's/önceki/evvelki/' ornek.txt
Bu birinci satır
Sonra gelir ikinci
Sondan bir evvelki üçüncü
En sonda da dördüncü

Eğer son kesmeden sonra bir sayı gelmiyorsa sadece ilk görülen "önceki" kelimesi "evvelki" ile değiştirilir. En son kesme işaretinden sonra bir sayı geliyorsa, örneğin 2, "önceki" kelimesinin sadece 2. tekrarını "evvelki" ile değiştirir. Eğer kesmeden sonra g geliyorsa tüm tekrarlar değiştirilir.

Bir dosyanın içindeki boşluk karakterlerini yeni satır (carriage return) karakteriyle değiştirmek için

$ sed s/" "/\\n/g ornek.txt

Tüm satırların öncesinde satır numaralarını yazmak için '=' kullanılır (ki bunun alternatifi cat -n dir)

$ sed '=' ornek.txt
1
Bu birinci satır
2
Sonra gelir ikinci

3
Sondan bir önceki üçüncü

4
En sonda da dördüncü
İkinci satırın içeriğini tümüyle değiştirmek istersek
$ sed '3c\BURASI ÜÇÜNCÜ SATIR' ornek.txt
Bu birinci satır
Sonra gelir ikinci
BURASI ÜÇÜNCÜ SATIR
En sonda da dördüncü
Birkaç karakteri değiştirmek:
$ sed 'y/ioü/104/' ornek.txt
B1r1nc1 satır
S0nra gel1r 1k1nc1
S0ndan b1r öncek1 4ç4nc4
En s0nda da dörd4nc4

cut

Bu da çok yetenekli bir metin aracı. Aşağıdaki farazi personel.txt dosyası üzerinden birkaç örnek yapalım.
 
personel.txt
Mazhar Alonson 1950 Ankara
Fuat Güner 1948 İstanbul
Özkan Uğur 1953 İstanbul
 
Bu dosyada boşluk karakteriyle ayrılmış bazı alanlar var; isim, soyisim, doğum yılı, doğum yeri.
 
Sadece isim ve doğu yılını almak için
 
$ cut -d " " -f 1,3 personel.txt
Mazhar 1950
Fuat 1948
Özkan 1953
 
Her satırdan sadece ilk 3 karakteri (byte) almak için
 
$ cut -b 1,3 personel.txt
Maz
Fua
Özk 

-b (byte) ve -c (character) komutlarının farkını göremedim. İkisi de belli sayıda karakter veya byte okumak için kullanılıyor. -d "AYRAÇ" ile alan ayracı belirtilebiliyor. Varsayılan ayraç TAB. -f ile ayrılan alanlardan istenilen numaralı olan (indeksleme 1'den başlıyor) seçilebiliyor.

Bazı ls parametreleri
Bulunduğumuz klasördeki sadece klasörleri görüntülemek için

$ ls -ld */

Listelemede önce klasör isimlerini görmek için
$ ls --group-directories-first

Bir klasörde yer alan dosyaları en son değiştirilme tarihine göre listelemek istersek:
$ ls -lt
kullanabiliriz. Bu şekilde en yeniler en üstte yer alır. Sıralamayı tersine çevirmek için -r (reverse) anahtarını eklemek gerek:
$ ls -ltr
Bunu bütün alt klasörler için yapmak istesek -R anahtarını kullanmak gerek (büyük/küçük harf hassasiyetine dikkat!):
$ ls -ltR

Klasördeki dosyaları boyutlarına göre sıralamak için -S (varsayılan olarak büyükten küçüğe) anahtarı kullanılır:

$ ls -lS | head -5

ile mevcut klasördeki en büyük 5 dosyayı görebiliriz. 

Bir sürecin başlama zamanını ve açık kalma süresini görmek için aşağıdaki komut kullanılabilir [8]:

# ps -eo comm,lstart,etime,user | grep firefox

En çok işlemci kullanan 3 uygulamayı görmek için

# ps -e –sort=-pcpu -o pid,pcpu,comm | head -n 4

Aynı şekilde en çok bellek kullanan 3 uygulamayı görmek için

# ps -e –sort=-pmem -o pid,pmem,comm | head -n 4

find

Bir klasör ve alt klasörlerinde son 24 saatte değişen dosyaları ve klasörleri bulabilmek için şu komut kullanılabilir:

$ find /klasor -mtime -1 -ls
Burada -1 son 24 saat içinde değişenler demek. +1 kullansaydık son 24 saatten önce değişenler anlamına gelecekti. Ayrıca şunun gibi "daha insani" yollar da önerilmiş:
$ find /klasor -newermt "-24 hours" -ls
$ find /klasor -newermt "5 days ago" -ls
$ find /klasor -newermt "yesterday" -ls
Daha iyi bir çıktı için:
$ find /klasor -mtime 0 -printf '%T+\t%s\t%p\n' 2>/dev/null | sort -r | more

gibi bir komuttan bahsedilmiş ki burada dosyalar son değiştirilme tarihi ile listelenecek, bu tarihe göre sıralanacak ve sayfalanacak. Sadece dosyaları görmek istersek -type f ile listelenecek öğe tipini dosya (f) olarak kısıtlayabiliriz. Burada -prinf sonrasındaki alanlar şöyle verilmiş:

%T : Dosyanın son değiştirilme tarihi (yerel saatte)

%s : Byte olarak dosya boyutu

%p : Dosya adı

aralardaki \t tab karakteri, \n ise tahmin edilebileceği gibi yeni satır karakteri.

Bir klasör ve alt klasörleri içinde son 6 ay içinde üzerinde değişiklik yapılmamış dosyaları silmek için

find /hedef -type f -mtime +180 -exec rm -f {} \+

Burada
-type f : sadece dosyaları hedef al
-mtime +180: değiştirilme tarihi 180 günden önce (-180 olsaydı 180 günden sonra olurdu)
-exec rm -f {} : bulunan her öğe için rm (remove) komutunu çalıştır, bunu -f ile (force) destekle
\+ : bunları tek bir satırda toplayarak rm -f dosya1 dosya2 ... dosyaN şeklinde çalıştır
\; olsaydı bu her bir exec işlemini ayrı ayrı yap anlamına gelecekti (rm -f dosya1, rm -f dosya2, .... gibi). Burada \ escape karakteri.

Bir klasörün altındaki tüm boş dosyaları bulmak için

    $ find . -type f -empty

Hatta boş klasörler için

    $ find . -type d -empty

Veya 2 KB'tan büyük dosyaları bulmak için

    $ find . -type f -size +2K

Bir kullanıcının sahip olduğu dosyaları aramak için

    $ find . -user metin
 
lsof (list open files)
Açık dosyaları sorgulamak çoğu durumda çok faydalı olabilir. Hiçbir parametre olmaksızın aşağıdaki gibi bir çıktı üretir.
# lsof
COMMAND PID TID TASKCMD USER FD TYPE DEVICE SIZE/OFF NODE NAME
systemd 1               root cwd DIR 8,3       4096     2 /
systemd 1               root rtd DIR 8,3       4096     2 /
systemd 1               root txt REG 8,3    1640496 14161 /usr/lib/systemd/systemd


Çıkışta geçen FD dosya tanımlayıcısıdır (file descriptor) ve şu değerleri alabilir:
cwd: şimdi bulunulan klasör (current working directory)
rtd : root'un klasörü, yani /root (root directory)
txt : program metni
mem : memory mapped file
r: bir sayı eşliğinde geçen r okuma (read) kipinde açılmış dosyayı gösterir
w: bir sayı eşliğinde geçen w yazma (write) kipinde açılmış dosyayı gösterir
u: yine bir sayı eşliğinde geçer ve yazma ve okuma modunda açılmış dosyayı gösterir
 
TYPE alanı dosya tipini gösterir şu değerleri alabilir:
REG: normal dosya (regular file)
DIR: klasör (directory)
CHR: karakter tipi cihaz (character special file)
FIFO: ilk giren ilk çıkar tipi yapı (first in first out)

Birkaç örnek üzerinden gidelim.

Belli bir kullanıcı tarafından açılan dosyaların listesini almak için
# lsof -u metin
hatta bu kullanıcının açtığı tüm süreçleri sonlandırmak için
# kill -9 `lsof -t -u metin`
veya belli bir kullanıcıyı hariç tutmak için
# lsof -u^root
Ağ bağlantıları içinde dinleme durumunda (listening) ve kurulmuş (established) bağlantıları görmek için
# lsof -i
TCP 25 portunu kullananlar
# lsof -i TCP:25
Protokol farketmeksizin 53 portunu kullanan uygulamalar için
# lsof -i :53
Sadece IPv4 bağlantıları listelemek için
# lsof -i 4
PID'si 1135 olan süreç tarafından açılan dosyaları görmek için
# lsof -p 1135
/var/log/clamav/freshclam.log dosyasını açan prosesi bulmak için
# lsof /var/log/clamav/freshclam.log
/var/log klasöründeki dosyalarla ilgileniyorsak
# lsof +D /var/log

du (disk usage)
Komut satırında çalışırken bir klasörün alt klasörleri ile birlikte diskte ne kadar yer kapladığını bulmak için bu komut ideal. Örneğin Fedora'nın dnf yerel önbelleğinde tutulan dosyaların boyutunu öğrenmek için

$ sudo du -sh /var/cache/dnf/
kullanabiliriz. Burada

-s : tek satırda tüm alt klasörlerle boyutu yaz
-h : byte cinsinden değil, otomatik olarak hangi ölçekteyse KB, MB veya GB cinsinden yaz.

Faydalı bir anahtarı daha var; örneğin tmp uzantılı dosyalar hariç boyutu görmek istiyorsak --exclude="*.tmp" yazabiliriz. 
Bunun sonucunda görülecek sayı dosya yöneticisi ile bakıldığında görülecek sayı ile bir olmayabilir. Bunun sebebi du'nun dosyanın diskte kapladığı yeri göstermesi, dosya yöneticisinin ise dosyaların toplam boyutlarını göstermesidir (aradaki fark; 300 byte'lık bir dosya diskte asgari bir blocksize yer kaplar ki o da muhtemelen 4KB'dır. Sizinkini görmek için blocksize --getbsz /dev/sdaX). Bu durumda dosya yöneticisinin verilerini doğrulamak için
$ find /var/cache/dnf/ -type f -exec ls -l {} \; | awk '{toplam+=$1} END {print toplam}'
kullanılabilir. Bu byte cinsinden verir. du -h anahtarı ile bunu MB veya duruma göre GB cinsinden gösterebilir.

df
Dosya sistemi kullanım oranlarını gösterir. Hiçbir parametre kullanmadan çalıştırınca tüm dosya sistemlerini listeler. Listelenen dosya sistemi türlerini de ayrı bir sütunda görmek için -T anahtarı kullanılabilir.

$ df -T
Dosyasistemi                            Tür       1K-blok     Dolu      Boş Kull% Bağlanılan yer
devtmpfs                                devtmpfs   469808        0   469808    0% /dev
tmpfs                                   tmpfs      488044        0   488044    0% /dev/shm
tmpfs                                   tmpfs      488044     1284   486760    1% /run
/dev/mapper/fedora_localhost--live-root ext4     37868960 10927560 24988020   31% /
tmpfs                                   tmpfs      488044      164   487880    1% /tmp
/dev/sda1                               ext4       999320   235008   695500   26% /boot
tmpfs                                   tmpfs       97608       36    97572    1% /run/user/1000


Listelenecek dosya sistemlerini dosya sistemi türüne göre sınırlandırmak için -t anahtarı ve sonrasında dosya sistemi tipi kullanılabilir:

$ df -t ext4
Dosyasistemi                             1K-blok     Dolu      Boş Kull% Bağlanılan yer
/dev/mapper/fedora_localhost--live-root 37868960 10927560 24988020   31% /
/dev/sda1                                 999320   235008   695500   26% /boot


Veya tam tersi olarak bir dosya sistemini hariç tutarak listelemek için -x ve sonrasında dosya sistemi tipi kullanılabilir.

$ df -T -x tmpfs
Dosyasistemi                            Tür       1K-blok     Dolu      Boş Kull% Bağlanılan yer
devtmpfs                                devtmpfs   469808        0   469808    0% /dev
/dev/mapper/fedora_localhost--live-root ext4     37868960 10927584 24987996   31% /
/dev/sda1                               ext4       999320   235008   695500   26% /boot


less
Bir komutun çıktısını sayfalayarak göstermeye yarayan more komutuna benzer yapıda çalışıyor. Bu komutla ilgili çok sık yapılan bir espri var: "The less is more, more or less". More'a göre daha işlevsel. Kısayollar şöyle:


Kısayol Tuşu
İşlevi
aşağı ok, enter, e, veya j Bir satır aşağı
yukarı ok, y, veya k Bir satır yukarı
boşluk çubuğu
Bir sayfa aşağı
b Bir sayfa yukarı
sağ ok
Yatay sağa kay
sol ok
Yatay sola kay
g İlk satıra git
G Son satıra git
10g 10. satıra git. Farklı sayıla ile istenen satıra gidilebilir
50p veya 50% Tam ortaya (veya başka bir sayı verilerek istenen yüzdelik noktaya) git
/search terim Şu anki noktadan aşağıya doğru terimi ara
?search terim Şu anki noktadan yukarıya doğru terimi ara
n Arama sırasında bir sonraki bulunan noktaya git
N Arama sırasındaki bir önceki bulunan noktaya git
m<c> m'den sonra herhangi bir karakter girerek şu anki konumu işaretle
'<c> Tek tırnak tuşu ile yukarıdaki gibi işaretlenen noktaya git   
q çıkış yap


---
[1] https://likegeeks.com/awk-command/
[2] https://linuxconfig.org/learning-linux-commands-awk
[3] https://www.geeksforgeeks.org/sed-command-in-linux-unix-with-examples/
[4] https://www.linuxtechi.com/20-sed-command-examples-linux-users/
[5] https://likegeeks.com/sed-linux/
[6] https://www.howtogeek.com/562941/how-to-use-the-awk-command-on-linux/ 
[7] https://www.linuxteck.com/find-command-in-linux-with-examples/
[8] https://www.linuxteck.com/ps-command-in-linux-with-examples/
[9] https://medium.com/techtofreedom/8-uses-of-sed-in-linux-e61678b04114

[10] https://medium.com/@hicransevik/some-text-processing-tools-aaac89e89a16

2019-09-13

Powershell ile kullanıcı hesapları yönetimi

Süresi dolan parolalar, yanlış girilince kilitlenen hesaplar... Komut satırından yönetilse fena mı olurdu?

Windows istemci işletim sistemleri için RSAT'ın yüklenişi için şu bağlantıya bakılabilir. Bir kere

PS> Get-Module -ListAvailable
ile ActiveDirectory modülünü gördükten sonra Powershell 3.0 ve üstü sürümlerde Import-Module'e gerek kalmadan doğrudan cmdlet isimlerini yazarak kullanabiliriz.

En sık kullanılabilecek şey parola süresi dolan hesapları görmek olabilir. Search-ADAccount bu amaçlı güzel bir İsviçre çakısı.
PS> Search-ADAccount -PasswordExpired

Parolası dolan hesapları admin tarafından değiştirmek için şu yöntem kullanılabilir:

PS> Set-ADAccountPassword -Identity kullanici.adi
   -Reset
   -NewPassword (ConvertTo-SecureString -AsPlainText "P@ssw0rd!" -Force)

Burada -NewPassword alanı SecureString  tipinde bir veri bekliyor. Bunu sağlamak çin ConvertTo-SecureString cmdlet'ini kullanıyoruz. Ama şifreyi de aynı zamanda okunabilir bir şekilde yazdığımız için ConvertToSecureString cmdlet'i bunu ilk başta çevirmeyi reddedecektir. Bütün bu uyarıları görmezden gelmek için -Force parameteresini kullanmamız gerek. Daha doğru bir yöntemle şöyle de yapabilirdik:

PS> Set-ADAccountPassword -Identity kullanici.adi
   -Reset
   -NewPassword (Read-Host "Yeni parola" -AsSecureString)

Ya da parola süresi asla dolmayacak hesapların listesini almak için

PS> Search-ADAccount -PasswordNeverExpires
olabilir. Account lockout politikasına göre kilitlenmiş hesapları görmek için ise
PS> Search-ADAccount -Lockedout
faydalı olur. Bazı hesapları süreli açarız ve o süre dolduktan sonra hesabın kullanılmamasını isteriz. Bu şekilde süresi dolmuş hesapları görmek için
PS> Search-ADAccount -AccountExpired
ya da süresi haftaya dolacak hesapları görmek için
PS> Search-ADAccount -AccountExpiring -DateTime (Get-Date).AddDays(7)
ve kapatılmış (disabled) hesapları görmek için de
PS> Search-ADAccount -AccountDisabled
kullanılabilir. Bu komutların hepsi çok ayrıntılı sayfalarca veri üretiyorsa daha özet bir veri görmek için Select-Object (veya kısaca select) kullanılabilir. Örneğin son komut için
PS> Search-ADAccount -AccountDisabled | select SamAccountName
olabilir. Search-ADAccount'un yardımına bakınca -ComputersOnly ve -UsersOnly parametrelerini gördüm. Bu cmdlet hem bilgisayar hem de kullanıcı hesaplarını çıkış olarak verdiği için bu parametrelerle sadece bilgisayar veya sadece kullanıcı hesaplarını süzmek mümkün.
PS> Search-ADAccount -AccountDisabled -UsersOnly | select SamAccountName
Son 90 günde kullanılmamış (inactive) hesapları görmek için
PS> Search-ADAccount -AccountInactive
Parola süresi dolmuş bir hesabın parolasını değiştirmek için (net user hesap.adi * /DOM)
PS> Set-ADAccountPassword -Identity kullanici.adi -NewPassword (ConvertTo-SecureString -AsPlainText "..." -Force)
 Evet, bunu bir cmdlet'e çevirmek faydalı olabilir.

Yeni bir Active Directory hesabı yaratmak için: (net user user1 password /add /DOM)
PS> New-ADUser -Name "Kullanıcı Adı" 
   -GivenName "Ön Ad" 
   -Surname "Soyad" 
   -SamAccountName "hesap.adi" 
   -UserPrincipalName "hesap.adi@firmaadi.com" 
   -Path "OU=yoneticiler,DC=firmaadi,DC=com" 
   -AccountPassword(Read-Host -AsSecureString "Parola:")
   -Enabled $true
New-ADUser cmdlet'i ile kullanıcı adı yaratırken parola vermek zorunlu değildir, çünkü ilk yaratılan durumda kullanıcı etkinleştirilmemiş olarak yaratılır. Ya daha sonra parola ataması yapıp (domain password policy'ye uygun olarak) Enable-ADAccount ile kullanıcı etkinleştirilmeli, ya da yukarıdaki gibi hem parola belirtilip hem de -Enable $true parameteresi kullanılmalı. Başka önemli bir nokta ise -AccountPassword parametresi ile SecureString tipinde veri beklenmesi. Buraya "P@ssw0rd" gibi bir parola veremeyiz. Ama illaki önceden belirlenmiş bir parola verilecekse
  -AccountPassword (ConverTo-SecureString "P@ssw0rd" -AsPlainText -Force)
kullanılabilir.

Mevcut bir hesabı görmek için (net user hesap.adi /DOM)
PS> Get-ADUser -Identity "hesap.adi"
ya da hesabı bir sorgu ile bulmak için
PS> Get-ADUser -Filter {Name -like "murat*"}
Var olan bir kullanıcı hesabını silmek için (net user hesap.adi /Del /DOM)
PS> Remove-ADUser -Identity "hesap.adi"
Mevcut bir hesabın son kullanım tarihini 3 ay olarak belirlemek için
PS> Set-ADAccountExpiration hesap.adi -DateTime (Get-Date).AddMonths(3)
Tam  tersi, hesap üzerindeki son kullanma tarihini kaldırarak süresiz kullanılabilmesini sağlamak için
PS> Clear-ADAccountExpiration -Identity hesap.adi
Var olan bir hesabı kullanıma kapatmak için (disable, net user hesap.adi /DOM /active:no)
PS> Disable-ADAccount -Identity hesap.adi
Ya da tekrar etkinleştirmek için (net user hesap.adi /DOM /active:yes)
PS> Enable-ADAccount -Identity hesap.adi
Lockout olmuş bir hesabı tekrar kullanıma açmak için
PS> Unlock-ADAccount -Identity hesap.adi

Ya da unlock olmuş hesapları tek satırda bulup onları unlock etmek için

PS> Search-ADAccount - Lockedout | Unlock-ADAccount

 Active Directory modülü ile gelen benzer komutları aramak için

PS> Get-Command -Noun ADAccount*

veya

PS> Get-Command -Module ActiveDirectory

 kullanılabilir. Benzer şekilde grup işlemleri ile ilgili

PS> Get-Command -Noun ADGroup*
yazdığımda birkaç grup cmdlet'i buldum. Birkaç grup işlemi için de örnek yapayım.

Mail ile başlayan grupları bulmak için
PS> Get-ADGroup -Filter {Name -like 'Mail*'}

Bir kullanıcının grup üyeliklerini görmek için ise

PS> Get-ADPrincipalGroupMembership -Identity kullanici.adi

Bir grubun üyelerini görmek için (net group GrupAdi /DOM)
PS> Get-ADGroupMember Administrators
Veya bir kullanıcıyı gruba eklemek için (net group GrupAdi hesap.adi /DOM /ADD)
PS> Add-ADGroupMember -Identity GrupAdi -Members hesap.adi
Ve hatta bir kullanıcıyı grup üyeliğinden çıkarmak için (net group GrupAdi hesap.adi /DOM /DEL)
PS> Remove-ADGroupMember -Identity GrupAdi -Members hesap.adi -Confirm

Bu komut, kullanıcıyı gruptan çıkarmadan önce onaylama isteyecektir. Sondaki -Confirm bu onayı peşinen vermek için.

Evet, komut isimleri uzun, parametreler ve ek yönlendirmelerle gayet uzun komutlara dönüşebiliyorlar. Bunun için yeni alias'lar tanımlanabilir, ya da amaca özel yeni cmdlet'ler oluşturulabilir.

2022-08-25 Ek: Yerel hesaplar için de powershell gibisi yok. Yeni bir yerel hesap yaratmak için

PS> New-LocalUser -Name fatih -FullName 'Fatih Terim'

Bu komutu çalıştırdıktan sonra bir parola sorar. Parolasız bir kullanıcı oluşturmak istiyorsak -NoPassword kullanabilir, veya parolayı -Password argumanı ile vermek istiyorsak da Read-host -AsSecureString ile yapabiliriz. Ayrıca -AccountExpires ve -Desription gibi argümanlar da var. Parolasız oluşturulan hesabın parolasını daha sonra oluşturmak için

PS> Set-LocalUser -Name fatih -Password (Readhost "Parola?" -AsSecureString)

Bir kullanıcının parolasının süresiz olmasını sağlamak için

PS> Set-LocalUser -Name fatih -PasswordNeverExpires $true

Parolanın süreli olması için $true yerine $false yazılmalı. Ama parolanın süresini belirlemenin powershell ile bir yolu yok. Bu ayar kullanıcı başına belirlenen bir ayar değil. Bunu değiştirmek için

net /maxpwage:30

Yerel kullanıcı hesaplarının yönetilmesinde kullanılabilecek diğer cmdlet'ler ise şöyle:

PS> Enable-LocalUser -Name fatih

PS> Disable-LocalUser -Name fatih

PS> Remove-LocalUser -Name fatih

PS> Rename-LocalUser -Name Fatih -NewName FatihTerim

Yeni oluşturulan bir hesabı var olan bir gruba, örneğin Administrators grubuna üye yapmak için

PS> Add-LocalGroupMember -Group Administrators -Member fatih

kullanabiliriz. Yeni bir grup oluşturmak için New-LocalGroup, grup veya kullanıcı hesabını silmek için ise bu cmdlet'lerin Remove'larını, yani Remove-LocalGroup veya Remove-LocalUser kullanabiliriz.

Bonus
Eskiden, Windows sunucu etki alanı üyesi bir bilgisayarın ismini değiştirmek istediğimizde önce etki alanından çıkartıp, sonra ismini değiştirip sonra tekrar etki alanı üyesi yapardık. Bunun için de 3 kez terar başlatmak gerekirdi. Windows 7 sonrasında artık bu işi etki alanından çıkarmadan yapabileceğimizi duymuştum ama denememiştim. Bu şerefe powershell ile nail oldum. Aşağıdaki şekilde uzaktaki bir bilgsayara yeni bir isim vermek çok büyük kolaylık.

PS> Rename-Computer -ComputerName eskiadi -NewName yeniadi -Restart -Force -DomainCredential (Get-Credential)
Burada:
-ComputerName: hangi bilgisayarda yeniden adlandırma işlemi uygulanacak
-NewName: bilgisayarın yeni ismi ne olacak
-Force: Emin misiniz? gibi sorulara baştan "evet" diye cevap vermek için
-Restart: Yeniden adlandırma işleminin geçerli olması için hemen ardından yeniden başlatmaya zorlamak için. Bu parametre kullanılmazsa yeniden başlatma kullanıcının insiyatifinde olacak. Bilgisayar özelliklerinde de yeniden başlatma sonrası bilgisayarın yeni adının ne olacağına dair bir bilgilendirme mesajı görüntülenecek.
-DomainCredential: Etki alanında bu işlemi yapmak için yetkisi olan bir kullanıcı hesabını bildirmek için
-(Get-Credential): Grafik arayüz ile kullanıcı adı ve şifrenin girilebilmesi için

Bununla birlikte bilgisayarın yeni ismi şu anda ağda mevcut bir isim olamaz. Yeniden adlandırma öncesinde etki alanında bu isme sahip bir bilgisayar var mı diye bakabiliriz:
PS> Get-ADComputer -Identity yeniadi
ya da daha geniş bir arama için isim filtresi kullanarak
PS> Get-ADComputer -Filter 'Name -like "*ad*"'
ve eğer mevcutta böyle bir bilgisayar varsa o eski hesabı silmek için (kullanılmayan, eski bir hesap ise)
PS> Get-ADComputer -Identity yeniadi | Remove-ADComputer -Credential (Get-Credential)

2019-08-16

Yeni sistemlerde komut satırından IP yapılandırması

Eskiden ifconfig vardı. Artık bu paket bazı sistemlerde kurulu gelmiyor. Onun yerini ip komutu aldı. Bununla birlikte ağ arayüzlerindeki isimler de küçük bir değişime uğradı. Eskisi gibi eth0, wlan1 gibi isimler yok, onun yerine ens33 ya da enp2s0 gibi isimler var. Sanıyorum bunların hepsi altyapıda systemd'nin itiş gücü ile olan değişiklikler.

Bir sistemdeki IP yapılandırmasını görmek için (parantez içindeki kısaltılmış şekli)
$ ip address show (ip a)
Daha özel olarak belli bir arayüze ait IP yapılandırması için
$ ip address show dev ens33 (ip a s ens33)
diyebiliriz. Bir ağ bağlantısının durumunu görmek için
$ ip link show ens33 (ip l sh ens33)
ens33 arayüzü üzerinde yeni bir IP adresi ataması yapmak için
$ sudo ip addr add 192.168.1.1/24 dev ens33
Az önce yaptığımız IP adresi atamasını kaldırmak için
$ sudo ip addr del 192.168.1.1/24 dev ens33
Ağ arayüzü üzerindeki tüm yapıladırmayı kaldırmak için
$ sudo ip addr flush dev ens33
Ağ arayüzü için varsayılan ağ geçidi tanımlamak için
$ sudo ip route add default via 192.168.1.100
Az önce yaptığımız varsayılan ağ geçidi tanımlamasını silmek için
$ sudo ip route del default via 192.168.1.100
Yeni bir statik route eklemek için (bir sonraki tekrar başlatmada silinir)
$ sudo ip route add 192.168.7.0/24 via 192.168.1.200 dev ens33
Bu route'un bir sonraki tekrar başlatma sonrasında da geçerli olmasını istiyorsak /etc/sysconfig/network-scripts/route-eth0 dosyasına (Fedora için)
10.10.20.0/24 via 192.168.50.100 dev eth0
eklemek, Debian ve türevleri için (2018 öncesi) ise /etc/network/interfaces dosyasına
up ip route add 10.10.20.0/24 via 192.168.50.100 dev eth0
eklemek gerek. Sonrasında da
$ sudo systemctl restart systemd-networkd.service

ile ağ hizmetlerini tekrar başlatmak gerek. Ubuntu 18.04 sonrası ve muhtemelen ilgili Debian dağıtımlarında ise NetPlan kullanılıyor. Bu durumda yapılacaklar için tıklayın.

Mevcut route tablosunu görüntülemek için

$ ip route show
Bir arayüzü pasif duruma getirmek için
$ sudo ip link set ens33 down
Tekrar etkinleştirmek için
$ sudo ip link set eth1 up
ARP cache'ini görüntülemek için
$ ip neighbor
Özellikle DHCP tarafından atanmış DNS sunucuları bulmak için:
$ resolvctl dns
Ve hatta DHCP'nin adresini bulmak için
$ journalctl -b -g DHCPACK
veya
$ sudo grep -IR "DHCPOFFER" /var/log/*

olabilir. Bu da olmazsa dhclient aracını kullanarak atanmış adresi değiştirme talebiyle bir DHCPDISCOVER gönderilir. Bunun sonucunda ortamdaki DHCP sunucusu da bize DHCPOFFER ile bir IP adresi teklif eder, bizim makinemiz de DHCPACK ile bunu kabul eder, aşağıdaki gibi

# dhclient -d -nw enp3s0
Internet Systems Consortium DHCP Client 4.4.2b1
Copyright 2004-2019 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/enp3s0/38:60:77:42:4e:32
Sending on   LPF/enp3s0/38:60:77:42:4e:32
Sending on   Socket/fallback
DHCPDISCOVER on enp3s0 to 255.255.255.255 port 67 interval 7 (xid=0xb59d4262)
DHCPOFFER of 192.168.0.25 from 192.168.0.1
DHCPREQUEST for 192.168.0.25 on enp3s0 to 255.255.255.255 port 67 (xid=0xb59d4262)
DHCPACK of 192.168.0.25 from 192.168.0.1 (xid=0xb59d4262)
/usr/sbin/dhclient-script: line 706: /etc/resolv.conf: Permission denied
bound to 192.168.0.25 -- renewal in 254332 seconds.

2019-08-15

Linux hizmetleri ve systemd

sysemd, linux dünyasında çok tartışılan bir konu. Ama birçok dağıtım da bunu kullanmaya başladı. Ben daha çok bu bileşen ile linux'ta hizmetlerin nasıl yönetileceğine değineceğim.

Öncelikle systemctl komutuna terminalde aldığınız cevap
systemctl is not installed
gibi birşey olursa muhtemelen systemd dışında bir init sistemi kullanan bir linux dağıtımıyla karşı karşıyayız demektir.

Çalışan hizmetlerin bir listesini almak için kullanılacak komut
systemctl list-units
olacaktır. Systemctl yardım sayfasında hafızadaki birimleri listeler denmiş. Bu komut varsayılan olarak etkin birimleri (unit) listeler. Bunun yerine sadece
systemctl
ile de aynı şeyi yapabiliriz. Bu komut ile listelenen tablodaki LOAD, ACTIVE ve SUB sütunlarında yer alan değerlerin anlamları şöyledir:

LOAD: loaded / not-found / bad-setting / error / masked. ilgili birim dosyası bulundu ve yüklendi veya bulunamadı, kötü yapılandırma, hata, maskelenme.

ACTIVE: active / inactive. birimin durumu; etkin veya değil.

SUB (substate): running / dead / exited / plugged / mounted. Bu sütunda yer alan değerler ACTIVE sütununda verilen durum bilgisi ile ilgili daha ayrıntı vermek için kullanılır. Değerler sistemden sisteme, sürümden sürüme değişebilir. Tam listeyi görmek için systemctl --state=help kullanılabilir.

unit olarak ifade edilen birimler hizmetler olabildiği gibi soketler, zamanlayıcılar da olabilir. Systemd'nin haberdar olduğu tüm birim dosyalarını listelemek için
systemctl list-unit-files
kullanılabilir. Bunların içinden sadece hizmetlere ait birim dosyalarını listelemek için
systemctl list-unit-files --type=service

kullanılır. Bu komut sonucunda STATE sütununda görülebilecek değerlerin anlamları şöyle olur:

enabled: etkin birim
disabled: etkin olmayan birim

static: Birim dosyasında birimin etkinleştirilmesi için bir "kurulum" (install) bölümü yok demektir. Bu gibi birimler ya başka bir birimin bağımlılığı olarak başlar ve dururlar, etkinleştirilemezler.

masked: etkinleştirilmesi bile engellenmiş birimler.

Bir birimin özelliklerini görmek için

systemctl show docker.service

Bu komutla bir sürü özellik listelenir. Sadece bir özellik için -p <property> gibi özellik değeri listelenebilir. 

systemctl show docker.service -p Type

Bir birime ait yapılandırma dosyasını görmek için

systemctl cat docker.service
komutunu kullanabiliriz. Genel olarak birim adının noktadan sonraki .service son ekini atlayarak
systemctl cat docker
kullanabiliriz.

Sırasıya bir hizmeti (servis) durdurmak, başlatmak ve yeniden başlatmak için aşağıdaki komutlar kullanılır:
systemctl stop docker
systemctl start docker
systemctl restart docker
Bazı birimler reload komutunu destekler. Restart'tan farklı olarak bu komut sadece değişen yapılandırma dosyalarını tekrar yükler ve hizmeti ayarları duraksamadan değiştirilebilir.
systemctl reload docker
Bir hizmeti etkinleştirmek veya tersi için
systemctl enable docker
systemctl disable docker
kullanılır. Bir hizmetin durumunu görmek için
systemctl status docker
veya kısaca etkin olup olmadığını görmek için
systemctl is-enabled docker
ya da
systemctl is-failed docker

kullanılabilir.

Sorun çıkaran birimler/hizmetleri görebilmek için

systemctl --failed

list-unit-files ile sistemdeki etkin olan veya olmayan tüm birim dosyaları listelendi. Peki sistemdeki aktif birimleri (units) görmek için ne yapılabilir? Elbette

systemctl list-unit-files --state=enabled
gibi bir komut kullanılabilir ama etkinleştirilmiş ama mevcut durumu "çalışıyor"dan farklı olan tüm birimleri görmek için ilk başta yazdığım gibi şu komut daha uygun:
systemctl list-units
ya da, hiçbir parametre kullanmadan sadece systemctl de aynı işi yapıyor. [1]'de list-units ve list-unit-files arasındaki fark için şöyle denmiş:
"list-units, sadece systemd'nin gerekli görüp hafızaya aldığı birim dosyalarını listeler."
Bu durumda list-units'in, list-unit-files'ın bir altkümesini listelediğini düşünebiliriz. Aynı kaynakta birim için de şöyle bir tanım yapılmış:
"Birimler, systemd'nin bildiği kaynakların temsil edildiği dosyalardır."
Bir birimin bağımlılıklarını görmek için
systemctl list-dependencies docker

kullanılabilir.

2022-08-01 Ek:

systemctl status komutuyla çalışan, hata vermiş ve devre dışı bırakılmış birimlerin durumlarını ayırt edebilmek için bazı örnekler:

Aktif ve çalışan bir hizmet:

Aktive (running) yazar, altında çalışan sürecin PID'si ve kullandığı bellek (Memory) miktarı yazar. Durumunda "loaded active running" gibi ifade olur. Etkin bir birimin Loaded: satırında ise aşağıdaki sarı ile vurgulanan alandaki gibi enabled yazar. Devre dışı bırakılmış bir birim için burada disabled yazar.

crond.service                        loaded active running

● crond.service - Command Scheduler

     Loaded: loaded (/usr/lib/systemd/system/crond.service; enabled; vendor preset: enabled)

     Active: active (running) since Tue 2021-01-05 09:27:47 +03; 1h 25min ago

   Main PID: 956 (crond)r

      Tasks: 1 (limit: 2294)

     Memory: 1.7M

        CPU: 150ms

     CGroup: /system.slice/crond.service

             └─956 /usr/sbin/crond -n


Oca 05 10:01:01 localhost.localdomain anacron[15910]: Anacron started on 2021-01-05

Oca 05 10:01:01 localhost.localdomain run-parts[15912]: (/etc/cron.hourly) finished 0anacron

Oca 05 10:01:01 localhost.localdomain anacron[15910]: Will run job `cron.daily' in 30 min.

Oca 05 10:01:01 localhost.localdomain anacron[15910]: Will run job `cron.weekly' in 50 min.

Oca 05 10:01:01 localhost.localdomain anacron[15910]: Jobs will be executed sequentially

Oca 05 10:31:01 localhost.localdomain anacron[15910]: Job `cron.daily' started

Oca 05 10:31:01 localhost.localdomain anacron[15910]: Job `cron.daily' terminated

Oca 05 10:51:01 localhost.localdomain anacron[15910]: Job `cron.weekly' started

Oca 05 10:51:01 localhost.localdomain anacron[15910]: Job `cron.weekly' terminated

Oca 05 10:51:01 localhost.localdomain anacron[15910]: Normal exit (2 jobs run)

---

Sonlanmış (durmuş) bir hizmet: 

● bluetooth.service - Bluetooth service            loaded inactive dead

     Loaded: loaded (/usr/lib/systemd/system/bluetooth.service; enabled; vendor preset: enabled)

     Active: inactive (dead)

       Docs: man:bluetoothd(8)


Oca 08 21:52:51 ozm-fed systemd[1]: Condition check resulted in Bluetooth service being skipped.

Çalışmış ve ihtiyaç olmadığı için sonlanmış bir hizmet:

Active (exited) yazar. Bellek kullanımı sıfırdır. Durum bilgisi "loaded active exited" gibi bir ifadedir.

systemd-journal-flush.service                loaded active exited

● systemd-journal-flush.service - Flush Journal to Persistent Storage

     Loaded: loaded (/usr/lib/systemd/system/systemd-journal-flush.service; static; vendor preset: disabled)

     Active: active (exited) since Tue 2021-01-05 09:27:09 +03; 1h 23min ago

       Docs: man:systemd-journald.service(8)

             man:journald.conf(5)

   Main PID: 587 (code=exited, status=0/SUCCESS)

      Tasks: 0 (limit: 2294) 

     Memory: 0B

        CPU: 0

     CGroup: /system.slice/systemd-journal-flush.service


Oca 05 09:26:59 localhost.localdomain systemd[1]: Starting Flush Journal to Persistent Storage...

Oca 05 09:27:09 localhost.localdomain systemd[1]: Finished Flush Journal to Persistent Storage.

Hata vermiş ve çalışmayan bir hizmet:

Active: failed yazar. sonrasında bir exit-code, altında CPU ve Memory alanları olmaz. Durumda "loaded failed failed" gibi bir ifade olur. Alıntılanan journalctl loglarında ayrıntı verilir.

initial-setup.service                    loaded failed failed

● initial-setup.service - Initial Setup configuration program

     Loaded: loaded (/usr/lib/systemd/system/initial-setup.service; enabled; vendor preset: disabled)

     Active: failed (Result: exit-code) since Tue 2021-01-05 09:27:30 +03; 1h 14min ago

        CPU: 5ms


Oca 05 09:27:29 localhost.localdomain systemd[1]: Starting Initial Setup configuration program...

Oca 05 09:27:30 localhost.localdomain kill[739]: kill: geçersiz sinyal adı ya da numarası: SIGRTMIN+21

Oca 05 09:27:30 localhost.localdomain systemd[1]: initial-setup.service: Control process exited, code=exited, status=1/FAILURE

Oca 05 09:27:30 localhost.localdomain systemd[1]: initial-setup.service: Failed with result 'exit-code'.

Oca 05 09:27:30 localhost.localdomain systemd[1]: Failed to start Initial Setup configuration program.

Hata vermiş ve çalışmayan bir hizmet:


---

[1] https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
[2] https://wiki.archlinux.org/index.php/Systemd

[3] https://adamtheautomator.com/ubuntu-systemctl/

2019-05-02

DuckDuckGo'dan emin miyiz?

Bir süredir arama motoru olarak DuckDuckGo'yu kullanıyorum. Neredeyse her kanaldan, belli bir bilişim altyapısına sahip ve gizlilik farklındalığına sahip bireyler için bu konu ile ilgili "Google kötü, DuckDuckGo iyi" türünden haberler pompalanıyor. DuckDuckGo da anasayfasında da belirttiği gibi şu konuları vurguluyor:
  • Gizliliğinize önem veriyoruz.
  • Kişisel bilgilerinizi asla kaydetmiyoruz.
  • Sizi reklamlarla veya başka yöntemlerle takip etmiyoruz.
  • Aramalarınızı kaydetmiyoruz, bunları bir yerde kullanmıyoruz.

Ancak bugün Reddit'in /r/privacy subreddit'inde rastladığım şu gönderinin altında rainthunder tarafından yapılan yorum ilginç geldi. Yoruma DuckDuckGo'nun gizliliğimizi ihlal ettiğine dair bir kanıtın olmadığından, ama bununla ilgili çok şüpheli şeyler olduğundan bahsederek başlamış. Bu yorumda bahsedilenleri özetlemek istiyorum:
  1. DuckDuckGo kurucusu Gabriel Weinberg'in Names veritabanını (çalışmak için başkalarının eposta adreslerinin paylaşılmasına dayalı bir sistem) işlettiği, böyle bir geçmişe sahip bir kişinin DuckDuckGo gibi gizlilik tabanlı bir işe girmesinin çok şüpheli olduğunu söylemiş.
  2. DuckDuckGo'nun söylediğinin aksine, bir takip etme amaçlı çerez (tracking cookie) ile kullanıcılarını takip ettiğini, bunu da bizzat kendisinin değil, birlikte çalıştığı üçüncü parti bir şirket aracılığıyla yaptığını söylemiş ve şöyle demiş: "Bu iş bilinçli bir şekilde yapılmış olmayabilir. Ama bilinçsiz bir şekilde yapılmışsa bile gizlilik konusuna bu kadar vurgu yapılan bir durumda söz ile fiiliyatın arasında ciddi bir fark var demektir."
  3. DuckDuckGo'nun Yahoo (Verizon tarafından işletilen) ile ortaklığının olduğunu, Verizon'un ise gizlilik konusunda pek de hassas davranmayan, hatta kullanıcı verilerini sürekli satan bir çalışma şekline sahip olduğundan bahsetmiş.
  4. Her durumda açık kaynak kodlu yazılım kullandıklarının vurgusunun yapıldığından, ama aslında kısmi olarak açık kaynak kodlu olduğundan bahsetmiş. İşin çekirdeğindeki ana bileşenlerin kapalı kaynak kodlu olduğunu, bunun sonucu olarak da işin merkezinde yapılanların gizliliğe ne kadar saygı gösterdiklerini görmenin bir yolunun olmadığını, elimizden gelen tek şeyin DuckDuckGo'nun SÖZÜNE GÜVENMEK olduğunu, geçmişi ile ilgili şüpheli noktalar olan birinin de sözüne çok güvenilemeyeceğini söylemiş.
  5. Geçtiğimiz haftalarda kullanıcılarını takip ettiğine dair bazı ihtilaflar olduğu, ancak bu konuda da onların SÖZÜNE GÜVENMEKTEN başka çarenin olmadığı belirtilmiş.
Diğer yorumlarda da alternatif arama motoru olarak Searx.com (açık kaynak kodlu ve merkezi olmayan bir yapıda çalışan ve ABD sınırlarında olmayan) veya Qwant.com (Avrupa Birliği sınırlarında faaliyet gösteren) önerilmiş.

İşin özü süreç şu şekilde işliyor: Birileri biryerlerde yeni açık kaynak kodlu ve gizliliğe önem veren bir arama motoru olduğunu söylüyor, yavaş yavaş, zaman içinde bir sürü insan o arama motorunu benimseyip kullanmaya başlıyor. Sayılar ciddi bir miktara ulaştığında ise başka biri geliyor "aslında o kadar da açık kaynak kodlu değil" ya da "bunlar da bizi takip ediyor" gibi iddialarda bulunuyor. Bu süreç tekrarlanıyor. Gücü eline geçirenin daha önce söylediklerini unutması/yutması bu dünyanın kuralı!