00 dm-crypt / LUKS mimarisi
dm-crypt, Linux kernel'ın device mapper altyapısı üzerine kurulu saydam disk şifreleme katmanıdır. LUKS (Linux Unified Key Setup) ise dm-crypt için standart header ve anahtar yönetimi formatını tanımlar.
Katmanlı mimari
Uygulama / Dosya Sistemi (ext4, F2FS, Btrfs...)
↓ ↑
/dev/mapper/sifreliyol ← device mapper sanal blok
↓ ↑
dm-crypt kernel modülü ← AES-XTS şifreleme/çözme
↓ ↑
/dev/mmcblk0p3 ← fiziksel LUKS partition
┌─────────────────────────────────────────────┐
│ LUKS2 Header (4 MB) │
│ ├── PBKDF2 / Argon2id parametre alanı │
│ ├── Keyslot 0..31 (master key şifreli) │
│ └── JSON metadata alanı │
├─────────────────────────────────────────────┤
│ Şifreli veri alanı (sektör 0'dan itibaren) │
└─────────────────────────────────────────────┘
Temel kavramlar
LUKS1 vs LUKS2 karşılaştırması
| Özellik | LUKS1 | LUKS2 |
|---|---|---|
| Header boyutu | 1 MB | 4 MB (yedekli) |
| Keyslot sayısı | 8 | 32 |
| PBKDF | PBKDF2 | Argon2id (varsayılan) |
| Token desteği | Yok | Var (TPM2, clevis, fido2) |
| Integrity | Yok | dm-integrity entegrasyonu |
| Detached header | Yok | Var (harici header dosyası) |
dm-crypt yalnızca dinlenme halindeki veriyi (data at rest) korur. Çalışan sistem mount edilmiş disk üzerindeyken anahtar bellekte bulunur. Boot-time unlock için fiziksel güvenlik ve güvenli boot zinciri (Secure Boot + dm-verity) gereklidir.
Bu bölümde
- dm-crypt = kernel device mapper + AES-XTS katmanı
- LUKS header, master key'i keyslot'larda şifreli saklar
- LUKS2, Argon2id PBKDF ve TPM2 token desteğiyle öne çıkar
01 cryptsetup kurulum ve temel kullanım
cryptsetup, dm-crypt ve LUKS yönetiminin birincil kullanıcı alanı aracıdır. Debian/Ubuntu, Yocto ve Buildroot'ta kolayca kurulur.
Kurulum
# Debian/Ubuntu
apt-get install cryptsetup cryptsetup-initramfs
# Buildroot — menuconfig
# Target packages → Filesystem and flash utilities → cryptsetup
# Kernel — enable dm-crypt:
# Device Drivers → Multiple devices driver support → Device mapper support
# → Crypt target support
# Yocto — local.conf veya layer recipe'ye ekle
IMAGE_INSTALL:append = " cryptsetup"
KERNEL_FEATURES:append = " features/cryptsetup/cryptsetup.scc"
# Sürüm doğrula
cryptsetup --version
# cryptsetup 2.7.2
Temel komutlar
# Mevcut LUKS cihazları listele
cryptsetup luksDump /dev/mmcblk0p3
# Şifreli diski aç
cryptsetup open /dev/mmcblk0p3 veri_disk
# Artık /dev/mapper/veri_disk kullanılabilir
mount /dev/mapper/veri_disk /mnt/veri
# Kapat
umount /mnt/veri
cryptsetup close veri_disk
# Hızlı durum sorgulama
cryptsetup status veri_disk
Bu bölümde
- cryptsetup, Yocto/Buildroot/Debian üçünde de kolayca kurulur
- luksOpen → /dev/mapper/ sanal blok → mount zinciri standart akıştır
- luksDump ile header bilgisi, benchmark ile AES hızı ölçülür
02 LUKS container oluşturma
Yeni bir LUKS2 container oluşturmak için luksFormat kullanılır. Algoritma, anahtar boyutu ve PBKDF parametreleri bu adımda belirlenir.
luksFormat seçenekleri
# Minimum — varsayılan ayarlarla LUKS2 oluştur
cryptsetup luksFormat /dev/mmcblk0p3
# Üretim için önerilen: AES-256-XTS + Argon2id
cryptsetup luksFormat \
--type luks2 \
--cipher aes-xts-plain64 \
--key-size 512 \
--hash sha256 \
--pbkdf argon2id \
--pbkdf-memory 65536 \
--pbkdf-parallel 4 \
--pbkdf-force-iterations 4 \
--label "rootfs-enc" \
/dev/mmcblk0p3
# Parola yerine keyfile kullan (otomasyon için)
dd if=/dev/urandom bs=64 count=1 of=/tmp/luks.key
cryptsetup luksFormat \
--type luks2 \
--key-file /tmp/luks.key \
/dev/mmcblk0p3
# Formatlandıktan sonra aç ve dosya sistemi oluştur
cryptsetup open --key-file /tmp/luks.key /dev/mmcblk0p3 enc_root
mkfs.ext4 -L rootfs /dev/mapper/enc_root
cryptsetup close enc_root
Keyslot parametresi seçimi
| Parametre | Gömülü (düşük RAM) | Masaüstü / Sunucu | Açıklama |
|---|---|---|---|
| --pbkdf-memory | 16384 (16 MB) | 1048576 (1 GB) | Argon2id bellek tüketimi — brute force maliyetini artırır |
| --pbkdf-parallel | 1–2 | 4–8 | Paralel thread sayısı |
| --pbkdf-force-iterations | 4 | auto | Sabit iteration — boot hızı için kısıtlı kaynaklarda kullanılır |
| --key-size | 256 (AES-128-XTS) | 512 (AES-256-XTS) | XTS modunda key-size 2× etkili anahtar uzunluğudur |
Gömülü sistemlerde 256 MB RAM ile Argon2id 65536 KB bellek parametresi sistemi kitleyebilir. Boot sırasında anahtar türetimi için kullanılabilir RAM'i göz önünde bulundurun; gerekirse --pbkdf-memory 16384 kullanın.
LUKS header yedekleme
# Header'ı harici dosyaya yedekle — ZORUNLU!
cryptsetup luksHeaderBackup /dev/mmcblk0p3 \
--header-backup-file /secure/backup/mmcblk0p3_luks_header.bin
# Header geri yükle (acil durum)
cryptsetup luksHeaderRestore /dev/mmcblk0p3 \
--header-backup-file /secure/backup/mmcblk0p3_luks_header.bin
# Yedek header bilgisini doğrula
cryptsetup luksDump \
--header /secure/backup/mmcblk0p3_luks_header.bin \
/dev/mmcblk0p3
Bu bölümde
- luksFormat parametreleri kaynakla orantılı seçilmeli (RAM, CPU)
- AES-256-XTS için --key-size 512 gerekir (XTS çift anahtar kullanır)
- Header yedeği olmadan LUKS partition kurtarılamaz — her zaman yedekleyin
03 initramfs ile şifreli root unlock
Şifreli bir root partition, kernel başlamadan önce initramfs aşamasında açılmalıdır. cryptsetup-initramfs (Debian) veya Dracut/mkinitcpio ile bu otomasyon sağlanır.
Debian/Ubuntu — cryptsetup-initramfs
# /etc/crypttab — format: <name> <device> <keyfile> <options>
# Parola ile açmak için
enc_root UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 none luks,discard
# Keyfile ile açmak için (keyfile initramfs'e gömülür)
enc_root UUID=a1b2c3d4-e5f6-7890-abcd-ef1234567890 /etc/keys/luks.key luks,discard
# /etc/fstab — mapper cihazını root olarak mount et
/dev/mapper/enc_root / ext4 defaults,noatime 0 1
# initramfs'i güncelle
update-initramfs -u -k all
# GRUB kernel parametrelerine cryptdevice ekle
# /etc/default/grub
GRUB_CMDLINE_LINUX="cryptdevice=UUID=a1b2c3d4...:enc_root root=/dev/mapper/enc_root"
update-grub
Yocto — özel initramfs unlock scripti
#!/bin/sh
# /etc/initramfs-tools/scripts/local-top/unlock-luks
PREREQ="cryptroot"
prereqs() { echo "$PREREQ"; }
case $1 in prereqs) prereqs; exit 0;; esac
. /scripts/functions
DEVICE="/dev/mmcblk0p3"
MAPPER_NAME="enc_root"
KEY_DEVICE="/dev/mmcblk0p4" # ayrı key partition
KEY_FILE="/key.bin"
# Key partition'ı monte et
mkdir -p /mnt/keystore
mount -t vfat "$KEY_DEVICE" /mnt/keystore 2>/dev/null
if [ -f "/mnt/keystore${KEY_FILE}" ]; then
# Keyfile ile otomatik aç
cryptsetup open --key-file "/mnt/keystore${KEY_FILE}" \
"$DEVICE" "$MAPPER_NAME"
else
# Fallback: parola sor
cryptsetup open "$DEVICE" "$MAPPER_NAME"
fi
umount /mnt/keystore 2>/dev/null
U-Boot ile unlock parametresi
# U-Boot ortam değişkeni — kernel'a cryptdevice parametre ilet
setenv bootargs "console=ttyS0,115200 root=/dev/mapper/enc_root \
cryptdevice=/dev/mmcblk0p3:enc_root ro quiet"
# veya FIT imajı ile:
setenv bootargs "${bootargs} dm-mod.create=\
'enc_root,,0,rw, 0 $(blockdev --getsz /dev/mmcblk0p3) crypt aes-xts-plain64 \
:64:logon:cryptsetup:UUID 0 /dev/mmcblk0p3 0 1 allow_discards'"
initramfs kendisi şifrelenmemişse saldırgan initramfs'i değiştirip parola ele geçirebilir. Bunu engellemek için initramfs'i Secure Boot ile imzalamalı veya dm-verity ile koruma altına almalısınız.
Bu bölümde
- /etc/crypttab + update-initramfs ile Debian'da otomatik unlock kurulur
- Yocto'da özel init hook ile keyfile/parola akışı yazılır
- initramfs koruması için Secure Boot + dm-verity zorunludur
04 TPM2 ile key sealing
TPM2, sistemin güvenilir bir durumda olduğu doğrulandığında (PCR değerleri eşleştiğinde) anahtarı otomatik açabilen donanım güvenlik bileşenidir. systemd-cryptenroll ve clevis bu işlemi basitleştirir.
TPM2 PCR kavramı
systemd-cryptenroll ile TPM2 kayıt
# Gerekli paket
apt-get install systemd tpm2-tools
# Mevcut keyslotları görüntüle
systemd-cryptenroll /dev/mmcblk0p3
# TPM2 ile PCR 0+7 bind ederek kayıt
# Mevcut LUKS parolası ile kimlik doğrulama yapılır
systemd-cryptenroll \
--tpm2-device=auto \
--tpm2-pcrs=0+7 \
/dev/mmcblk0p3
# PCR 0+7+9 ile (initramfs da ölçüme katılır)
systemd-cryptenroll \
--tpm2-device=auto \
--tpm2-pcrs=0+7+9 \
--tpm2-with-pin=yes \
/dev/mmcblk0p3
# /etc/crypttab'ı TPM2 token kullanacak şekilde güncelle
enc_root UUID=... none luks,tpm2-device=auto,discard
# TPM2 enrollment'ı kaldır (belirli slot)
systemd-cryptenroll --wipe-slot=tpm2 /dev/mmcblk0p3
clevis ile Tang network unlock
# Tang sunucusu kur (anahtar sunucusu — ayrı cihazda)
apt-get install tang
systemctl enable --now tangd.socket
# Cihazda clevis kur
apt-get install clevis clevis-luks clevis-initramfs
# Tang sunucusuna bind et
clevis luks bind -d /dev/mmcblk0p3 tang \
'{"url":"http://192.168.1.10","thp":"ABC123..."}'
# TPM2 + Tang birlikte (shamir — her ikisi de gerekli)
clevis luks bind -d /dev/mmcblk0p3 sss \
'{"t":2,"pins":{"tpm2":{"pcr_ids":"0,7"},"tang":{"url":"http://192.168.1.10"}}}'
# initramfs güncelle
update-initramfs -u -k all
# Test: manuel clevis unlock
clevis luks unlock -d /dev/mmcblk0p3 -n enc_root
Bu bölümde
- TPM2 PCR binding, sistem durumu değişince otomatik kilitleme sağlar
- systemd-cryptenroll en basit TPM2 entegrasyonudur — systemd 248+
- clevis ile Tang network unlock veya Shamir kombinasyonu mümkündür
05 Key rotation ve slot yönetimi
Anahtar rotasyonu güvenlik politikasının kritik parçasıdır. LUKS'un çok keyslotlu yapısı, sıfır kesintili parola değişimine olanak tanır.
Keyslot yönetimi komutları
# Mevcut keyslot durumunu görüntüle
cryptsetup luksDump /dev/mmcblk0p3 | grep -E "Keyslot|State"
# Yeni parola ekle (slot 1'e) — önce mevcut parolayla doğrulama
cryptsetup luksAddKey \
--key-slot 1 \
/dev/mmcblk0p3
# Yeni keyfile ekle (slot 2)
cryptsetup luksAddKey \
--key-slot 2 \
--new-keyfile /etc/keys/new_luks.key \
/dev/mmcblk0p3
# Eski parolayı kaldır (slot 0)
cryptsetup luksKillSlot /dev/mmcblk0p3 0
# Acil durum: tüm keyslotları sil (veri erişilemez olur!)
cryptsetup erase /dev/mmcblk0p3
Sıfır kesintili key rotation prosedürü
1. Yeni anahtarı yeni bir slot'a ekle
cryptsetup luksAddKey --key-slot 1 /dev/mmcblk0p3
2. Yeni anahtarın çalıştığını doğrula
cryptsetup open --key-slot 1 --test-passphrase /dev/mmcblk0p3
3. initramfs / sistemleri yeni anahtarla güncelle
update-initramfs -u -k all
4. Yeniden başlat ve yeni anahtarla boot et
5. Eski slot'u sil
cryptsetup luksKillSlot /dev/mmcblk0p3 0
LUKS2 re-encrypt (master key değişimi)
# LUKS2 online re-encryption — disk mount'luyken bile çalışır
# Yeni cipher ve key-size ile master key yeniden oluşturulur
cryptsetup reencrypt \
--cipher aes-xts-plain64 \
--key-size 512 \
--pbkdf argon2id \
--resume-only \
/dev/mmcblk0p3
# İlerlemeyi takip et
cryptsetup reencrypt --resume-only --verbose /dev/mmcblk0p3
# Kesinti durumunda devam et
cryptsetup reencrypt --resume-only /dev/mmcblk0p3
Üretim cihazlarında her cihaz için benzersiz LUKS key kullanın. Master key'i cihaz UUID veya seri numarasından türetin ve merkezi bir anahtar kasasında (HashiCorp Vault, AWS KMS) saklayın. Aynı anahtarın tüm filolara yayılması, tek anahtar ifşasının tüm filoya zarar vermesi anlamına gelir.
Bu bölümde
- Yeni slot ekle → doğrula → eski sil zinciri kesintisiz rotasyonu sağlar
- LUKS2 online re-encryption, master key değişimini çalışırken yapar
- Her cihaza özgü anahtar politikası üretim güvenliğinin temelidir
06 dm-verity ile birlikte kullanım
dm-crypt şifreleme sağlarken dm-verity bütünlük sağlar. İkisi birlikte kullanıldığında hem dinlenme halindeki veri korunur hem de değiştirme saldırıları tespit edilir.
Katman mimarisi
Root Filesystem (read-only squashfs)
↓
dm-verity (bütünlük — hash tree doğrulama)
↓
dm-crypt (şifreleme — AES-XTS)
↓
Fiziksel depolama (eMMC partition)
dm-verity her zaman dm-crypt'in üstünde konumlanmalıdır. dm-crypt şifreli bloğu çözdükten sonra dm-verity hash'leri doğrular. Ters sıra hem güvenlik hem de performans açısından yanlıştır.
dm-verity + dm-crypt stack kurulumu
# 1. Root filesystem imajı oluştur (squashfs)
mksquashfs rootfs/ rootfs.squashfs -comp zstd
# 2. LUKS2 container oluştur (imaj boyutu + biraz fazla)
truncate -s 512M enc_rootfs.img
cryptsetup luksFormat --type luks2 enc_rootfs.img
# 3. LUKS aç ve squashfs'i içine yaz
cryptsetup open enc_rootfs.img enc_root
dd if=rootfs.squashfs of=/dev/mapper/enc_root bs=4M status=progress
cryptsetup close enc_root
# 4. Kapalıyken verity hash hesapla (şifreli bloğa karşı değil,
# açık veri üzerinde — dolayısıyla önce aç)
cryptsetup open enc_rootfs.img enc_root_tmp
veritysetup format /dev/mapper/enc_root_tmp verity_hash.bin \
| tee verity_params.txt
cryptsetup close enc_root_tmp
# 5. Boot zamanında stack:
# a. LUKS aç
cryptsetup open /dev/mmcblk0p3 enc_root
# b. dm-verity üstüne ekle
ROOT_HASH=$(grep "Root hash:" verity_params.txt | awk '{print $3}')
veritysetup open /dev/mapper/enc_root verity_root \
/dev/mapper/enc_root "$ROOT_HASH"
# c. Mount et (read-only!)
mount -o ro /dev/mapper/verity_root /
# Bütünlük ihlalinde verity EIO döndürür, sistem panik yapar
Kernel dm-crypt + dm-verity parametreleri
# Device mapper
CONFIG_BLK_DEV_DM=y
CONFIG_DM_CRYPT=y
CONFIG_DM_VERITY=y
CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y # root hash imza doğrulama
# AES donanım hızlandırma
CONFIG_CRYPTO_AES_ARM64_CE=y
CONFIG_CRYPTO_SHA256_ARM64=y
Bu bölümde
- dm-crypt (şifreleme) + dm-verity (bütünlük) birlikte tam at-rest koruma sağlar
- Sıra: fiziksel disk → dm-crypt → dm-verity → filesystem
- dm-verity ihlali EIO → kernel panic ile sistemi durdurur
07 Performans etkisi ve AES-NI
dm-crypt performans etkisi AES-NI donanım hızlandırması ile minimize edilebilir. Modern ARM SoC'ların büyük çoğunluğu AES-CE (Cryptography Extensions) içerir.
AES-NI desteğini kontrol et
# x86 — AES-NI
grep aes /proc/cpuinfo | head -1
# ARM64 — AES-CE (Cortex-A53/A72/A55...)
grep aes /proc/cpuinfo
# Features: fp asimd evtstrm aes pmull sha1 sha2 crc32 ...
# Kernel crypto listesi
cat /proc/crypto | grep -A4 "aes"
# Aktif şifreleme modülü
lsmod | grep aes
cryptsetup benchmark
# Tüm algoritmaları test et
cryptsetup benchmark
# Örnek çıktı (Cortex-A72 @ 1.8 GHz, AES-CE etkin):
# # Algorithm | Key | Encryption | Decryption
# aes-cbc 128b 943.2 MiB/s 3168.0 MiB/s
# aes-cbc 256b 720.7 MiB/s 2432.9 MiB/s
# aes-xts 256b 1024.3 MiB/s 1008.7 MiB/s
# aes-xts 512b 775.2 MiB/s 775.8 MiB/s
# Belirli algoritmayı test et
cryptsetup benchmark --cipher aes-xts --key-size 512
# fio ile gerçek disk I/O benchmark (LUKS açıkken)
fio --filename=/dev/mapper/enc_root \
--rw=randread \
--bs=4k \
--direct=1 \
--numjobs=4 \
--iodepth=32 \
--name=luks_randread \
--runtime=30 \
--output-format=json
Performans karşılaştırması
| Platform | AES-CE | Seq Write (ham) | LUKS AES-256-XTS | Ek yük |
|---|---|---|---|---|
| RPi 4 (A72) | Var | 230 MB/s | 215 MB/s | ~7% |
| RPi Zero (A6) | Yok (yazılımsal) | 22 MB/s | 8 MB/s | ~64% |
| i.MX8M (A53) | Var | 280 MB/s | 258 MB/s | ~8% |
| AM6254 (A53) | Var + TRNG | 200 MB/s | 188 MB/s | ~6% |
Bu bölümde
- AES-CE olan ARM64 SoC'larda dm-crypt ek yükü %6–8 düzeyindedir
- AES-CE olmayan eski ARM'larda yazılımsal AES %40–60 performans kaybı yaratır
- fio ile gerçek iş yükü benchmark her zaman sentetik testten üstündür
08 Pratik: RPi eMMC şifreleme + TPM2 unlock
Raspberry Pi CM4'ün eMMC'sini LUKS2 ile şifreleyin ve TPM2 (Infineon SLB9670 SPI modülü) ile otomatik unlock kurun.
Gereksinimler
Adım 1 — eMMC'yi imajla ve bölümle
# rpiboot ile eMMC'yi PC'ye bağla
rpiboot
# /dev/sdb olarak görünür
# GPT bölümleme
sgdisk --zap-all /dev/sdb
sgdisk --new=1:2048:526335 --typecode=1:0700 --change-name=1:"boot" /dev/sdb
sgdisk --new=2:526336:0 --typecode=2:8300 --change-name=2:"root-enc" /dev/sdb
# Boot partition (FAT32 — şifresiz)
mkfs.vfat -F32 -n BOOT /dev/sdb1
# LUKS2 root partition
cryptsetup luksFormat \
--type luks2 \
--cipher aes-xts-plain64 \
--key-size 512 \
--pbkdf argon2id \
--pbkdf-memory 32768 \
--label "rpi-root-enc" \
/dev/sdb2
# Geçici parolayla aç ve ext4 kur
cryptsetup open /dev/sdb2 rpi_root
mkfs.ext4 -L rootfs /dev/mapper/rpi_root
# Raspberry Pi OS rootfs'ini kopyala
mount /dev/mapper/rpi_root /mnt/rpi
# ... rsync veya tar ile kopyala ...
umount /mnt/rpi
cryptsetup close rpi_root
Adım 2 — TPM2 SPI modülü bağlantısı
# /boot/config.txt
dtoverlay=tpm-slb9670
# TPM2 cihazını doğrula
ls /dev/tpm0 /dev/tpmrm0
# tpm2-tools ile temel test
tpm2_getcap properties-fixed | grep -i vendor
tpm2_pcrread sha256:0,7
Adım 3 — systemd-cryptenroll ile TPM2 kayıt
# İlk boot'ta parolayla giriş yap
# Ardından TPM2'ye kaydet
systemd-cryptenroll \
--tpm2-device=/dev/tpmrm0 \
--tpm2-pcrs=0+7 \
/dev/mmcblk0p2
# /etc/crypttab güncelle
rpi_root UUID=$(blkid -s UUID -o value /dev/mmcblk0p2) \
none luks,tpm2-device=auto,discard
# initramfs güncelle
update-initramfs -u -k all
# Yeniden başlat — TPM2 ile otomatik unlock
reboot
# Header yedeği al
cryptsetup luksHeaderBackup /dev/mmcblk0p2 \
--header-backup-file /boot/luks_header_backup.bin
Adım 4 — Doğrulama ve izleme
# LUKS durumunu kontrol et
cryptsetup status rpi_root
cryptsetup luksDump /dev/mmcblk0p2 | grep -E "Keyslot|Token|State"
# TPM2 token listesi
systemd-cryptenroll /dev/mmcblk0p2
# TPM2 PCR değerlerini kaydet (baseline)
tpm2_pcrread sha256:0,1,7,9 > /secure/pcr_baseline.txt
# Kernel güncelleme sonrası TPM2 enrollment yenile
# (PCR9 değişecek)
systemd-cryptenroll --wipe-slot=tpm2 /dev/mmcblk0p2
systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=0+7 /dev/mmcblk0p2
Bu bölümde
- CM4 eMMC LUKS2 şifreleme + SPI TPM2 ile otomatik unlock kuruldu
- PCR 0+7 binding — firmware veya Secure Boot değişirse disk kilitlenir
- Kernel güncellemelerinde TPM2 enrollment yenilenmesi unutulmamalı