Arşivleme İşlemlerinde Şifreleme Katmanı Ekleme: age ile Modern ve Güvenli Yedek Şifreleme
Yedek almak güzel bir alışkanlık. Yedekleri şifrelemek ise artık bir zorunluluk. Ama şu an kullandığınız yöntem nedir? GPG mi? OpenSSL ile bir şeyler mi döndürüyorsunuz? Eğer cevabınız “biraz karmaşık ama çalışıyor” ise, bu yazıyı okumaya değer. age aracını tanıtacağım; modern, sade ve gereksiz karmaşıklıktan arınmış bir şifreleme aracı. Üretimde birkaç müşteride kullandım, sonuçlardan memnunum.
age Nedir ve Neden Önemli?
age (Actually Good Encryption), Filippo Valsorda tarafından geliştirilen, GPG’nin getirdiği konfigürasyon kaosuna tepki olarak doğmuş bir araç. Tasarım felsefesi son derece net: tek bir iş yap, onu doğru yap, arayüzü sade tut.
GPG ile çalışan herkes şunu bilir: anahtar yönetimi bir kabus olabilir. Yanlış keyring, süresi dolmuş alt anahtar, --armor mı --output mu karışıklığı… age bunların hiçbirini yaşatmıyor. Kuruyorsunuz, çalıştırıyorsunuz, iş bitiyor.
Kriptografik tarafta ise X25519, ChaCha20-Poly1305 ve HMAC-SHA256 kullanıyor. Bunlar 2024 itibarıyla kabul görmüş modern primitifler. RSA 2048 veya eski AES-CBC modlarıyla boğuşmuyorsunuz.
Kurulum
Çoğu dağıtımda paket depolarında mevcut:
# Ubuntu/Debian
sudo apt install age
# RHEL/Rocky/AlmaLinux (EPEL gerekebilir)
sudo dnf install age
# Arch
sudo pacman -S age
# macOS (Homebrew)
brew install age
# Go ile kaynak kodu üzerinden
go install filippo.io/age/cmd/age@latest
go install filippo.io/age/cmd/age-keygen@latest
Versiyon kontrolü:
age --version
# age v1.1.1
Anahtar Üretimi
age iki temel şifreleme modunu destekliyor: parola tabanlı ve açık anahtar tabanlı. Otomasyon senaryoları için açık anahtar yöntemi çok daha uygun.
# Anahtar çifti oluşturma
age-keygen -o ~/.age/backup-key.txt
# Çıktı şuna benzer:
# Public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
# age secret key generated
# Dosya içeriğini görmek için
cat ~/.age/backup-key.txt
# # created: 2024-01-15T10:23:45+03:00
# # public key: age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
# AGE-SECRET-KEY-1QJFJDFL...
Özel anahtarı güvenli bir yere alın. Gerçek bir senaryoda bu anahtarı HashiCorp Vault’a veya bir parola yöneticisine koymanızı öneririm. ~/.age/ dizininin izinlerini de kontrol edin:
chmod 700 ~/.age
chmod 600 ~/.age/backup-key.txt
Temel Şifreleme ve Çözme
Önce en basit kullanıma bakalım. Bir dosyayı şifreleyelim:
# Açık anahtarla şifreleme
age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
-o backup.tar.gz.age
backup.tar.gz
# Çözme (özel anahtar gerekli)
age -d -i ~/.age/backup-key.txt
-o backup.tar.gz
backup.tar.gz.age
Parola tabanlı şifreleme için:
# Parola ile şifreleme (interaktif)
age -p -o secrets.tar.gz.age secrets.tar.gz
# Çözme
age -d -o secrets.tar.gz secrets.tar.gz.age
Parola tabanlı yöntemde age Argon2id kullanıyor, bu da kaba kuvvet saldırılarına karşı dirençli hale getiriyor. Ama otomasyon için tercih etmiyorum; parolanın bir yerde durması gerekiyor ve bu başka bir sorun açıyor.
tar ile Entegrasyon: Pipe Kullanımı
age‘in güzel özelliklerinden biri pipe ile mükemmel çalışması. Büyük dosyaları geçici bir ara dosyaya yazmadan doğrudan şifreleyebilirsiniz:
# tar + age pipe ile (disk alanı tasarrufu)
tar czf - /var/www/html |
age -r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
-o /mnt/backup/webroot-$(date +%Y%m%d).tar.gz.age
# Geri çözme ve açma
age -d -i ~/.age/backup-key.txt /mnt/backup/webroot-20240115.tar.gz.age |
tar xzf - -C /tmp/restore/
Bu yaklaşım özellikle disk alanının kısıtlı olduğu durumlarda fark yaratıyor. /var/www 50GB ise önce 50GB arşiv oluşturup sonra şifrelemek yerine, doğrudan pipe üzerinden işliyorsunuz.
Veritabanı Yedeklerinde Kullanım
MySQL/MariaDB ve PostgreSQL yedeklerinde sıklıkla kullandığım bir pattern:
#!/bin/bash
# /usr/local/bin/db-backup-encrypted.sh
set -euo pipefail
BACKUP_DIR="/mnt/nas/db-backups"
AGE_PUBKEY="age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="production_db"
RETENTION_DAYS=30
# PostgreSQL yedek + sıkıştırma + şifreleme (tek geçişte)
pg_dump -Fc "${DB_NAME}" |
gzip |
age -r "${AGE_PUBKEY}"
-o "${BACKUP_DIR}/${DB_NAME}_${DATE}.dump.gz.age"
echo "[$(date)] Yedek tamamlandı: ${DB_NAME}_${DATE}.dump.gz.age"
# Eski yedekleri temizle
find "${BACKUP_DIR}" -name "*.age" -mtime "+${RETENTION_DAYS}" -delete
echo "[$(date)] ${RETENTION_DAYS} günden eski yedekler temizlendi."
Bu script’i crontab’a eklemek için:
crontab -e
# Her gün gece 02:00'de çalıştır
0 2 * * * /usr/local/bin/db-backup-encrypted.sh >> /var/log/db-backup.log 2>&1
Burada dikkat etmem gereken nokta: script’te özel anahtar yok, sadece açık anahtar var. Script ele geçirilse bile şifrelenmiş yedekler korunuyor. Çözme işlemi sadece özel anahtarın bulunduğu ortamda yapılabilir.
Çoklu Alıcı Desteği
age‘in az bilinen ama çok işe yarayan özelliklerinden biri: aynı dosyayı birden fazla alıcı için şifreleyebiliyorsunuz. Büyük ekiplerde bu kritik önem taşıyor.
# Üç farklı adminlerin açık anahtarlarıyla şifreleme
age
-r age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
-r age1lggyhqr5jz99s7jaylee5lm3tkalmrp6726p5vc7yt3mn3at5ltsrngvh3
-r age1y9rwve7jvynre64fqj3zhvkk50yr8djkf4x4u5z85stzk8znzmqsm7k42h
-o critical-backup.tar.gz.age
critical-backup.tar.gz
Bu dosyayı artık her üç admin de kendi özel anahtarıyla çözebilir. Birisi şirketten ayrılırsa, yeni bir şifreleme yapmak yeterli; mevcut yedeklerin içindeki veri erişilebilir kalmaya devam eder.
Anahtarları bir dosyada tutmak daha temiz:
# recipients.txt dosyası oluştur
cat > /etc/age/recipients.txt << 'EOF'
# Ali - DevOps Lead
age1ql3z7hjy54pw3hyww5ayyfg7zqgvc7w3j2elw8zmrj2kg5sfn9aqmcac8p
# Ayse - SysAdmin
age1lggyhqr5jz99s7jaylee5lm3tkalmrp6726p5vc7yt3mn3at5ltsrngvh3
# Backup Service Account
age1y9rwve7jvynre64fqj3zhvkk50yr8djkf4x4u5z85stzk8znzmqsm7k42h
EOF
# Dosyaları okuyarak şifreleme
age -R /etc/age/recipients.txt
-o backup.tar.gz.age
backup.tar.gz
SSH Anahtarlarıyla Kullanım
age Ed25519 ve RSA SSH anahtarlarını da destekliyor. Eğer zaten SSH altyapınız varsa, ayrı age anahtarı oluşturmadan mevcut SSH anahtarlarınızı kullanabilirsiniz:
# SSH açık anahtarıyla şifreleme
age -r "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..."
-o backup.tar.gz.age
backup.tar.gz
# GitHub'daki SSH anahtarları üzerinden de çalışır
age -r https://github.com/kullanici-adi.keys
-o backup.tar.gz.age
backup.tar.gz
# SSH özel anahtarıyla çözme
age -d -i ~/.ssh/id_ed25519
-o backup.tar.gz
backup.tar.gz.age
GitHub entegrasyonu özellikle ilginç: takım üyelerinin GitHub hesaplarına kayıtlı anahtarlarını kullanarak şifreleme yapabilirsiniz. Elbette bunu üretim ortamında yapmadan önce hesabın anahtarlarını doğrulamanız lazım.
Kapsamlı Yedek Script’i
Birden fazla dizini ve servisi kapsayan, gerçek dünya kullanımına yakın bir örnek:
#!/bin/bash
# /usr/local/bin/full-system-backup.sh
set -euo pipefail
# Konfigürasyon
BACKUP_BASE="/mnt/offsite-backup"
RECIPIENTS_FILE="/etc/age/recipients.txt"
DATE=$(date +%Y%m%d)
HOSTNAME=$(hostname -s)
LOG_FILE="/var/log/encrypted-backup.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "${LOG_FILE}"
}
encrypt_and_store() {
local name="$1"
local source="$2"
local dest="${BACKUP_BASE}/${HOSTNAME}/${DATE}/${name}_${DATE}.tar.gz.age"
mkdir -p "$(dirname "${dest}")"
log "Basliyor: ${name} -> ${dest}"
tar czf - "${source}" 2>/dev/null |
age -R "${RECIPIENTS_FILE}" -o "${dest}"
local size
size=$(du -sh "${dest}" | cut -f1)
log "Tamamlandi: ${name} (${size})"
}
# Web dosyaları
encrypt_and_store "webroot" "/var/www"
# Nginx konfigürasyonu
encrypt_and_store "nginx-conf" "/etc/nginx"
# SSL sertifikaları
encrypt_and_store "ssl-certs" "/etc/letsencrypt"
# Sistem konfigürasyonları
encrypt_and_store "etc-backup" "/etc"
# Veritabanı
log "MySQL dump basliyor..."
mysqldump --all-databases --single-transaction 2>/dev/null |
gzip |
age -R "${RECIPIENTS_FILE}"
-o "${BACKUP_BASE}/${HOSTNAME}/${DATE}/mysql-all_${DATE}.sql.gz.age"
log "MySQL dump tamamlandi."
# Retention: 60 gunluk yedekleri tut
find "${BACKUP_BASE}/${HOSTNAME}"
-maxdepth 1
-type d
-name "20*"
| sort
| head -n -60
| xargs -r rm -rf
log "Tum islemler tamamlandi."
Şifrelenmiş Yedeklerin Doğrulanması
Yedek aldım, şifreli dosya var, güzel. Ama içi dolu mu? Bozuk değil mi? Bunu doğrulamak için ayrı bir rutin işletiyorum:
#!/bin/bash
# Yedek dogrulama script'i
# Tam cozme yapmadan header kontrolu + kucuk ornekle test
BACKUP_FILE="$1"
PRIVATE_KEY="${HOME}/.age/backup-key.txt"
if [[ -z "${BACKUP_FILE}" ]]; then
echo "Kullanim: $0 <backup-dosyasi>"
exit 1
fi
echo "Kontrol ediliyor: ${BACKUP_FILE}"
echo "Boyut: $(du -sh "${BACKUP_FILE}" | cut -f1)"
# age ile cozup tar icerigini listele (dosyalari cikartma)
if age -d -i "${PRIVATE_KEY}" "${BACKUP_FILE}" | tar tzv 2>/dev/null | head -20; then
echo ""
echo "BASARILI: Sifreleme katmani ve arsiv icerigi dogrulandi."
else
echo "HATA: Yedek dosyasi bozuk veya yanlis anahtar!"
exit 1
fi
Bu script’i her hafta çalıştırıyorum ve çıktıyı bir monitoring sistemine gönderiyorum. Yedek almak kadar, alınan yedeğin çalıştığını bilmek de önemli.
age vs GPG: Pratik Karşılaştırma
GPG’yi tamamen bırakmıyorum. Dijital imza gereken durumlarda, e-posta şifrelemesinde GPG hala anlamlı. Ama yedek şifreleme için age açık ara daha uygun:
- Kurulum karmaşıklığı: GPG’de keyring yönetimi, trust level’ları, subkey’ler var.
age-keygenile bir komutta bitiriyor. - Script entegrasyonu: GPG’de
--batch,--yes,--passphrase-fdgibi bayraklar gerekiyor.agepipe ile doğal çalışıyor. - Anahtar formatı: GPG anahtarları farklı formatlarda ihraç edilebiliyor, karışıklık çıkabiliyor.
ageanahtarları tek bir satır, kopyalanabilir, açık formatlı. - Kriptografik güncellik: GPG eski algoritmaları da destekliyor ve yanlış konfigürasyonda zayıf algoritmalar seçilebiliyor.
agemodern bir algoritma seti kullanıyor ve seçenek sunmuyor. - Hata mesajları: GPG’nin hata mesajları bazen muğlak oluyor.
ageçok daha net mesajlar veriyor.
Dezavantaj olarak söyleyebileceklerim: imzalama desteği yok (ayrı bir araç gerekiyor), ekosistem GPG kadar geniş değil, kurumsal uyumluluk gerektiren bazı ortamlarda GPG zorunlu olabiliyor.
Sonuç
age benim için bir paradigma değişikliğiydi. Yıllarca GPG ile yazdığım script’lerdeki karmaşıklığın farkına tam olarak ancak age‘e geçince vardım. Tek bir komutla çalışan, pipe dostu, modern kriptografi kullanan bir araç arıyorsanız, denemek için bir neden daha beklemenize gerek yok.
Temel mesaj şu: şifreli yedek almak zor değil. Zor gibi görünüyorsa, doğru aracı kullanmıyorsunuzdur. age bu engeli kaldırıyor. Açık anahtarınızı bir kez oluşturun, script’lerinize ekleyin, özel anahtarı güvenli bir yerde saklayın. Bu kadar.
Üretim ortamında uygulamadan önce birkaç şeyi kesinlikle yapın: yedek doğrulama rutinini kurun, özel anahtarın birden fazla güvenli kopyasını alın (bir USB’de, bir parola yöneticisinde), ve “anahtar kaybolursa” senaryonuzu yazılı hale getirin. Şifreleme, özel anahtarınızla birlikte yönetilmezse mükemmel bir kilit ama anahtarsız bir kapı olur.
