Dosya Türlerini Anlama: Linux’ta file Komutu Kullanımı

Bir dosyaya bakıyorsun, uzantısı .dat, içinde ne olduğu belirsiz. Ya da birisi sana bir script göndermiş ama çalıştırmak için önce ne tür bir dosya olduğunu anlamak istiyorsun. İşte tam bu noktada file komutu devreye giriyor. Linux dünyasında belki de en hafife alınan ama en kullanışlı araçlardan biri olan file, dosyaların gerçek kimliğini ortaya çıkarıyor. Uzantıya değil, dosyanın içeriğine bakarak sana doğru bilgiyi veriyor.

file Komutu Nedir ve Nasıl Çalışır?

file komutu, bir dosyanın türünü tespit etmek için kullanılan bir Unix/Linux aracıdır. Peki bunu nasıl yapıyor? Windows dünyasında dosya türü genellikle uzantıyla belirlenir. .jpg ise resimdir, .exe ise çalıştırılabilirdir. Ama Linux’ta bu yaklaşım güvenilir değildir. Bir dosyanın uzantısı olmayabilir, yanlış uzantı taşıyabilir ya da kasıtlı olarak gizlenmiş olabilir.

file komutu üç farklı test mekanizması kullanır:

  • Filesystem testleri: Dosyanın bir dizin mi, sembolik link mi, boş dosya mı olduğuna bakar.
  • Magic number testleri: Dosyanın başındaki birkaç byte’ı okur. Bu “sihirli sayılar” her dosya formatında farklıdır ve /usr/share/misc/magic veya /etc/magic dosyasında tanımlıdır.
  • Metin testleri: Eğer dosya metin tabanlıysa, hangi programlama dili veya karakter seti olduğunu anlamaya çalışır.

Bu testler sırayla uygulanır ve ilk eşleşme sonucu döndürülür.

Temel Kullanım

En basit haliyle file komutunu tek bir dosyaya uygulamak yeterli:

file /etc/passwd

Çıktı şöyle olacaktır:

/etc/passwd: ASCII text

Birden fazla dosyaya aynı anda bakabilirsin:

file /bin/ls /etc/hostname /var/log/syslog
/bin/ls:          ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked...
/etc/hostname:    ASCII text
/var/log/syslog:  ASCII text

Ya da wildcard kullanarak bir dizindeki tüm dosyaları kontrol edebilirsin:

file /etc/*

Bu, /etc dizinindeki tüm dosya ve dizinlerin türünü listeler. Özellikle yeni bir sunucuya bağlandığında veya bilinmeyen bir ortamda çalışırken bu komut sana hızlı bir genel bakış sunar.

Önemli Parametreler

file komutunun en çok kullanılan parametreleri şunlardır:

  • -b: “Brief” modu, dosya adını çıktıya dahil etmez, sadece tür bilgisini gösterir
  • -i veya –mime-type: MIME type formatında çıktı verir (örneğin text/plain, image/jpeg)
  • -z: Sıkıştırılmış dosyaların içine bakarak gerçek içerik türünü tespit eder
  • -L: Sembolik linkleri takip eder, linkin kendisi yerine işaret ettiği dosyanın türünü gösterir
  • -s: Özel dosyalar ve blok aygıt dosyaları için de okuma yapar (root gerektirebilir)
  • -f: Dosya adlarını bir listeden okur, her satırda bir dosya adı olan bir dosyayı girdi olarak alır
  • -r: Sihirli dosya önbelleğini kullanmadan doğrudan okur
  • –extension: Dosya türüne uygun olası uzantıları listeler
  • -k: İlk eşleşmede durmaz, tüm eşleşmeleri gösterir
  • -e: Belirli bir test grubunu devre dışı bırakır (örneğin -e text metin testini atlar)

Pratik Senaryolar

Senaryo 1: Uzantısı Olmayan veya Yanlış Uzantılı Dosyalar

Bir müşteriden dosya aldın, adı sadece backup_data ve uzantısı yok. Ne yapacaksın?

file backup_data
backup_data: gzip compressed data, was "backup_data.tar", last modified: Mon Oct 14 09:23:11 2024, max compression, from Unix, original size modulo 2^32 1048576

Dosyanın aslında bir .tar.gz arşivi olduğunu anladın. Artık nasıl açacağını biliyorsun:

tar -xzf backup_data

Peki ya birisi sana .jpg uzantılı ama aslında başka bir şey olan bir dosya gönderirse?

file suspicious_image.jpg
suspicious_image.jpg: PHP script, ASCII text

Bu tür bir çıktı gördüğünde alarm zillerini çalması lazım. Birisi PHP scriptini .jpg olarak gizlemeye çalışmış. Bu tür durumlar güvenlik açıklarında sıkça karşılaşılan bir senaryo.

Senaryo 2: Çalıştırılabilir Dosya Analizi

Sistem üzerinde bilinmeyen bir binary bulduğunda:

file /usr/local/bin/unknown_tool
/usr/local/bin/unknown_tool: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=a1b2c3..., for GNU/Linux 3.2.0, not stripped

Bu çıktıdan çok şey öğrenebilirsin:

  • ELF 64-bit: Linux için derlenmiş 64 bit bir binary
  • statically linked: Tüm kütüphaneleri kendi içinde taşıyor, ldd ile bağımlılık göremezsin
  • not stripped: Debug sembolleri silinmemiş, strings veya objdump ile daha fazla bilgi çıkarılabilir

Aynı dizindeki tüm binaryleri incelemek istersen:

file /usr/local/bin/*

Senaryo 3: Log Dosyaları ve Encoding Sorunları

Bir uygulama log dosyası seni karşılıyor ama içeriği düzgün görüntülenemiyor:

file application.log
application.log: UTF-16 Unicode text, with CRLF line terminators

UTF-16 ile UTF-8 arasındaki fark ve Windows satır sonları (rn) sorunun kaynağı. Artık düzeltmek için ne yapman gerektiğini biliyorsun:

iconv -f UTF-16 -t UTF-8 application.log | sed 's/r//' > application_fixed.log

Senaryo 4: MIME Type ile Web Sunucu Konfigürasyonu

Web uygulamalarında dosya türünü doğrulamak için MIME type kullanmak daha güvenilirdir:

file -i uploaded_document
uploaded_document: application/pdf; charset=binary

Bir script yazarak upload edilen dosyaları kontrol edebilirsin:

#!/bin/bash
UPLOAD_DIR="/var/www/uploads"

for dosya in "$UPLOAD_DIR"/*; do
    MIME_TYPE=$(file -i "$dosya" | awk '{print $2}' | cut -d';' -f1)
    
    case $MIME_TYPE in
        image/jpeg|image/png|image/gif)
            echo "$dosya: Güvenli resim dosyası"
            ;;
        application/pdf)
            echo "$dosya: PDF dosyası"
            ;;
        text/x-php|application/x-php)
            echo "UYARI: $dosya PHP scripti olabilir! Kontrol et!"
            mv "$dosya" /tmp/quarantine/
            ;;
        *)
            echo "BILINMEYEN: $dosya - MIME: $MIME_TYPE"
            ;;
    esac
done

Senaryo 5: Sıkıştırılmış Dosyaların İçine Bakmak

-z parametresi ile sıkıştırılmış dosyaların gerçek içeriğini görebilirsin:

file -z archive.tar.gz
archive.tar.gz: POSIX tar archive (GNU) (gzip compressed data, last modified: Wed Oct 16 14:30:00 2024, max compression, from Unix)

Bu, sadece “gzip compressed data” demekten öte, içinde tar arşivi olduğunu da gösteriyor. Bir adım daha:

file -z suspicious_archive.gz
suspicious_archive.gz: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux) (gzip compressed data, max compression, from Unix)

Bir gzip içinde saklı executable! Bu mutlaka incelenmesi gereken bir durum.

Senaryo 6: Toplu Dosya Analizi ve Raporlama

Büyük bir dizinde farklı türde dosyaları gruplamak istiyorsun. -f parametresiyle dosya listesini girdi olarak verebilirsin:

find /home/kullanici/belgeler -type f > dosya_listesi.txt
file -f dosya_listesi.txt | sort > dosya_turleri_raporu.txt

Ya da doğrudan pipe kullanabilirsin:

find /opt/uygulama -type f | xargs file | grep -i "executable" | cut -d: -f1

Bu komut /opt/uygulama dizini altındaki tüm çalıştırılabilir dosyaları listeler.

Belirli bir türdeki dosyaları saymak için:

find /var/www -type f | xargs file | grep -c "PHP script"

Senaryo 7: Güvenlik Denetimi için Kullanım

Bir web sunucusunda potansiyel olarak tehlikeli dosyaları tespit etmek:

#!/bin/bash
WEB_ROOT="/var/www/html"
RAPOR="/tmp/guvenlik_raporu_$(date +%Y%m%d).txt"

echo "Web Root Güvenlik Taraması - $(date)" > $RAPOR
echo "================================" >> $RAPOR

find "$WEB_ROOT" -type f | while read dosya; do
    TUR=$(file -b "$dosya")
    
    if echo "$TUR" | grep -qiE "executable|script|ELF"; then
        echo "[UYARI] $dosya: $TUR" >> $RAPOR
    fi
    
    if echo "$TUR" | grep -qiE "PHP|perl|python|shell script"; then
        UZANTI="${dosya##*.}"
        if [[ "$UZANTI" =~ ^(jpg|png|gif|pdf|doc|txt)$ ]]; then
            echo "[KRITIK] Yanlis uzantili script: $dosya ($TUR)" >> $RAPOR
        fi
    fi
done

echo "Tarama tamamlandı. Rapor: $RAPOR"
cat $RAPOR

file Komutu ile Disk Bölümü ve Aygıt Analizi

file komutu sadece düzenli dosyalarla sınırlı değil. -s parametresiyle blok aygıtlara da bakabilirsin (root yetkisi gerekir):

sudo file -s /dev/sda
/dev/sda: DOS/MBR boot sector; partition 1 : ID=0xee, start-CHS (0x0,0,2), end-CHS (0x3ff,255,63), startsector 1, 2097151 sectors, extended partition table (last)

Disk üzerindeki bölümlere bakmak için:

sudo file -s /dev/sda1
/dev/sda1: Linux rev 1.0 ext4 filesystem data, UUID=a1b2c3d4-... (extents) (64bit) (large files) (huge files)

Bu, özellikle bir diski recovery modda incelediğinde veya tanımadığın bir aygıt bağladığında son derece faydalı.

Sembolik Linklerle Çalışmak

Varsayılan olarak file, sembolik linkleri takip etmez, linkin kendisi hakkında bilgi verir:

file /usr/bin/python
/usr/bin/python: symbolic link to python3

Linkin işaret ettiği gerçek dosyanın türünü görmek için -L kullanırsın:

file -L /usr/bin/python
/usr/bin/python: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked...

Brief Mod ve Script Entegrasyonu

Scriptlerde file komutunu kullanırken -b (brief) modu çok işe yarar çünkü sadece tür bilgisini döndürür, dosya adını tekrarlamaz:

TUR=$(file -b /path/to/dosya)
echo "Dosya türü: $TUR"

MIME type ile daha temiz bir çıktı için:

MIME=$(file -bi /path/to/dosya)
# Çıktı: text/plain; charset=utf-8

# Sadece MIME tipini almak için:
MIME_TIPI=$(file -bi /path/to/dosya | cut -d';' -f1)
# Çıktı: text/plain

Bu yaklaşım özellikle dosya yükleme işlemlerini doğrularken, backup scriptlerinde dosya türüne göre farklı işlem yaparken veya log analiz araçları geliştirirken sıkça kullanılır.

Magic Database Hakkında

file komutu bilgilerini /usr/share/misc/magic.mgc (derlenmiş) veya /usr/share/misc/magic dizininden alır. Bu veritabanı yüzlerce farklı dosya formatının sihirli sayılarını içerir.

Kendi özel formatın için magic tanımı ekleyebilirsin:

# Önce mevcut magic dosyalarına bak
file --version
# Hangi magic dosyasını kullandığını göster

# Özel magic dosyası oluştur
cat >> ~/.magic << 'EOF'
# Özel uygulama formatı
0       string  MYAPP   Kendi uygulama formatı v1
EOF

# Derle
file -C -m ~/.magic

Bu ileri düzey bir kullanım ama kendi uygulamanın binary formatını geliştiriyorsan veya kurum içi özel bir format kullanıyorsan işe yarayabilir.

Sık Karşılaşılan Durumlar ve Yorumları

Bazı çıktıları ilk gördüğünde ne anlama geldiğini anlamak zor olabilir:

  • data: file komutu formatı tanıyamadı, muhtemelen binary bir dosya
  • empty: Dosya tamamen boş (0 byte)
  • very short file (no magic): Dosya çok küçük, sihirli sayı tespiti yapılamadı
  • ASCII text, with CRLF line terminators: Windows formatında metin dosyası
  • ASCII text, with CR line terminators: Eski Mac formatında metin (Classic Mac OS)
  • UTF-8 Unicode text: Modern UTF-8 metin
  • ISO-8859 text: Batı Avrupa karakter setiyle metin

Encoding sorunlarıyla boğuşan birinin bu çıktıları anlıyor olması çok değerli. Özellikle Windows’tan gelen dosyaları Linux’ta işlerken CRLF sorunlarını file ile tespit etmek ve sed veya dos2unix ile çözmek standart bir iş akışı haline gelir.

file Komutunun Sınırlamaları

file komutu güçlü bir araç ama her şeyi çözmez. Bazı sınırlamaların farkında olmak lazım:

  • Bazı dosya formatları çok benzeri “magic bytes” kullandığından yanlış tespit yapılabilir
  • Şifrelenmiş dosyaları doğru tanımayabilir, genellikle “data” der
  • Çok yeni veya egzotik formatlar magic veritabanında olmayabilir
  • Kötü niyetle hazırlanmış dosyalar, başına sahte magic bytes eklenerek yanıltıcı çıktı üretebilir

Bu nedenle güvenlik açısından kritik kararlar için file komutunu tek başına kullanmak yeterli değil. hexdump, strings, binwalk gibi araçlarla desteklemek gerekir.

Sonuç

file komutu, her sysadmin’in araç kutusunda olması gereken, küçük ama çok değerli bir araç. Günlük işlerde bilinmeyen dosyaları tanımlamaktan güvenlik denetimlerine, encoding sorunlarından disk analizine kadar pek çok senaryoda kullanılıyor. En güçlü yanı, dosya uzantısına değil gerçek içeriğe bakması. Bu sayede hem hataları hem de kasıtlı gizleme girişimlerini ortaya çıkarabiliyor.

Scriptlerin içine entegre ettiğinde, özellikle dosya yükleme doğrulama veya toplu işlem senaryolarında, güçlü ve güvenilir bir katman eklemiş oluyorsun. -b, -i, -z ve -L parametrelerini doğru kombinasyonda kullanmayı öğrendiğinde, file komutu sana düşündüğünden çok daha fazlasını söylüyor.

Bir dahaki sefere bilinmeyen bir dosyayla karşılaştığında, ilk içgüdün cat veya less ile içine bakmak olmasın. Önce file ile ne olduğunu anla, sonra ona göre devam et.

Yorum yapın