Bir web sunucusuna sertifika yüklemek ile o sunucuyu gerçekten güvenli hale getirmek birbirinden farklı iki iştir. Apache üzerinde SSL'i çalışır duruma getirmek çoğu zaman birkaç satırlık bir işlem gibi görünür; ama tarayıcının adres çubuğundaki kilit simgesi yeşil yandığında bile arka planda zayıf bir protokol, eski bir şifreleme algoritması veya yanlış yapılandırılmış bir yönlendirme kuralı sizi savunmasız bırakabilir. Bu rehberde amacımız yalnızca "https çalışsın" demek değil; modern tarayıcıların ve güvenlik tarama araçlarının onay verdiği, uzun ömürlü ve bakımı kolay bir Apache SSL kurgusu ortaya koymak.
Aşağıda mod_ssl modülünü etkinleştirmekten başlayıp 443 portu için VirtualHost bloğunu kurmaya, ardından protokol ve cipher seçimlerini güvenli değerlerle sabitlemeye, HSTS başlığını eklemeye ve nihayet HTTP trafiğini kalıcı olarak HTTPS'e yönlendirmeye kadar tüm zinciri adım adım işleyeceğiz. Örnekler Ubuntu/Debian ve CentOS/AlmaLinux ailesindeki farkları da gözetiyor; komutları doğrudan kendi sunucunuzda deneyebilir, kendi alan adınıza uyarlayabilirsiniz. Kıdemli bir sistem yöneticisinin omzunuzun üzerinden bakarak anlattığı bir kurulum gibi düşünün.
mod_ssl Modülünü Etkinleştirme#
SSL/TLS'i Apache üzerinde konuşabilmenin ön koşulu mod_ssl modülünün yüklü ve etkin olmasıdır. Bu modül, OpenSSL kütüphanesini kullanarak şifreli el sıkışmayı (handshake), sertifika sunumunu ve oturum yönetimini üstlenir. Dağıtıma göre etkinleştirme yöntemi değişir.
Debian/Ubuntu tarafında modül ayrı bir komutla açılır ve apache2 servisi yeniden başlatılır:
# Apache kurulu değilse
sudo apt update
sudo apt install apache2 -y
# mod_ssl'i etkinleştir
sudo a2enmod ssl
sudo a2enmod headers # HSTS başlığı için gerekli
sudo systemctl restart apache2
CentOS/AlmaLinux/Rocky ailesinde mod_ssl çoğunlukla ayrı bir paket olarak gelir ve kurulur kurulmaz yüklü sayılır:
sudo dnf install mod_ssl -y
sudo systemctl restart httpd
Modülün gerçekten yüklendiğini teyit etmek için aşağıdaki komutu çalıştırın. Çıktıda ssl_module satırını görmeniz gerekir:
# Debian/Ubuntu
apache2ctl -M | grep ssl
# CentOS/AlmaLinux
httpd -M | grep ssl
Bu noktada 443 portunun dinlenmesi gerektiğini Apache'ye söyleyen Listen 443 satırının da bulunduğundan emin olun. Debian tarafında bu satır /etc/apache2/ports.conf içinde, RHEL tarafında ise genellikle /etc/httpd/conf.d/ssl.conf içinde tanımlıdır. Eksikse ekleyin; aksi halde VirtualHost bloğunuz doğru olsa bile Apache 443'ü dinlemez.
443 Portu için VirtualHost Bloğu#
SSL yapılandırmasının kalbi, 443 portunu hedefleyen bir VirtualHost bloğudur. Burada sertifika dosyalarının yollarını, sunucu adını ve doküman kökünü tanımlarsınız. Elinizde üç dosya bulunması gerekir: sunucu sertifikası, özel anahtar ve (varsa) ara sertifika zinciri. Let's Encrypt kullanıyorsanız fullchain.pem zaten zinciri içerir; ticari bir sertifika satın aldıysanız CA'nın verdiği bundle dosyasını SSLCertificateChainFile ile ayrıca belirtmeniz gerekebilir.
Aşağıdaki örnek bloğu kendi alan adınıza uyarlayın. Debian'da bunu /etc/apache2/sites-available/ornek-ssl.conf olarak, RHEL'de /etc/httpd/conf.d/ornek-ssl.conf olarak kaydedebilirsiniz:
<VirtualHost *:443>
ServerName ornek.com
ServerAlias www.ornek.com
DocumentRoot /var/www/ornek
SSLEngine on
SSLCertificateFile /etc/ssl/ornek/fullchain.pem
SSLCertificateKeyFile /etc/ssl/ornek/privkey.pem
# Ticari sertifikada zincir ayrıysa:
# SSLCertificateChainFile /etc/ssl/ornek/chain.pem
<Directory /var/www/ornek>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/ornek-ssl-error.log
CustomLog ${APACHE_LOG_DIR}/ornek-ssl-access.log combined
</VirtualHost>
Debian ailesinde yeni siteyi etkinleştirmek için a2ensite kullanın; RHEL'de dosya conf.d altında olduğu için ek komuta gerek yoktur:
# Debian/Ubuntu
sudo a2ensite ornek-ssl.conf
sudo apache2ctl configtest # sözdizimi kontrolü
sudo systemctl reload apache2
configtest (ya da apachectl -t) adımını asla atlamayın. SSL bloklarında küçük bir yazım hatası bile Apache'nin başlamamasına yol açar ve o anda sitede yayında olan başka VirtualHost'lar da düşer. Test yeşil "Syntax OK" verdikten sonra reload edin.
Güvenli Protokol Seçimi: SSLProtocol#
Sertifikayı yükledikten sonra en kritik adım, hangi TLS sürümlerine izin vereceğinizi belirlemektir. SSLv2, SSLv3, TLS 1.0 ve TLS 1.1 bugün kırık kabul edilir; POODLE, BEAST gibi saldırılar bu sürümleri hedefler ve PCI-DSS gibi uyumluluk standartları bunların kapatılmasını zorunlu tutar. Modern bir sunucuda yalnızca TLS 1.2 ve TLS 1.3 açık olmalıdır.
SSLProtocol direktifini eski sürümleri açıkça reddedecek şekilde ayarlayın. Bu satırı VirtualHost içine koyabileceğiniz gibi, tek yerden tüm siteleri yönetmek için ayrı bir global dosyaya (/etc/apache2/conf-available/ssl-hardening.conf gibi) da yazabilirsiniz:
# Sadece TLS 1.2 ve TLS 1.3'e izin ver
SSLProtocol -all +TLSv1.2 +TLSv1.3
Buradaki -all ifadesi önce tüm protokolleri kapatır, ardından +TLSv1.2 +TLSv1.3 yalnızca güvenli olanları geri açar. Bu "önce hepsini kapat, sonra istediğini aç" yaklaşımı, ileride OpenSSL yeni bir protokol eklediğinde onun otomatik olarak açık gelmemesini garanti eder; yani güvenli tarafta kalırsınız.
TLS sürümlerinin destek durumunu ve güvenlik seviyesini şöyle özetleyebiliriz:
| Protokol | Durum | Öneri |
|---|---|---|
| SSLv2 / SSLv3 | Kırık, birçok saldırıya açık | Kesinlikle kapatın |
| TLS 1.0 | Eski, PCI-DSS uyumsuz | Kapatın |
| TLS 1.1 | Eski, artık desteklenmiyor | Kapatın |
| TLS 1.2 | Güvenli, yaygın | Açık tutun |
| TLS 1.3 | En güvenli, en hızlı el sıkışma | Açık tutun |
TLS 1.3 desteği için Apache 2.4.37 ve üzeri ile OpenSSL 1.1.1 veya daha yenisine ihtiyaç duyarsınız. Sürümünüz eskiyse openssl version ve apache2 -v çıktılarını kontrol edin; güncel bir dağıtım kullanmak hem performans hem güvenlik açısından en sağlıklısıdır.
Cipher Suite ve SSLHonorCipherOrder#
Protokol sürümünü sabitledikten sonra sıra, el sıkışma sırasında kullanılacak şifreleme algoritmalarını (cipher suite) seçmeye gelir. Amaç; ileri gizlilik (forward secrecy) sağlayan ECDHE tabanlı, AEAD modundaki (GCM, ChaCha20-Poly1305) modern algoritmaları tercih etmek, RC4, 3DES ve MD5 gibi zayıf olanları dışlamaktır. Böylece bir sunucu anahtarı ileride ele geçse bile geçmiş trafik çözülemez.
Aşağıdaki değerler, geniş tarayıcı uyumluluğunu koruyarak güçlü bir seçim sunar:
SSLCipherSuite HIGH:!aNULL:!MD5:!RC4:!3DES:!EXPORT:!DES:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305
# Sunucunun cipher tercihini istemciye dayat (TLS 1.2 için önemli)
SSLHonorCipherOrder on
SSLHonorCipherOrder on direktifi, hangi cipher'ın kullanılacağına istemcinin değil sunucunun karar vermesini sağlar. Bunu açık bırakmazsanız, eski bir tarayıcı listenizdeki en zayıf algoritmayı seçebilir. Not olarak: TLS 1.3'te cipher pazarlığı yeniden tasarlandığı için bu direktifin etkisi yalnızca TLS 1.2 ve öncesindedir; yine de açık tutmakta fayda var.
Bir başka önemli koruma da güvenli yeniden pazarlık ve sıkıştırma açıklarını kapatmaktır. Aşağıdaki iki satırı ekleyerek CRIME saldırısına yol açabilen TLS sıkıştırmasını ve istemci kaynaklı yeniden pazarlığı devre dışı bırakın:
SSLCompression off
SSLInsecureRenegotiation off
SSLSessionTickets off
Yapılandırmanın gerçekten istediğiniz gibi çalışıp çalışmadığını komut satırından hızlıca test edebilirsiniz. Örneğin sadece TLS 1.3 ile bağlanmayı denemek için:
openssl s_client -connect ornek.com:443 -tls1_3 </dev/null 2>/dev/null | grep -i protocol
Kapalı olması gereken TLS 1.0'a bağlanmayı denediğinizde ise bağlantının reddedilmesini beklersiniz:
openssl s_client -connect ornek.com:443 -tls1 </dev/null
# "no protocols available" veya handshake failure => doğru davranış
Cipher ve protokol tercihlerini elle ayarlamakla uğraşmak istemiyorsanız, Mozilla'nın SSL Configuration Generator aracı Apache sürümünüze ve hedeflediğiniz uyumluluk seviyesine (modern/intermediate/old) göre hazır bir blok üretir; çıktıyı buradaki mantıkla karşılaştırarak kullanabilirsiniz.
HSTS Başlığı ile HTTPS'i Zorunlu Kılma#
Sitenizi HTTPS'e taşımak, tek başına saldırganın araya girmesini (man-in-the-middle) engellemez. Kullanıcı adres çubuğuna http:// yazdığında ya da eski bir bağlantıya tıkladığında ilk istek hâlâ şifresiz gider ve tam o anda downgrade saldırısına açık olur. HSTS (HTTP Strict Transport Security) başlığı, tarayıcıya "bu alan adına bundan sonra yalnızca HTTPS ile bağlan, http'yi hiç deneme bile" talimatını verir ve bu açığı kapatır.
HSTS eklemek için daha önce etkinleştirdiğimiz mod_headers modülü gerekir. Başlığı 443 VirtualHost'unun içine ekleyin:
<VirtualHost *:443>
# ... sertifika ve diğer ayarlar ...
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
</VirtualHost>
Direktifteki parçaları tek tek anlamak önemlidir:
max-age=63072000— Tarayıcının bu kuralı hatırlayacağı süre, saniye cinsinden (burada 2 yıl). Test aşamasında bunu düşük tutun (örneğin300), her şey yolundaysa yükseltin.includeSubDomains— Kuralıwww,blog,panelgibi tüm alt alan adlarına da uygular. Tüm alt alan adlarınız gerçekten HTTPS destekliyorsa ekleyin; aksi halde erişilemeyen bir alt alan adını kilitleyebilirsiniz.preload— Alan adınızın tarayıcıların gömülü HSTS ön yükleme listesine eklenmesini talep eder. Bu listeye girmek, kullanıcının siteye ilk ziyaretinde bile http denemesini engeller; ancak geri dönüşü zordur, bu yüzden yalnızca kalıcı olarak HTTPS'te kalacağınıza eminseniz kullanın.
Header always set ifadesindeki always anahtar kelimesi kritiktir; onsuz başlık yalnızca 2xx yanıtlarda gönderilir, hata sayfalarında (404, 500) gönderilmez. always ile her yanıt kodunda başlığın eklenmesini garanti edersiniz. HSTS'yi tam olarak devreye almadan önce sertifikanızın sorunsuz çalıştığından ve yenileme (renewal) sürecinizin oturmuş olduğundan emin olun; ücretsiz sertifika kurulumunu ayrıntılı ele aldığımız Let's Encrypt ile ücretsiz SSL rehberi bu konuda yardımcı olur.
HTTP'den HTTPS'e Kalıcı Yönlendirme#
HSTS ilk ziyaretten sonra tarayıcıyı yönlendirir, ama sunucunuz yine de 80 portundan gelen istekleri karşılamalı ve hepsini nazikçe 443'e taşımalıdır. Bunun en temiz yolu, 80 portu için ayrı bir VirtualHost bloğu tutup içinde kalıcı (301) bir yönlendirme tanımlamaktır. 301 kodu tarayıcılara ve arama motorlarına adresin kalıcı olarak değiştiğini bildirir; SEO açısından doğru sinyaldir.
En basit ve en performanslı yöntem Redirect direktifi ya da RewriteRule ile yapılan yönlendirmedir:
<VirtualHost *:80>
ServerName ornek.com
ServerAlias www.ornek.com
# Yöntem 1: mod_rewrite ile (yol/query korunur)
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
</VirtualHost>
mod_rewrite kullanmak istemiyorsanız, aynı işi daha hafif bir şekilde Redirect ile de görebilirsiniz:
<VirtualHost *:80>
ServerName ornek.com
ServerAlias www.ornek.com
# Yöntem 2: basit ve hızlı
Redirect permanent / https://ornek.com/
</VirtualHost>
İki yaklaşımın farkı incedir ama önemlidir: RewriteRule ile %{REQUEST_URI} kullandığınızda kullanıcının gittiği tam yol (/urunler/123?renk=mavi gibi) HTTPS tarafında da korunur. Redirect permanent / https://ornek.com/ biçimi ise kök adresi hedef alarak yolu genellikle taşır; ancak alan adı sabit yazıldığı için birden fazla ServerAlias varsa her istek ornek.coma gider. Çoğu senaryoda yol ve alan adını dinamik tutan birinci yöntem daha esnektir.
Yönlendirmeyi doğrulamak için curl ile başlıkları inceleyin; HTTP/1.1 301 ve Location: https://... satırlarını görmelisiniz:
curl -I http://ornek.com
# Beklenen:
# HTTP/1.1 301 Moved Permanently
# Location: https://ornek.com/
Yönlendirme mantığında sık yapılan bir hata, 80 ve 443 bloklarını iç içe geçirmek ya da yönlendirmeyi HTTPS VirtualHost'un içine koyarak sonsuz döngü yaratmaktır. Yönlendirme kuralı yalnızca 80 portu bloğunda, sertifika ve içerik ise yalnızca 443 bloğunda olmalıdır. Apache ile Nginx'in yönlendirme ve genel yapılandırma mantığını karşılaştırmak isterseniz Apache ile Nginx karşılaştırması yazımız iki sunucunun yaklaşımını yan yana koyuyor.
Yapılandırmayı Test Etme ve Doğrulama#
Tüm bloklar yerine oturduktan sonra son adım, kurgunun dışarıdan gerçekten güvenli göründüğünü doğrulamaktır. Yerelde apache2ctl configtest ile sözdizimini kontrol edip servisi reload ettikten sonra, dışarıdan kapsamlı bir tarama yapmak yerinde olur. En yaygın araç SSL Labs'in çevrimiçi testidir; A veya A+ notu hedefleyin. Zayıf protokol, eksik zincir sertifikası veya güvensiz cipher varsa rapor bunları tek tek gösterir.
Komut satırından hızlı bir sağlık kontrolü için sertifikanın son kullanma tarihini ve zincirini şöyle görebilirsiniz:
# Sertifikanın geçerlilik tarihleri
echo | openssl s_client -connect ornek.com:443 -servername ornek.com 2>/dev/null | openssl x509 -noout -dates
# Sunulan zincirin tamamı
openssl s_client -connect ornek.com:443 -servername ornek.com -showcerts </dev/null
-servername parametresini eklemeyi unutmayın; aynı IP üzerinde birden fazla SSL sitesi barındırıyorsanız (SNI), bu parametre olmadan yanlış sertifikayı test edebilirsiniz. Sertifika yenileme sürecinizi de otomatikleştirin: Let's Encrypt'te certbot renew zaten cron ile çalışır ama yenilemeden sonra Apache'nin reload edildiğinden emin olun, aksi halde yeni sertifika belleğe alınmaz. Bu tür sunucu tarafı bakım ve sertifika yönetimini kendiniz üstlenmek istemiyorsanız, sunucu yönetimi hizmetimizle bu yükü ekibimize devredebilirsiniz.
Sık karşılaşılan bir başka konu da "mixed content" (karışık içerik) uyarısıdır: sayfa HTTPS ile açılır ama içindeki bazı resim, CSS veya script hâlâ http:// ile çağrılır. Tarayıcı bu durumda kilit simgesini eksik gösterir. Uygulama tarafında tüm iç bağlantıları protokolden bağımsız ya da açıkça https:// yapın; WordPress kullanıyorsanız site URL'sini HTTPS olarak güncellemek çoğu sorunu çözer. Bu konuda düzenli bakım desteği için WordPress bakım hizmetimize göz atabilirsiniz.
Sıkça Sorulan Sorular#
mod_ssl ile OpenSSL arasındaki fark nedir?#
OpenSSL, şifreleme algoritmalarını, sertifika işlemlerini ve TLS el sıkışmasını gerçekleştiren temel kütüphanedir; işletim sistemi düzeyinde çalışır. mod_ssl ise Apache'nin bu kütüphaneyle konuşmasını sağlayan köprüdür, yani Apache'ye TLS yeteneği kazandıran modüldür. Kısaca OpenSSL motoru, mod_ssl ise o motoru Apache'ye bağlayan direksiyon sistemidir; ikisi birlikte çalışır ve TLS 1.3 gibi yeni özellikler için ikisinin de yeterince güncel olması gerekir.
SSLProtocol satırını her VirtualHost içine ayrı ayrı yazmalı mıyım?#
Zorunlu değil, hatta önerilmez. Protokol, cipher ve HSTS gibi güvenlik direktiflerini tek bir global dosyada (örneğin ssl-hardening.conf) toplamak, ilerideki bakımı çok kolaylaştırır. Böylece cipher listesini güncellemeniz gerektiğinde onlarca VirtualHost yerine tek dosyayı düzenlersiniz. Yalnızca bir siteye özel bir istisna gerekiyorsa, o ayarı ilgili VirtualHost içinde ezerek (override) uygulayabilirsiniz.
HSTS başlığını ekledikten sonra siteme HTTP ile erişemiyorum, geri alabilir miyim?#
HSTS'nin kalıcı yapısı tam da bu yüzden dikkat ister. Başlığı sunucudan kaldırsanız bile, kuralı daha önce almış tarayıcılar max-age süresi dolana kadar sitenize yalnızca HTTPS ile bağlanmaya devam eder. Bu yüzden HSTS'yi ilk açtığınızda max-age değerini düşük tutmak (örneğin birkaç dakika) ve her şeyin sağlam çalıştığından emin olduktan sonra yükseltmek en güvenli yoldur. preload listesine girdiyseniz geri dönüş çok daha zordur ve ayrı bir çıkarma başvurusu gerektirir.
Ücretsiz Let's Encrypt sertifikası ile ticari sertifika arasında yapılandırma farkı var mı?#
Apache tarafındaki mantık ikisinde de aynıdır; SSLCertificateFile ve SSLCertificateKeyFile direktifleri her iki durumda da kullanılır. Fark daha çok dosya biçiminde ve zincirdedir. Let's Encrypt size fullchain.pem verir ve zincir bunun içindedir, ayrıca SSLCertificateChainFile belirtmenize gerek kalmaz. Ticari sertifikalarda CA çoğunlukla ayrı bir ara sertifika (bundle) dosyası verir ve bunu ya fullchain'e birleştirmeniz ya da chain direktifiyle ayrıca göstermeniz gerekir. Güvenlik seviyesi doğru yapılandırıldığında ikisinde de eşittir; ticari sertifikalar ek olarak sigorta ve kuruluş doğrulaması gibi ticari avantajlar sunar.
Sertifikamı yükledim ama tarayıcı hâlâ güvenli değil diyor, sorun ne olabilir?#
En sık üç nedeni vardır. Birincisi eksik zincir sertifikasıdır; sunucu ara sertifikayı sunmuyorsa bazı tarayıcılar sertifikaya güvenmez, bunu openssl s_client -showcerts ile kontrol edebilirsiniz. İkincisi mixed content sorunudur; sayfa HTTPS ile açılsa da içindeki bazı kaynaklar http ile çağrıldığında kilit kırık görünür. Üçüncüsü ise alan adı uyuşmazlığıdır; sertifika ornek.com için düzenlenmişken kullanıcı www.ornek.com ile giriyorsa ve sertifikada bu alt alan adı yoksa uyarı çıkar. Bu üç noktayı sırayla kontrol etmek sorunların büyük çoğunluğunu çözer.
Apache SSL yapılandırması performansı yavaşlatır mı?#
Modern donanımda etkisi çok küçüktür ve genellikle ihmal edilebilir. TLS el sıkışması ilk bağlantıda küçük bir CPU maliyeti getirir, ancak oturum yeniden kullanımı (session resumption) ve TLS 1.3'ün tek tur el sıkışması bu maliyeti büyük ölçüde azaltır. Ayrıca HTTP/2 yalnızca TLS üzerinden çalıştığı için HTTPS'e geçmek çoğu zaman siteyi yavaşlatmak yerine hızlandırır. ECDHE tabanlı cipher'lar ve GCM modları hem güvenli hem de donanım hızlandırmasından yararlandığı için performans endişesiyle güvenlikten ödün vermenize gerek yoktur.
Kapanış#
Apache üzerinde SSL yapılandırmak, sertifikayı yüklemekle bitmeyen; protokol seçimi, cipher sertleştirmesi, HSTS ve doğru yönlendirme ile tamamlanan bir zincirdir. Bu adımları bir kez düzgün kurduğunuzda hem kullanıcılarınızın verisini korur hem de arama motorları ve güvenlik tarama araçları karşısında güçlü bir duruş sergilersiniz. Anahtar nokta her değişiklikten sonra configtest çalıştırmak, dışarıdan bir SSL testiyle sonucu doğrulamak ve sertifika yenilemeyi otomatikleştirmektir.
Bu kurulum ve bakımı kendiniz üstlenmek yerine hazır ve güvenli bir altyapıda çalışmak isterseniz, güçlü hosting ve WordPress hosting paketlerimizde SSL kurulumu ve yönetimi büyük ölçüde sizin için otomatikleştirilmiştir. Tam kontrol isteyen ekipler için sanal sunucu ve VDS sunucu çözümlerimiz, dilerseniz sunucu yönetimi desteğiyle birlikte gelir. Sertifika ihtiyaçlarınız için SSL sayfamıza, ek güvenlik katmanları için WAF ve DDoS koruma hizmetlerimize göz atabilir; sitenizi bize taşımak isterseniz ücretsiz site taşıma ekibimizle iletişime geçebilirsiniz.