İçindekiler
- 1 VPS’te .env ve gizli anahtar yönetimi neden bu kadar kritik?
- 2 Hangi veriler gerçekten gizli? .env’de ne tutulur, ne tutulmaz?
- 3 .env yaklaşımı: Güçlü yanları ve riskleri
- 4 VPS üzerinde güvenli .env ve config dosyası yerleşimi
- 5 .env yerine/yanında ortam değişkenleri kullanmak
- 6 CI/CD ve deploy sürecinde gizli anahtar yönetimi
- 7 İleri seviye secrets yönetimi: Şifreleme, sops, age ve ötesi
- 8 Uygulama bazlı pratikler: Laravel, WordPress, Node.js ve diğerleri
- 9 Erişim kontrolü, audit ve anahtar rotasyonu
- 10 DCHost VPS üzerinde güvenli secrets mimarisini adım adım kurmak
VPS’te .env ve gizli anahtar yönetimi neden bu kadar kritik?
Bir VPS üzerinde çalışan her modern web uygulaması, yüzeyde basit görünen ama altyapının kalbinde duran onlarca gizli bilgiye dayanır: veritabanı şifreleri, API anahtarları, OAuth client secret’ları, JWT imzalama anahtarları, ödeme altyapısı token’ları, SMTP parolaları ve daha fazlası. Bunlar sızdığı anda yalnızca uygulamanız değil, müşterilerinizin verileri, itibarınız ve hatta şirketinizin hukuki durumu risk altına girer.
Uygulama kodu için Git, CI/CD, test ve code review süreçleri kurmak görece kolay. Asıl zor ve çoğu zaman ihmal edilen kısım; .env dosyaları, config dosyaları ve gizli anahtarların (secrets) VPS üzerinde nasıl saklanacağı, kim tarafından yönetileceği ve nasıl güncelleneceğidir. Birçok güvenlik denetiminde gördüğümüz temel problem, .env dosyalarının yanlış izinlerle herkese açık olması, Git deposuna yanlışlıkla commit edilmiş API key’ler veya yedeklerde şifrelenmeden duran kritik yapılandırmalar oluyor.
Bu yazıda DCHost ekibi olarak, VPS üzerinde .env ve gizli anahtar yönetimini uçtan uca ele alacağız. Hangi verilerin secret sayılması gerektiğinden, Linux dosya izinleri ve dizin yapısına; systemd ve ortam değişkenlerinden CI/CD boru hattında secrets kullanımına, şifreli secrets yönetimine ve anahtar rotasyonuna kadar adım adım ilerleyeceğiz. Amacımız; pratik, uygulanabilir ve denetlenebilir bir model kurmanıza yardım etmek.
Hangi veriler gerçekten gizli? .env’de ne tutulur, ne tutulmaz?
Gizli sayılması gereken tipik bilgiler
Önce neyi koruduğumuzu netleştirmek gerekiyor. Aşağıdaki bilgiler kesinlikle gizli kabul edilmeli ve .env veya benzeri bir yapı üzerinden dikkatle yönetilmelidir:
- Veritabanı erişim bilgileri: DB kullanıcı adı, parola, bağlantı URL’leri, read/write replikalar için ayrı kullanıcılar
- API anahtarları ve token’lar: Ödeme sağlayıcıları, SMS sağlayıcıları, harita/konum servisleri, e-posta servisleri vb.
- OAuth2 client_id / client_secret ve redirect secret’ları: Google, sosyal ağlar veya kurumsal SSO entegrasyonları
- JWT imzalama anahtarları ve şifreleme anahtarları: access/refresh token’larını imzalamak veya şifrelemek için kullandığınız secret’lar
- Uygulama anahtarları: Laravel APP_KEY, WordPress auth/secure salts, framework’e özgü gizli anahtarlar
- SMTP ve IMAP parolaları: Transactional e-posta gönderimi veya gelen kutusu senkronizasyonu için kullanılan bilgiler
- 3. parti sistem erişim bilgileri: CRM, ERP, muhasebe, kargo entegrasyonu gibi dış sistem kullanıcı/parolaları
Bu başlıkların ortak noktası, ele geçirildiğinde sistem dışında bir kapı açmalarıdır. Yani sadece uygulamanızı değil, bağlı olduğunuz başka servisleri de tehlikeye atabilirler.
.env dosyasına yazmamanız gerekenler
.env dosyası her tür veriyi atabileceğiniz bir çöp kutusu değildir. Aşağıdakileri .env’e koymaktan kaçının:
- Büyük konfigürasyon blokları: JSON, XML, YAML gibi uzun metinler; yönetimi zorlaştırır, hata riskini artırır
- Kullanıcı verileri: İsim, e-posta, telefon gibi dinamik ve veri tabanında tutulması gereken bilgiler
- Log veya debug çıktıları: Hata ayıklarken geçici olarak eklenen ve sonra unutulan debug string’leri
- Fazla değişen iş kuralları: Fiyat listeleri, kampanya oranları gibi sık sık güncellenen iş verileri
.env; ortam bazlı yapılandırma ve gizli anahtarlar için kullanılmalıdır, iş verisi veya geçici debug verisi için değil.
.env yaklaşımı: Güçlü yanları ve riskleri
.env nedir, nasıl çalışır?
.env, projeye özel ortam değişkenlerini düz metin dosyasında tutma yaklaşımıdır. Çoğu dil ve framework’te bir dotenv kütüphanesi, uygulama başlarken bu dosyayı okuyup içindeki değerleri ENV/process.env gibi yapıların içine yükler. Böylece:
- Production, staging, test gibi ortamlar için farklı .env dosyaları kullanabilirsiniz
- Aynı kod tabanını farklı müşterilere/markalara göre konfigüre edebilirsiniz
- Gizli anahtarlarınızı koddan ayırıp konfigürasyon katmanına taşırsınız
Doğru kullanıldığında bu yaklaşım, hem geliştirme sürecini temizler hem de güvenlik açısından kod–secret ayrımını netleştirir.
Yerel geliştirme vs VPS üretim ortamı
Geliştiriciler çoğu zaman kendi bilgisayarlarında .env dosyasını ev dizininde veya proje kökünde saklar, bu da çoğu senaryoda kabul edilebilir. Ancak VPS üzerinde durum farklıdır:
- Sunucuyu birden fazla kişi ve servis kullanıyor olabilir
- Yanlış dosya izinleri, diğer sistem kullanıcılarının secrets’ları okumasına yol açabilir
- Yanlış Nginx/Apache yapılandırması .env dosyasını doğrudan HTTP üzerinden erişilebilir hale getirebilir
- Yedekler, snapshot’lar ve loglar da gizli bilgileri içinde taşıyabilir
Bu nedenle VPS üzerinde .env yönetimi, yalnızca “dosyayı oluşturup doldurma” değil; dosya konumu, izinler, sahiplik, backup ve erişim denetimi ile birlikte ele alınmalıdır.
.env dosyasını asla Git deposuna koymamak
Güvenlik denetimlerinde en çok karşılaştığımız hatalardan biri, .env dosyasının yanlışlıkla Git deposuna commit edilmesidir. Bunu önlemek için:
- Proje kökünüzde mutlaka bir
.gitignoredosyası bulundurun .gitignoreiçine.env,.env.*gibi desenleri ekleyin- Takım için sadece .env.example dosyası oluşturun; içini sahte/placeholder değerlerle doldurun
- Gerçek prod değerleri sadece sunucuda veya güvenli bir secrets yönetim sistemi içinde tutun
Eğer bir gün yanlışlıkla .env’i commit ettiyseniz, ilgili API key ve parolaları hemen iptal edip yenisini oluşturmanız gerekir; yalnızca repository’den dosyayı silmek yetmez.
VPS üzerinde güvenli .env ve config dosyası yerleşimi
Doğru dizin yapısı ve izolasyon
Güvenli bir yapı için önce dizin hiyerarşisini temizlemek gerekir. Önerdiğimiz yaklaşım:
- Her proje için ayrı bir Linux kullanıcısı oluşturun (örneğin
projex) - Uygulama dosyalarını
/var/www/projexveya benzeri bir klasörde tutun - Public web kökünü (örneğin Laravel için
public, WordPress içinpublic_html) bu klasörün altına alın - .env ve diğer gizli config dosyalarını public web kökünün DIŞINDA bir yerde saklayın
Böylece yanlış bir sunucu yapılandırmasında bile .env dosyasının doğrudan HTTP üzerinden servis edilme riskini azaltmış olursunuz.
Dizin ve izin konusunu daha derinlemesine ele almak isterseniz, Linux dosya izinleri 644, 755, 777 için güvenli ayarları detaylı anlattığımız rehbere mutlaka göz atın.
Dosya sahipliği ve izinler: chown, chmod ve pratik değerler
.env ve config dosyaları için tipik bir pratik:
- Sahip: Uygulamanın çalıştığı kullanıcı (örneğin
projex) - Grup: Web sunucusu kullanıcısı veya proje grubu (örneğin
www-dataveyaprojex) - İzinler:
640veya daha sıkı ise600
Örnek komutlar:
chown projex:projex /var/www/projex/.envchmod 600 /var/www/projex/.env
Böylece dosyayı sadece ilgili kullanıcı (ve gerekirse grup) okuyabilir, sistemdeki diğer kullanıcılar ise içeriği göremez. Aynı prensipleri wp-config.php, config.php, local.php gibi diğer yapılandırma dosyalarına da uygulayın.
.env dosyasının web üzerinden indirilmesini engellemek
İkinci kritik nokta, .env dosyalarının yanlışlıkla public kökün içine taşınması veya Nginx/Apache yapılandırmasındaki bir hata sonucu erişilebilir hale gelmesidir. Alınabilecek önlemler:
- .env’i her zaman public web klasörünün dışında tutun
- Yine de risk almak istemiyorsanız, web sunucusuna
*.envuzantılı dosyaları asla servis etme kuralı ekleyin - Güvenlik taramalarıyla sitenizin kök dizininde yaygın dosya yollarını (/.env gibi) periyodik olarak kontrol edin
Genel VPS sertleştirme adımlarıyla birlikte düşünmek için, VPS sunucu güvenliği için hazırladığımız kapsamlı rehbere de mutlaka bakın.
Yedekleme ve snapshot’larda secrets
Gizli anahtarlar sadece canlı sunucuda değil, yedeklerde ve snapshot’larda da bulunur. Bu nedenle:
- Yedek lokasyonlarını sadece yetkili kullanıcı ve servislerle sınırlayın
- Mümkünse yedekleri şifreli (örneğin restic, borg gibi araçlarla) alın
- Yedekleme stratejinizde retention süresi ve erişim yetkilerini yazılı hale getirin
- Test geri yüklemelerinde test ortamına aktardığınız secrets’ların, production ile aynı yetkilere sahip olmadığından emin olun
Yedek ve saklama stratejisini daha sistematik ele almak isterseniz, RPO/RTO odaklı yedekleme stratejisi rehberimizi okuyabilirsiniz.
.env yerine/yanında ortam değişkenleri kullanmak
systemd servis dosyası ile environment yönetimi
Modern Linux VPS’lerde çoğu service systemd ile yönetiliyor. Uygulamanızı bir systemd servisi olarak çalıştırıyorsanız, secrets’ları dosya yerine doğrudan environment değişkeni olarak verebilirsiniz:
/etc/systemd/system/app.serviceiçindeEnvironment=DB_PASSWORD=...satırları kullanmak- Veya daha güvenlisi;
EnvironmentFile=/etc/app/app.envile sadece root’un okuyabildiği bir dosyadan environment yüklemek
Bu sayede uygulama dizinindeki dosyalar (örneğin deploy eden kullanıcılar) ile systemd’nin okuduğu secrets dosyaları arasında ek bir ayrım katmanı oluşturmuş olursunuz.
PHP-FPM, Node.js ve diğerleri için ortam değişkenleri
Benzer şekilde:
- PHP-FPM havuz dosyalarında (
www.confvb.)env[VAR_NAME]=valueşeklinde environment tanımlayabilirsiniz - Node.js için PM2, systemd veya benzeri process manager üzerinden environment set edebilirsiniz
- Python uygulamaları için gunicorn, uvicorn, systemd kombinasyonunda environment değişkenlerini servis dosyasına taşıyabilirsiniz
Avantajı, secrets’ların tek bir merkezi yapılandırma katmanında tutulmasıdır. Dezavantajı ise, bu dosyaların tipik olarak /etc altında bulunması ve yanlış düzenleme durumunda tüm servisin kalkamayabilmesidir; dikkatli değişiklik ve rollback planı şarttır.
CI/CD ve deploy sürecinde gizli anahtar yönetimi
.env.example, production .env ve takım içi pratikler
Takım çalışmasında önerdiğimiz model:
- Repository’de sadece .env.example dosyası bulunur; gerçek secrets içermez
- Geliştiriciler, kendi makinalarında .env.local veya .env.development gibi dosyalar oluşturur
- Production .env dosyası sadece VPS üzerinde bulunur; Git ile taşınmaz
- .env dosyası için değişiklikler, manuel değil; yetkili kişi tarafından yazılı bir prosedüre göre yapılır (örneğin change request ile)
Bu yaklaşım, hem yeni geliştiricilerin projeye hızlı adapte olmasını sağlar, hem de gerçek secrets’ın repository dışında kalmasını garanti eder.
GitHub Actions ve benzeri CI/CD sistemlerinde secrets kullanımı
Eğer kodunuzu GitHub Actions veya benzeri bir CI/CD sistemi üzerinden DCHost VPS’inize otomatik deploy ediyorsanız, secrets’ları CI tarafında değil, sunucu tarafında tutmanız çoğu durumda daha güvenlidir. Örneğin:
- CI pipeline yalnızca kodu build eder ve sunucuya rsync/ssh ile gönderir
- Sunucuda daha önce oluşturulmuş .env dosyası yerinde kalır, pipeline bu dosyayı asla dokunmaz
- Sadece gerçekten gerekli birkaç deploy parametresi (örneğin
DEPLOY_SSH_KEY) CI secrets olarak tutulur
CI tarafında secrets’ları nasıl güvenli yönetebileceğinizi ve sıfır kesintiyle deploy akışı kurabileceğinizi görmek için, GitHub Actions ile VPS’e otomatik deploy rehberimizi inceleyebilirsiniz.
İleri seviye secrets yönetimi: Şifreleme, sops, age ve ötesi
Neden düz metin .env her zaman yeterli değil?
Düz metin .env dosyaları, dosya sistemi doğru yapılandırılmışsa birçok senaryoda yeterli olabilir. Ancak regülasyon baskısının yüksek olduğu (KVKK, GDPR, finans, sağlık vb.) veya ekip ve altyapı karmaşıklaştıkça şu ihtiyaçlar ortaya çıkar:
- Secrets’ların Git repository’de şifreli tutulabilmesi
- Her değişikliğin kim tarafından, ne zaman yapıldığının izlenebilmesi
- Farklı ortamlar için (dev, test, prod) ayrı yetki ve anahtar setleri
- Otomatik rotasyon ve eski anahtarların güvenli şekilde devre dışı bırakılması
Bu noktada sops + age gibi araçlar, Vault benzeri merkezi secrets yönetim sistemleri veya KMS entegrasyonları devreye girer.
sops + age ile şifreli .env dosyaları
sops (Secrets OPerationS), yapılandırma dosyalarınızın içindeki gizli alanları şifreleyip Git içinde güvenle saklamanızı sağlayan bir araçtır. age ise modern, kullanımı görece basit bir dosya şifreleme formatıdır. Bu ikilinin tipik kullanım şekli:
.envyerine.env.encgibi şifreli dosyalar Git’te tutulur- Deploy sırasında, yalnızca yetkili kullanıcı veya CI job’ı bu dosyayı çözüp gerçek .env dosyasını üretir
- Şifreleme anahtarları FIDO2 donanım anahtarlarına veya ayrı KMS sistemlerine bağlanabilir
Bu konuyu pratik örneklerle ve GitOps akışlarıyla daha derin ele aldığımız VPS’te secrets yönetimi, sops + age ve rotasyon rehberimizi mutlaka okumanızı öneririz.
Uygulama bazlı pratikler: Laravel, WordPress, Node.js ve diğerleri
Laravel ve diğer modern PHP framework’leri
Laravel ve benzeri framework’ler .env kullanımını merkezine almıştır:
- APP_KEY: Uygulamanın kriptografik omurgasıdır, asla paylaşılmamalı ve tahmin edilebilir olmamalıdır
- Debug, cache, queue, mail, database gibi tüm kritik ayarlar .env üzerinden yönetilir
- Production ortamda
php artisan config:cacheile konfigürasyonlar önbelleğe alınır
Öneriler:
- APP_KEY’i hiçbir ortamda sabit, basit bir string yapmayın; Laravel’in ürettiği güçlü anahtarı kullanın
- Staging ve production ortamlarında farklı APP_KEY kullanın; veritabanı dump’larını staging’e taşıyorsanız bunu planlı yapın
- config cache aldıktan sonra .env değişikliklerinin etkili olması için yeniden deploy veya cache temizleme adımlarını akışınıza ekleyin
PHP tarafında hata logları ve konfigürasyonların doğru ayarlanması da secrets sızıntısını önlemek için önemlidir. Bunun için PHP hata kayıtlarını doğru yapılandırma rehberimize göz atabilirsiniz.
WordPress: wp-config.php ve salt anahtarları
WordPress dünyasında .env kullanımı son yıllarda yaygınlaşsa da, hâlâ en kritik dosya wp-config.php’dir. Bu dosyada:
- Veritabanı adı, kullanıcı adı ve parolası
- Tablo ön eki (
$table_prefix) - AUTH_KEY, SECURE_AUTH_KEY, LOGGED_IN_KEY, NONCE_KEY gibi salt anahtarları
bulunur. Bunların tamamı gizlidir.
Öneriler:
- wp-config.php dosyasını mümkünse bir üst dizine taşıyın; WordPress buna izin verir
- Dosya izinlerini
600veya640seviyesinde tutun - Salt anahtarlarını periyodik olarak yenileyin; kullanıcı cookie’lerini ve oturumlarını yönetirken bu değişimin etkisini planlayın
WordPress’i daha geniş bir güvenlik perspektifinden sertleştirmek için, WordPress güvenlik sertleştirme kontrol listemiz iyi bir tamamlayıcı olacaktır.
Node.js, Python ve mikroservis yapıları
Node.js ve Python tarafında yaygın yaklaşım, process.env üzerinden environment değişkenlerine erişmek veya bir dotenv kütüphanesiyle .env dosyasını okumaktır. Mikroservis ortamlarında tipik pratikler:
- Her servis için ayrı .env veya environment seti; servisler arasında secrets paylaşımı yapılmaması
- Ortak secrets (örneğin ortak bir Redis parolası) için merkezi bir secrets yönetim sistemi kullanmak
- Docker kullanılıyorsa, secrets’ları image içine gömmemek; runtime’da environment veya volume üzerinden vermek
Burada dikkat edilmesi gereken en önemli nokta, loglama ve debug çıktılarında secrets’ların asla açıkça yazılmamasıdır. Masking ve redaction mekanizmaları zorunlu olmalıdır.
Erişim kontrolü, audit ve anahtar rotasyonu
Kim hangi secret’a erişebilmeli?
Teknik önlemler kadar, erişim modeli de önemlidir. Basit bir kural seti:
- Geliştiriciler development ve gerekiyorsa staging secrets’larına erişebilir; production secrets erişimi sadece sınırlı sayıda kişide olmalıdır
- Ops/DevOps ekibi production secrets’lara erişir, ancak bu erişim kayıt altına alınır
- Her proje için ayrı Linux kullanıcıları ve grupları kullanılır; sudo yetkileri sadece gerçekten ihtiyaç duyanlarda olur
Bunu hayata geçirirken, Linux VPS’te kullanıcı, grup ve sudo mimarisi rehberimizde anlattığımız çoklu proje/ekip yetki tasarımı size güçlü bir çerçeve sunacaktır.
Anahtar rotasyonu: Ne sıklıkla, nasıl?
Secrets yönetiminin önemli ama sıkça atlanan kısmı, rotasyondur. Yani:
- API anahtarlarının, DB parolalarının, JWT secret’larının belirli aralıklarla yenilenmesi
- Eski anahtarların belirli bir geçiş süresi boyunca kısıtlı da olsa çalışabilir kalması (mümkünse)
- Rotasyon sürecinin dokümante edilmesi ve otomasyona bağlanması
Pratik bir yol:
- Önce yeni secret’ı üretin ve uygulamaya ekleyin (mümkünse hem eski hem yeni secret’ı destekleyecek şekilde)
- Deploy edip sistemin yeni secret’la sorunsuz çalıştığını doğrulayın
- Eski secret’ı ilgili sağlayıcı panelinden veya sistemden iptal edin
- Bu işlemin tarih ve sorumlusunu içeren kısa bir kayıt oluşturun
Bu süreci manuel değil, mümkün olduğunca script’ler ve runbook’lar ile standartlaştırmak uzun vadede büyük hata ve kesinti riskini azaltır.
Loglarda ve hata mesajlarında secrets sızıntısını önlemek
En iyi dosya izinlerini ayarlasak bile, uygulama loglarında secrets sızdırıyorsak aslında tüm emeğimiz boşa gider. Dikkat edilmesi gerekenler:
- Hata fırlatırken veya log yazarken request header’lar, Authorization header, cookie’ler, form alanları gibi kritik alanları maskeleyin
- Üretim ortamında asla tam stack trace’i son kullanıcıya göstermeyin; sadece genel bir hata mesajı verin
- Log yönetiminde, log dosyalarına kimlerin erişimi olduğunu ve ne kadar süreyle saklandığını tanımlayın
Merkezi loglama ve alarm sistemleri kurarken, log boyutu ve gizlilik dengesini de gözetmek gerekir; bunun için VPS log yönetimi rehberimizden yararlanabilirsiniz.
DCHost VPS üzerinde güvenli secrets mimarisini adım adım kurmak
Buraya kadar anlattıklarımızı, DCHost VPS üzerinde uygulanabilir bir kontrol listesine dönüştürelim:
- Her proje için ayrı Linux kullanıcıları ve grupları tanımlayın; paylaşılan user hesabı kullanmayın
- Uygulama dizinini public web kökü ve gizli config dosyaları (örn. .env, wp-config.php) olacak şekilde katmanlı tasarlayın
- .env ve config dosyalarına
600veya640izinleri verin, sahiplikleri doğru kullanıcı ve gruba ayarlayın - .env dosyalarını asla Git’e commit etmeyin; sadece .env.example dosyasını repository’de tutun
- Production secrets’ları sadece VPS üzerinde yönetin; CI/CD tarafını minimum secrets ile sade tutun
- Daha ileri ihtiyaçlar için sops + age gibi şifreli secrets yönetimi araçlarını devreye alın
- Anahtar rotasyonu, erişim yetkileri ve loglama politikalarını kısa ama net bir dokümana bağlayın
DCHost olarak amacımız sadece hızlı ve güçlü VPS altyapısı sunmak değil; üzerinde çalışan uygulamalarınızın güvenli, denetlenebilir ve sürdürülebilir bir yapıda kalmasını sağlamak. Mevcut DCHost VPS’inizde .env ve gizli anahtar yönetiminin ne durumda olduğunu birlikte gözden geçirmek veya yeni bir proje için en baştan doğru mimariyi kurmak isterseniz, ekibimizle iletişime geçebilir, ihtiyaçlarınıza özel bir yol haritası çıkarabiliriz.
Doğru secrets mimarisini bir kez kurduğunuzda, yeni projelerde tekrar tekrar kullanabileceğiniz sağlam bir temel elde etmiş olursunuz. Böylece hem güvenlik denetimlerinde hem de gerçek hayattaki saldırılarda, altyapınızın bu kritik katmanına güvenle bakabilirsiniz.
