Author: anilaras

  • firewall-cmd ve Firewalld Mimarisi

    firewall-cmd ve Firewalld Mimarisi

    Linux sunucu yönetiminde güvenlik, opsiyonel bir özellik değil, bir zorunluluktur. Yıllarca iptables komut zincirleri ile boğuştuktan sonra, modern Linux dağıtımları (RHEL 7+, CentOS 7+, Fedora, Suse vb.) daha dinamik ve yönetilebilir bir çözüm olan Firewalld servisine geçiş yaptı.

    Bu makalede, Firewalld servisinin yönetim aracı olan firewall-cmd komutunu, mimarisini, “Zone” kavramını ve gerçek hayat senaryolarında nasıl kullanılacağını en ince detayına kadar inceleyeceğiz.

    Firewalld Nedir ve Neden İhtiyacımız Var?

    Geleneksel iptables veya onun modern hali nftables, paket filtreleme işlemini çekirdek seviyesinde (kernel space) yapar. Ancak bu araçların kurallarını yönetmek statiktir. Yani bir kural setini değiştirmek için genellikle güvenlik duvarını “flush” (tüm kuralları silip yeniden yükleme) yapmak gerekir. Bu işlem sırasında saniyelik de olsa bağlantı kayıpları yaşanabilir.

    Firewalld ise, çekirdek paket filtreleme mekanizmalarının (netfilter/nftables) üzerinde çalışan dinamik bir yönetim katmanıdır. En büyük avantajı, D-Bus arayüzü sayesinde kuralları dinamik olarak yönetebilmesidir. Yani çalışan sisteme, mevcut bağlantıları koparmadan yeni bir kural ekleyebilir veya çıkarabilirsiniz.

    firewall-cmd ise bu servisi terminal üzerinden yönetmemizi sağlayan istemci (client) aracıdır.

    Temel Kavram: Zones (Bölgeler)

    Firewalld mantığını anlamak için “Zone” kavramını içselleştirmek gerekir. Firewalld, ağ arayüzlerinizi (network interfaces) ve kaynaklarınızı farklı güvenlik seviyelerine ayırır. Bir sunucunun dış dünyaya bakan bacağı (eth0) ile yerel ağa bakan bacağı (eth1) aynı güvenlik kurallarına tabi olmamalıdır.

    İşte en sık kullanılan bölgeler ve anlamları:

    • drop: En paranoyak seviyedir. Gelen tüm paketleri reddeder ve karşı tarafa hiçbir cevap (ICMP hatası dahil) dönmez. Sadece dışarı giden (outgoing) bağlantılara izin verilir.
    • block: Gelen bağlantıları reddeder ancak karşı tarafa “IPv4 için icmp-host-prohibited” hatası döner. Karşı taraf, portun kapalı olduğunu anlar ama zaman aşımına uğramaz.
    • public: (Varsayılan) Halka açık alanlarda kullanım içindir. Bilgisayarınıza gelen bağlantılara güvenmezsiniz. Sadece seçtiğiniz portlar açıktır.
    • internal: İç ağlar içindir. Ağdaki diğer bilgisayarlara çoğunlukla güvenirsiniz.
    • trusted: Tüm ağ bağlantılarına izin verilir. (Dikkatli kullanılmalıdır).

    Kurulum ve Servis Kontrolü

    Çoğu modern dağıtımda yüklü gelir, ancak emin olmak ve başlatmak için aşağıdaki adımları izleyin.

    Durum Kontrolü:

    sudo systemctl status firewalld
    sudo firewall-cmd --state
    

    Varsayılan Bölgeyi Öğrenme: Sistemin, yeni bir ağ arayüzü eklendiğinde onu hangi bölgeye atayacağını gösterir.

    sudo firewall-cmd --get-default-zone
    # Çıktı genellikle: public
    

    Aktif Bölgeleri Listeleme: Hangi ağ kartının hangi bölgeye bağlı olduğunu görmek için kritiktir.

    sudo firewall-cmd --get-active-zones
    

    Örnek Çıktı:

    public
      interfaces: eth0 wlan0
    docker
      interfaces: docker0

    Kural Yönetimi: Runtime vs. Permanent

    Firewalld kullanırken yapılan en büyük hata, kuralların kalıcılığını karıştırmaktır.

    1. Runtime (Geçici) Yapılandırma: Komutu yazdığınız an etkindir ancak sunucu yeniden başlatıldığında veya firewalld servisi reload edildiğinde silinir. Test amaçlı kullanılır.
    2. Permanent (Kalıcı) Yapılandırma: --permanent parametresi ile yapılır. Ayarlar /etc/firewalld/zones/ altındaki XML dosyalarına yazılır. Ancak komutu yazdığınız an devreye girmez; reload gerektirir.

    Altın Kural: Bir ayarı kalıcı yapmak istiyorsanız --permanent kullanın ve ardından --reload yapın.

    Uygulamalı Kural Yönetimi

    1. Servis Bazlı İzinler (Önerilen Yöntem)

    Port numaralarını (örn. 80, 443, 22) ezberlemek yerine servis isimlerini kullanmak daha yönetilebilirdir. Firewalld, /usr/lib/firewalld/services/ altında yüzlerce servisi tanımlı tutar.

    Mevcut servisleri listeleme:

    sudo firewall-cmd --get-services

    HTTP ve HTTPS servisine izin verme (Kalıcı):

    sudo firewall-cmd --permanent --add-service=http
    sudo firewall-cmd --permanent --add-service=https
    sudo firewall-cmd --reload

    Bir servisi kaldırma:

    sudo firewall-cmd --permanent --remove-service=http
    sudo firewall-cmd --reload

    2. Port Bazlı İzinler

    Tanımlı olmayan özel bir uygulamanız varsa (örneğin 8080 portunda çalışan bir Node.js uygulaması), doğrudan port açabilirsiniz.

    TCP 8080 portunu açma:

    sudo firewall-cmd --permanent --add-port=8080/tcp
    sudo firewall-cmd --reload

    Bir port aralığını açma (Örn: 5000-5100 arası):

    sudo firewall-cmd --permanent --add-port=5000-5100/tcp
    sudo firewall-cmd --reload

    3. Yapılandırmayı Kontrol Etme

    sudo firewall-cmd --list-all

    Örnek Çıktı:

    public (active)
      target: default
      icmp-block-inversion: no
      interfaces: eth0
      sources:
      services: cockpit dhcpv6-client http ssh
      ports: 8080/tcp
      protocols:
      masquerade: no

    İleri Seviye Özellikler

    Sıradan port açıp kapatmanın ötesine geçmek isteyenler için Firewalld güçlü araçlar sunar.

    Rich Rules (Zengin Kurallar)

    Standart kurallar “herkese açık” veya “herkese kapalı” mantığındadır. Ancak “Sadece X IP adresi SSH yapabilsin, diğerleri yapamasın” demek istiyorsanız Rich Rules kullanmalısınız.

    Senaryo: Sadece 192.168.1.50 IP adresinden gelen SSH bağlantılarına izin ver, diğerlerini reddet.

    Önce varsayılan SSH servisini kaldıralım (dikkat, bağlantınız kopabilir, bunu konsoldan veya dikkatli yapın):

    sudo firewall-cmd --permanent --remove-service=ssh

    Ardından özel kuralı ekleyelim:

    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.50" service name="ssh" accept'
    sudo firewall-cmd --reload

    Loglama ile Reddetme: Belirli bir alt ağdan gelen trafiği reddetmek ve bunu loglara kaydetmek istiyorsanız:

    sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="10.0.0.0/24" service name="http" log prefix="HTTP_BLOCK: " level="info" reject'

    Port Yönlendirme (Port Forwarding)

    Sunucunuza gelen trafiği farklı bir porta veya tamamen farklı bir sunucuya yönlendirebilirsiniz (NAT).

    Örnek: Dışarıdan 80. porta gelen isteği, içeride 8080. portta çalışan uygulamaya yönlendirme.

    Önce “masquerade” özelliğini açmalıyız:

    sudo firewall-cmd --permanent --add-masquerade

    Ardından yönlendirme kuralı:

    sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
    sudo firewall-cmd --reload

    Panic Mode (Panik Modu)

    Sisteminiz saldırı altındaysa veya ağ trafiğinde şüpheli bir durum fark ettiyseniz, kabloyu çekmek yerine yazılımsal olarak tüm trafiği kesebilirsiniz.

    Aktif etme:

    sudo firewall-cmd --panic-on

    Not: Bu komut SSH bağlantınızı da koparır! Sadece fiziksel erişiminiz varsa veya konsol bağlantınız varsa kullanın.

    Kapatma:

    sudo firewall-cmd --panic-off

    İpuçları ve Sorun Giderme

    1. Conf Dosyaları: Tüm kalıcı ayarlar /etc/firewalld/zones/ altında .xml dosyaları olarak saklanır. Bu dosyaları yedeklemek, firewall kurallarınızı yedeklemek anlamına gelir.
    2. Runtime to Permanent: Eğer test ederken (runtime) birçok kural eklediniz ve bunların hepsini beğendiyseniz, tek tek --permanent ile yazmak yerine şu komutu kullanabilirsiniz:
      sudo firewall-cmd –runtime-to-permanent
    3. Öncelik: Rich Rules, standart kurallardan önce işlenir. Sıralama önemlidir.

    Firewalld ve firewall-cmd, modern Linux sistem yöneticisinin çantasındaki en değerli araçlardan biridir. Esnek yapısı, XML tabanlı yönetimi ve D-Bus entegrasyonu ile sunucu güvenliğinizi sağlam temellere oturtmanızı sağlar.

  • cURL

    cURL

    cURL (Client URL), geliştiricilerin ve sistem yöneticilerinin veri transferi için kullandığı en popüler ve güçlü komut satırı araçlarından biridir. Genellikle “İnternetin İsviçre Çakısı” olarak adlandırılır.


    1. cURL Nedir?

    cURL, URL (Uniform Resource Locator) sözdizimini kullanarak sunucudan sunucuya veya istemciden sunucuya veri aktarımı sağlayan bir komut satırı aracı ve kütüphanesidir.

    • Desteklediği Protokoller: HTTP, HTTPS, FTP, FTPS, SFTP, SCP, SMTP, POP3, IMAP, LDAP ve daha fazlasını destekler.
    • Platformlar: Linux, macOS ve Windows (CMD/PowerShell) üzerinde varsayılan olarak gelir veya kolayca kurulabilir.

    2. Nerede ve Ne İçin Kullanılır?

    cURL genellikle şu senaryolarda kullanılır:

    • API Testleri: REST API’lere istek atmak (GET, POST, PUT, DELETE) ve dönen JSON/XML yanıtlarını incelemek.
    • Hata Ayıklama (Debugging): Bir web sitesinin HTTP başlıklarını (headers), yönlendirmelerini veya SSL sertifikalarını kontrol etmek.
    • Dosya İndirme/Yükleme: Komut satırı üzerinden dosya transferi yapmak.
    • Otomasyon: Shell scriptleri içinde web servisleriyle haberleşmek için kullanılır.

    3. Temel Kullanım ve Örnekler

    En basit haliyle cURL, bir web sayfasının kaynak kodunu (HTML) terminale döker.

    curl https://www.google.com

    Ancak cURL’ün gerçek gücü parametrelerinde (flag) saklıdır. İşte en sık kullanılan senaryolar:

    A. Dosya İndirme (-o ve -O)

    Bir çıktıyı terminale basmak yerine dosyaya kaydetmek için kullanılır

    -O (büyük O): Sunucudaki orijinal dosya adını kullanarak kaydeder.

    curl -O https://ornek.com/dosya.zip

    -o (küçük o): Dosya adını siz belirlersiniz.

    curl -o yeni_dosya.html https://ornek.com/sayfa

    B. Yönlendirmeleri Takip Etme (-L)

    Bir site sizi başka bir adrese yönlendiriyorsa (örneğin HTTP’den HTTPS’ye veya www eklemeye), cURL varsayılan olarak bunu takip etmez. -L (Location) parametresi yönlendirmeyi izler.

    curl -L http://google.com

    C. Sadece Başlıkları Görme (-I)

    Sayfanın içeriğini indirmeden, sunucunun yanıt başlıklarını (Response Headers) görmek için kullanılır. Sunucu türü, önbellek durumu veya çerezler hakkında bilgi verir.

    curl -I https://www.github.com

    D. API İstekleri (GET, POST, PUT, DELETE)

    Bir API ile çalışırken en çok kullanılan parametreler şunlardır:

    GET İsteği (Varsayılan):

    curl https://api.ornek.com/kullanicilar

    POST İsteği (-d): Veri göndermek için kullanılır.

    curl -X POST -d "isim=Ahmet&yas=30" https://api.ornek.com/kayit

    JSON Verisi Gönderme (-H ile Başlık Ekleme): Modern API’ler genellikle JSON formatı ister. Bunun için Content-Type başlığını belirtmelisiniz.

    curl -X POST https://api.ornek.com/kullanici \ -H "Content-Type: application/json" \ -d '{"isim": "Ahmet", "email": "ahmet@mail.com"}'

    E. Detaylı Loglama (-v)

    İsteğin gidişini, el sıkışmayı (handshake) ve sunucudan gelen ham yanıtı görmek için “verbose” modunu açar. Hata ayıklarken hayat kurtarır.

    curl -v https://www.ornek.com

    4. En Önemli Parametreler (Kısa Liste)

    Aşağıdaki tabloyu hızlı bir referans olarak kullanabilirsiniz:

    ParametreAçıklamaÖrnek
    -X [METOT]HTTP metodunu belirler (GET, POST, PUT, DELETE).-X POST
    -d [VERİ]POST isteği ile veri (body) gönderir.-d "id=123"
    -H [BAŞLIK]İsteğe özel bir Header (Başlık) ekler.-H "Authorization: Bearer token"
    -o [DOSYA]Çıktıyı belirtilen dosyaya yazar.-o sonuc.json
    -LSunucu yönlendirmelerini (Redirect 301/302) takip eder.-L
    -iÇıktıda hem HTTP başlıklarını hem de yanıtı gösterir.-i
    -uKullanıcı adı ve şifre ile yetkilendirme sağlar (Basic Auth).-u user:password
    -kSSL sertifika kontrolünü atlar (Güvenli değildir ama development ortamında işe yarar).-k
    -s“Silent” mod. İlerleme çubuğunu ve hataları gizler.-s

    5. İleri Seviye Bir Örnek: API’ye Token ile Bağlanma

    Diyelim ki bir REST API’ye bağlanıp, güvenli bir “Bearer Token” kullanarak veri çekeceksiniz ve sonucu data.json dosyasına yazdıracaksınız. Komut şöyle olacaktır:

    curl -X GET https://api.servis.com/v1/siparisler \
         -H "Authorization: Bearer BURAYA_UZUN_TOKEN_GELECEK" \
         -H "Accept: application/json" \
         -o data.json
    
    
  • Systemd Unit Files

    Systemd Unit Files

    Systemd Unit File (Birim Dosyası), Linux sisteminin yapı taşlarını tanımlayan, .ini formatına benzeyen metin tabanlı konfigürasyon dosyalarıdır. Systemd’ye “neyi”, “nasıl”, “ne zaman” ve “hangi koşullarda” çalıştıracağını bu dosyalarla anlatırız.

    bu dosyaları sadece “yazılımı çalıştıran komut dosyası” olarak değil, Systemd Dependency Graph (Bağımlılık Grafiği) üzerindeki birer düğüm (node) olarak görmelisiniz.

    1. Dosya Konumları ve Hiyerarşi (Nerede Bulunurlar?)

    Systemd, unit dosyalarını belirli bir öncelik sırasına göre arar. Aynı isimde iki dosya varsa, önceliği yüksek olan klasördeki kazanır. Bu yapı, sistem güncellemelerinin sizin özel ayarlarınızı ezmesini engeller.

    Öncelik sırasına göre (En yüksekten en düşüğe):

    ÖncelikDizin YoluAçıklama
    1. Yönetici (Admin)/etc/systemd/system/Sizin çalışma alanınız. Buraya yazdığınız dosyalar her şeyi ezer. Sistem genelinde (tüm kullanıcılar için) bir servis yazıyorsanız burayı kullanırsınız.
    2. Çalışma Zamanı/run/systemd/system/Geçici dosyalar içindir. Reboot atınca silinir. Genelde programlar tarafından dinamik oluşturulur.
    3. Dağıtım (Vendor)/usr/lib/systemd/system/Dokunmayın. Paket yöneticisiyle (dnf/apt) gelen varsayılan dosyalar buradadır. Güncelleme gelirse buradaki dosya değişir.
    4. Kullanıcı~/.config/systemd/user/Kişisel alanınız. Root yetkisi gerektirmeyen, sadece o kullanıcı oturum açtığında çalışan servisler içindir.

    Mühendislik İpucu: Asla /usr/lib/ altındaki bir dosyayı değiştirmeyin. Eğer varsayılan bir servisin davranışını değiştirmek istiyorsanız, o dosyayı /etc/systemd/system/ altına kopyalayın ve orada düzenleyin. Systemd otomatik olarak /etc altındakini kullanacaktır.

    2. Unit Dosyası Nasıl Yazılır? (Anatomi)

    Bir unit dosyası genellikle 3 ana bölümden oluşur. Köşeli parantezler [] ile bölümler ayrılır.

    A. [Unit] Bölümü (Kimlik ve Bağımlılıklar)

    Dosyanın ne olduğunu ve diğer servislerle ilişkisini tanımlar.

    • Description=: İnsanların okuması için kısa açıklama. (systemctl status çıktısında görünür).
    • After=: Sıralama belirler. After=network.target derseniz, ağ servisi ayağa kalktıktan sonra bu servisi başlatmaya çalışır. (Dikkat: Bu sıkı bir bağımlılık değildir, sadece sıralamadır).
    • Requires=: Sıkı bağımlılık. “Eğer X servisi çalışmıyorsa ben de çalışmam” demektir. X servisi çökerse bu servis de durdurulur.
    • Wants=: Gevşek bağımlılık. “X servisini de başlatmayı dene ama o hata verirse beni etkileme” demektir. En çok kullanılan budur.

    B. [Service] Bölümü (Çalıştırma Mantığı)

    Sadece .service uzantılı dosyalarda bulunur. Yazılımın nasıl çalışacağını anlatır.

    • Type=: Servisin türünü belirler.
      • simple: (Varsayılan) Komut çalıştırılır çalıştırılmaz servis “hazır” kabul edilir. (Python scriptleri için ideal).
      • forking: Eğer programınız kendini arka plana atıyorsa (daemonize oluyorsa) kullanılır (Örn: Nginx).
      • oneshot: Script çalışır, işini yapar ve kapanır. Servis “çalışıyor” durumda kalmaz. (Örn: Yedekleme scriptleri, güncelleme kontrolü).
    • ExecStart=: Çalıştırılacak ana komut. Tam yol (absolute path) kullanılmalıdır (python yerine /usr/bin/python3).
    • ExecStop=: Servis durdurulurken çalışacak komut.
    • Restart=: Hangi durumda yeniden başlasın? (no, on-failure, always).
    • User= / Group=: Servis hangi kullanıcı haklarıyla çalışsın? (System servisleri için önemlidir, User servislerinde zaten sizsinizdir).
    • Environment=: Ortam değişkeni tanımlamak için kullanılır.

    C. [Install] Bölümü (Kurulum ve Tetikleme)

    systemctl enable komutunu çalıştırdığınızda ne olacağını belirler.

    • WantedBy=: Bu servis hangi “hedef” (target) tetiklendiğinde ayağa kalksın?
      • multi-user.target: Grafik arayüzsüz sunucu modu (Genel standart).
      • graphical.target: Grafik arayüzlü masaüstü modu.
      • default.target: Sistemin varsayılan açılış modu.

    3. Örnek Senaryo: Basit Bir Web Server Servisi

    Diyelim ki /opt/myserver/app.py adresinde bir Flask uygulamanız var ve bunu sistem servisi yapmak istiyorsunuz.

    Dosya: /etc/systemd/system/myapp.service

    [Unit]
    Description=Benim Ozel Web Sunucum
    After=network.target
    # Ağ bağlantısı olmadan çalışmasının bir anlamı yok
    
    [Service]
    Type=simple
    User=anil
    WorkingDirectory=/opt/myserver
    ExecStart=/usr/bin/python3 app.py
    Restart=always
    RestartSec=10
    # Çökerse 10 saniye bekle ve tekrar dene
    
    [Install]
    WantedBy=multi-user.target

    4. Sadece .service mi var? (Unit Türleri)

    Hayır, Systemd modülerdir. Uzantısına göre farklı işler yapan unit dosyaları vardır:

    1. .service: Uygulamaları ve süreçleri yönetir (En yaygın).
    2. .timer: Zamanlanmış görevler (Cron yerine geçer). Bir .service dosyasını tetikler.
    3. .socket: Bir portu veya soketi dinler. Veri geldiği anda ilgili .service‘i uyandırır. (Socket Activation). Kaynak tasarrufu için muazzamdır.
    4. .target: Diğer unitleri gruplamak için kullanılır (Örn: graphical.target aslında ekran kartı, GNOME, ses servisi vb. servislerin bir grubudur).
    5. .mount: Disk bağlama işlemlerini yönetir (/etc/fstab girdileri systemd tarafından otomatik olarak bu dosyalara dönüştürülür).

    5. Mühendisler İçin İpuçları

    • Değişikliği Bildirmek: Bir unit dosyasını oluşturduktan veya değiştirdikten sonra systemd’ye “dosyaları tekrar oku” demeniz şarttır:Bashsudo systemctl daemon-reload
    • Doğrulama (Verify): Dosyanızda sözdizimi hatası olup olmadığını servisi çalıştırmadan test edebilirsiniz:Bashsystemd-analyze verify /etc/systemd/system/myapp.service
    • Override (Ezme): Mevcut bir servisin (örneğin docker.service) ayarlarını değiştirmek istiyorsunuz ama tüm dosyayı kopyalamak istemiyorsunuz. Şu komutla sadece farkları içeren bir “drop-in” dosyası oluşturabilirsiniz:Bashsudo systemctl edit docker.service Bu komut otomatik olarak /etc/systemd/system/docker.service.d/override.conf oluşturur ve içine yazdıklarınız ana ayarları ezer.

    alma centos firewall firewall-cmd firewalld redhat rocky sistem yönetimi

  • F5’e Basmaktan Ciğerim Soldu: Fedora’da “İlk İstekte Hata” Sorununu Nasıl Debug Ettim?

    Linux kullanmanın en keyifli yanı, sistemin kaputunun altında her şeyin şeffaf olmasıdır. Ancak Fedora’nın kararlı bir sürümünü kullanıyor olsanız bile, bazen ağ yığınının (networking stack) derinliklerinde, standart kullanıcıların asla fark etmeyeceği ama teknik detaya hakim olanları çileden çıkaran “edge case” durumlarla karşılaşabiliyorsunuz. Geçtiğimiz günlerde tam da böyle bir sorunla, bir “ilk bağlantı zaman aşımı” problemiyle boğuştum. Hangi siteye gitsem tarayıcım ilk GET isteğinde ERR_ADDRESS_UNREACHABLE hatası fırlatıyor, sayfayı yenilediğimde ise sorunsuz şekilde çalışıyordu.

    İşte bu “bir kere hata, sonra devam” döngüsünü nasıl analiz ettiğim ve (biraz kaba kuvvetle de olsa) nasıl çözdüğümün hikayesi.

    Şüpheliler ve İlk Müdahaleler

    İlk bakışta sorun klasik bir DNS timeout gibi duruyordu. Hemen ilk aklıma gelen çözümleri denemeye koyuldum. İlk olarak DNS Değişikliği yapmayı denedim. Hemen systemd-resolved servisini aradan çıkarıp NetworkManager üzerinden statik DNS (1.1.1.1 Cloudflare Çiçeğim 🙂 ) verdim fakat uzun bir süre bütün DNS sistemini bızıklasam da sonuç değişmedi. Sonrasında Tarayıcı Ayarları ile oynamaya başladım Chrome ve Firefox’un Secure DNS özelliklerini kapattım ama sinir bozucu hata devam ediyordu. Paylaşımlı bir ağdayım diye MAC adresi sabitleme (Sabit MAC adresini kullanacak değiliz değil mi?), MTU ayarları, Wi-Fi güç tasarrufu kapatma… Hepsini denedim. Sistem inatla ilk seferde “Ağa ulaşamıyorum” diyor, ikinci seferde yolu buluyordu. Bu bir “bağlantı” sorunu değil, bir “karar verme” sorunuydu.

    Dedektiflik Zamanı: strace ile Suçüstü

    Tahmin yürütmek mühendisliğe yakışmaz diyerek terminali açtım ve sorunu daha derinden incelemeye karar verdim. Tarayıcının hata verdiği o milisaniyede arka planda ne dönüyordu?

    Chrome’u strace ile başlatıp sadece bağlantı (connect) çağrılarını izledim:

    strace -e trace=connect -f google-chrome 2>&1 | grep "ENETUNREACH"

    Ve işte suçlu karşımdaydı

    connect(18, {sa_family=AF_INET6, ...}) = -1 ENETUNREACH

    Çıktı çok netti

    Sistemim inatla IPv6 (AF_INET6) üzerinden bağlantı kurmaya çalışıyordu. Ancak ağımda geçerli bir IPv6 çıkışı olmadığı için Kernel Ağ erişilebilir değil” (ENETUNREACH) hatası dönüyordu. İşin garibi ben IPv6yı Kapatmıştım?! NetworkManager ayarlarından IPv6’yı “Disabled” yapmıştım. ip addr komutunu çalıştırdığımda ise acı gerçeği gördüm:

    inet6 fe80::bc24:661f... scope link

    Ben ne kadar kapatsam da, NetworkManager veya Kernel, arayüze bir Link-Local (fe80::) adresi atıyordu. Sistem bu adresi görünce “Hey, benim IPv6’m var, hadi Google’a IPv6 ile gidelim!” sanrısına kapılıyor, ama o adresten dışarı çıkamayıp duvara tosluyordu. gai.conf ile IPv4’ü önceliklendirmek bile bu inatçı davranışı çözmedi.

    Nükleer Çözüm: Kernel Parametresi

    Yazılımsal ricalar (sysctl, nmcli) işe yaramayınca, sorunu en tepeden kernel seviyesinden çözmeye karar verdim. İşletim sistemine “Sen IPv6 diye bir protokolü hiç öğrenmedin, bilmiyorsun” diyecektim.

    GRUB ayar dosyasını (/etc/default/grub) açtım ve şu parametreyi ekledim:

    ipv6.disable=1

    Bu parametre, Linux çekirdeği yüklenirken IPv6 modülünü tamamen devre dışı bırakıyor.

    Tetiği çekip bilgisayarı yeniden başlattım. Bilgisayar açıldığında ip addr komutunda tek bir inet6 satırı bile yoktu. Tarayıcıyı açtım, bir siteye girdim ve… Anında açıldı. Çünkü Kernel artık IPv6 çağrısına “Ulaşılamıyor” (ENETUNREACH) hatası değil, “Böyle bir protokol yok” (EAFNOSUPPORT) hatası dönüyordu. Tarayıcı bu cevabı aldığı nanosaniye içinde vakit kaybetmeden IPv4’ü kullanıyordu.

    Linux kullanıyorsanız bazen arayüzdeki “Kapat” butonu gerçekten kapatmak anlamına gelmeyebiliyor. Ve bir sorunu çözemiyorsanız, loglara (strace, journalctl) bakmak, karanlıkta el yordamıyla yürümekten her zaman iyidir, doğru log okumak körü körüne çözüm aramaktan çok daha değerli.

  • VMware Workstation 17.6 Güncellemesi Sonrası Linux Sanal Makinelerde Klavye Gecikmesi ve Çözümü

    VMware Workstation 16’dan 17.6 ve 17.6.1 sürümüne geçtikten sonra, Windows 11 (23H2) üzerinde çalışan çeşitli Linux dağıtımlarıyla oluşturulmuş sanal makinelerde ciddi klavye gecikmeleri yaşamaya başladım. 

    Eğer benzer bir sorun yaıyorsanız, bu problemi çözmek için sanal makinenin yapılandırma dosyasına (.vmx uzantılı dosya) aşağıdaki satırı eklemek yeterli:

    keyboard.vusb.enable = "TRUE"

    Bu ayar, klavye girişini USB üzerinden yönlendirerek gecikme problemini ortadan kaldırıyor.