SSL kurdum ama kilit işareti çıkmıyor: karışık içerik nedir?

Sertifika kurulu olduğu hâlde tarayıcının kilidi vermemesinin sebebi neredeyse her zaman aynıdır: HTTPS ile açılan sayfanın içinde HTTP ile çağrılan bir kaynak vardır. Hangi kaynağın yükseltildiği, hangisinin tamamen engellendiği ve sayfanın neden “bozuk” göründüğü.

DigiWSS Ekibi denetim, güvenlik, https, ssl

Kısa cevap: Sertifika kurulduğu hâlde tarayıcı kilit işaretini vermiyorsa sorun çoğunlukla sertifikada değildir: HTTPS ile açılan sayfa, içinde http:// ile çağrılan bir kaynak barındırıyordur. Buna karışık içerik (mixed content) deniyor. Tarayıcı görsel ve video gibi kaynakları sessizce HTTPS'e yükseltir, ama script ve stil dosyalarını tamamen engeller – işte “SSL kurdum, site bozuldu” şikâyetinin açıklaması budur. Çözüm, sayfadaki adresleri düzeltmektir.

Kilit işaretini sertifika değil, sayfanın tamamı belirler

Sertifika kurmak tek başına bir sonuç üretmez. Tarayıcı adres çubuğuna kilidi koyarken yalnızca “bu sunucunun geçerli bir sertifikası var mı” sorusuna bakmaz; sayfayı oluşturan bütün kaynakların da güvenli bağlantıyla geldiğini kontrol eder. Tek bir görsel, tek bir stil dosyası ya da tek bir gömülü harita hâlâ şifresiz bağlantıyla çağrılıyorsa, sayfanın bütünü artık “tamamen güvenli” sayılmaz.

Mantığı şudur: şifresiz çağrılan bir kaynak yolda değiştirilebilir. Bu kaynak bir görselse zarar sınırlıdır, ama bir script dosyasıysa saldırgan sayfanın tamamını kontrol edebilir. Tarayıcılar bu yüzden karışık içeriği iki sınıfa ayırır ve farklı davranır.

Bu ayrımı bilmek sorunu teşhis etmenin en hızlı yoludur. Sayfa görünüşte düzgün çalışıyor ama kilit yoksa, elinizde yükseltilebilir türde bir kaynak vardır. Sayfa stilsiz açılıyor, menü tıklanmıyor ya da form gönderilmiyorsa, elinizde engellenen türde bir kaynak vardır.

Karışık içerik türleri: hangisi yükseltilir, hangisi engellenir

Yükseltilebilir (upgradable) içerikte tarayıcı adresi kendiliğinden https:// olarak çevirip dener. Engellenen (blockable) içerikte böyle bir nezaket yoktur; kaynak hiç yüklenmez. Aşağıdaki tablo günlük işte karşınıza çıkan bütün durumları toplar.

Kaynak türü Tarayıcı davranışı Görünen belirti Çözümü
<img src>, <video src>, <audio src>, <source src>Yükseltilir: http adresi https olarak denenirKilit yok, konsolda uyarı; görüntü genelde gelirAdresi kaynakta https olarak düzeltin
CSS background-image ve border-imageYükseltilirArka plan görseli kimi sayfada gelmezStil dosyasındaki adresi düzeltin
Kaynak bir IP adresiyse (örneğin görsel sunucusu)Yükseltilmez, ENGELLENİRGörsel hiç yüklenmezIP yerine sertifikalı bir alan adı kullanın
<script src>EngellenirMenü açılmaz, slider durur, form doğrulaması çalışmazAdresi düzeltin ya da kaynağı kaldırın
<link rel=stylesheet>EngellenirSayfa stilsiz, düz metin yığını gibi görünürStil adresini https yapın
<iframe src>, <object data>EngellenirHarita, video ya da ödeme çerçevesi boş kalırGömülü içeriğin https sürümüne geçin
<img srcset> ve <picture>EngellenirDuyarlı görseller hiç çıkmaz, boşluk kalırsrcset içindeki her adresi düzeltin
fetch() ve XMLHttpRequestEngellenirSepet, arama ve form gönderimi sessizce başarısız olurUç adreslerini https yapın
Karışık indirmeler (http bağlantılı dosya)Varsayılan olarak engellenirKatalog ya da fiyat listesi indirilemezDosya bağlantılarını https yapın

Tablonun en kritik satırı IP satırıdır. Bir görseli IP adresiyle çağırıyorsanız tarayıcı bunu yükseltmez, doğrudan engeller – çünkü yükseltme adı üzerinden yapılır ve bir IP adresine sertifika eşlemek güvenilir biçimde mümkün değildir.

Sertifikanın ömrü ve yenileme: unutulursa site kapanır

Ücretsiz sertifika sağlayıcısı Let's Encrypt kullanıyorsanız varsayılan sertifika ömrü 90 gündür ve 60 günde bir yenilenmesi önerilir. Bu, yenilemenin ertelenmesi için otuz günlük bir pay bırakır; yenileme bir kez başarısız olsa bile ikinci deneme için zaman kalır. Let's Encrypt ayrıca altı günlük kısa ömürlü sertifika seçeneği de sunuyor; onu kullanacaksanız üç günde bir yenileme önerilir, yani otomasyon tercihe bağlı değil zorunludur.

Alt alan adlarının tamamını tek sertifikayla kapatmak istiyorsanız joker (wildcard) sertifika destekleniyor, ancak bunun için DNS-01 doğrulaması zorunludur: doğrulama bir dosya yüklemesiyle değil, DNS bölgenize yazılan bir kayıtla yapılır. Pratik sonucu şudur: joker sertifikayı otomatik yenilemek için yenileme aracının DNS sağlayıcınıza erişim izni olması gerekir.

Adım adım: HTTPS'i gerçekten çalışır hâle getirmek

  1. Sertifikayı kurun ve zincirin tam olduğunu doğrulayın. Sunucu yalnızca kendi sertifikasını değil, ara sertifikaları da sunmalıdır. Zincir eksikse masaüstü tarayıcılar eksiği kendi başına tamamlayabilir, bazı mobil cihazlar tamamlamaz; sonuç “bende açılıyor, müşteride açılmıyor” olur.
  2. Otomatik yenilemeyi kurun ve bir kez elle tetikleyip çalıştığını görün. Yenileme görevini kurmak yeterli değildir; bir deneme çalıştırması yapıp çıktısını okuyun. İlk gerçek yenilemenin iki ay sonra olacağını düşünürsek, hatayı bugün görmek tek şansınızdır.
  3. Tarayıcı konsolunda karışık içerik uyarılarını toplayın. Siteyi HTTPS ile açıp geliştirici araçlarının konsolunu açın ve ana sayfa dışında en az bir ürün, bir blog yazısı ve bir form sayfası dolaşın. Uyarılar genelde şablonun tamamında değil, tek tek sayfalarda gömülü kalmış adreslerden çıkar.
  4. Veritabanındaki ve şablondaki http adreslerini düzeltin. İçerik yönetim sistemi kullanıyorsanız adreslerin büyük kısmı şablonda değil veritabanındaki içerik alanlarında durur. Toplu değiştirme yapmadan önce veritabanı yedeği alın.
  5. Üçüncü taraf gömülü içeriğin HTTPS sürümüne geçin, yoksa kaldırın. Harita, sohbet kutusu, eski bir rezervasyon formu ya da sayaç betiği HTTPS sunmuyorsa onu düzeltmenin yolu yoktur; kaldırmak gerekir. Engellenmiş bir çerçeve, boş bir kutu olarak kalır ve kullanıcı bunu sitenin arızası sanır.
  6. HTTP'den HTTPS'e 301 yönlendirmesini kurun. Sertifika kurulduktan sonra eski adresler hâlâ çalışıyorsa iki ayrı site yayında demektir. Yönlendirme tek kuralla, her adresi kendi karşılığına gönderecek biçimde kurulur.
  7. HSTS başlığını ekleyin. Yönlendirme çalıştığı doğrulandıktan SONRA ekleyin. Başlık, tarayıcıya bu alan adına bundan sonra yalnızca HTTPS ile bağlanmasını söyler.
  8. Konsolun temiz olduğunu doğrulayın. Aynı sayfaları yeniden dolaşın; konsolda tek bir karışık içerik satırı kalmamalı. Kilit işareti çıktığında iş bitmiş sayılır, önce değil.

HSTS başlığı ve geçici CSP çözümü

Aşağıdaki iki örnek gerçektir; alan adı geçmediği için yer tutucuya da ihtiyaç yok.

# HSTS basligi, yalnizca HTTPS yanitinda gonderilir
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
# gecici cozum, HTTP basligi olarak
Content-Security-Policy: upgrade-insecure-requests
# ayni yonerge, sayfanin head bolumunde meta etiketi olarak
<meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests">

HSTS başlığının kuralları net: preload listesine girmek istiyorsanız max-age değeri en az 31536000 (bir yıl) olmalı ve includeSubDomains bulunmalıdır. Başlık yalnızca HTTPS üzerinden gönderilir; HTTP üzerinden gelirse tarayıcı onu yok sayar. HSTS devredeyken kullanıcı sertifika hatasını “yine de devam et” diyerek geçemez – güvenlik açısından istenen davranış budur, ama HTTPS'i bozarsanız sitenize kimsenin giremeyeceği anlamına da gelir. Son bir ayrıntı: preload listesi Google tarafından barındırılıyor ve bütün büyük tarayıcılar onu kullanıyor, fakat liste HSTS spesifikasyonunun parçası değildir.

İkinci ve üçüncü satırdaki upgrade-insecure-requests yönergesi, sayfadaki şifresiz istekleri tarayıcıya yükselterek denetirtir. Başlık olarak ya da sayfanın başına konan bir meta etiketi olarak verilebilir. Bunun KALICI bir çözüm olmadığını özellikle vurgulamak gerekir: adresler hâlâ yanlıştır, yalnızca belirti örtülmüştür. Yarın bir kaynak taşındığında ya da yönergeyi kaldırdığınızda sorun aynen geri döner. Yönergeyi geçişin ilk gününde nefes almak için kullanın, sonra adresleri düzeltip kaldırın.

Yaygın hatalar

  • Sertifikayı kurup yenilemeyi otomatikleştirmemek. 90 gün sonra sertifika düşer ve site, hata ekranını görmeyi kabul eden ziyaretçi dışında kimseye açılmaz. Üstelik bu genelde bir hafta sonu olur.
  • Sertifika zincirini eksik kurmak. Masaüstünde sorunsuz görünür, bazı mobil cihazlarda ve uygulama içi tarayıcılarda güven hatası verir. Teşhisi en zor arızalardan biridir, çünkü sizin cihazınızda hiç görünmez.
  • Karışık içeriği upgrade-insecure-requests ile süpürüp adresleri hiç düzeltmemek. Konsol temizlenir, sorun durur. Yönergeyi taşıyan şablon değiştiğinde ya da yeni bir sayfa eklendiğinde belirti geri gelir ve bu kez sebebi kimse hatırlamaz.
  • HSTS'i preload ile açıp sonra HTTPS'i bozmak. Preload listesindeki bir alan adında tarayıcı HTTP'yi hiç denemez ve sertifika hatasını atlatma seçeneği sunmaz. Geri dönüş pratikte yoktur; sertifikanız bozulduğu sürece kullanıcı içeri giremez.
  • Alt alan adlarında sertifika yokken includeSubDomains vermek. Kural bütün alt adlara yayılır. Sertifikası olmayan bir panel ya da test alt adınız varsa, o adres o anda erişilemez hâle gelir.
  • Yönlendirmeyi kurmadan HSTS eklemek. Başlık yalnızca HTTPS yanıtında gönderildiği için, ziyaretçi siteye HTTP ile geliyorsa başlığı hiç görmez. Sıra önce yönlendirme, sonra başlıktır.

Ne zaman uzmana bırakmalı

Tek sayfalık bir tanıtım sitesinde karışık içerik avı yarım saatlik bir iştir. Şu durumlarda işin boyutu değişir: sitede yıllar içinde farklı kişilerin eklediği üçüncü taraf betikleri varsa, içerik veritabanında binlerce gömülü adres birikmişse, ödeme ya da rezervasyon gibi bir akış şifresiz bir uca bağlıysa, ya da site bir ara katmanın (CDN, güvenlik duvarı) arkasındaysa – bu son durumda sertifika iki ayrı bacakta ayrı ayrı kurulur ve yanlış mod seçimi sonsuz yönlendirme döngüsü üretir.

Mevcut durumun ölçülmüş bir fotoğrafını istiyorsanız teknik denetim çalışmamız sertifika zincirini, yönlendirme sırasını, başlıkları ve sayfa sayfa karışık içerik uyarılarını listeler. Sorularınızı iletişim sayfasından yazabilirsiniz.

Devamını okumak için

Sertifika çalıştıktan sonraki iş arama tarafını bozmadan taşınmaktır: HTTP'den HTTPS'e taşınma, 301 ve canonical yazısı üç katmanın nasıl hizalandığını anlatıyor. Siteyi bir ara katmanın arkasına alacaksanız Cloudflare geçişi ve SSL modu yazısındaki mod tablosuna bakın. Geçişten sonra sayfalar aramada kaybolduysa sitem Google'da çıkmıyor yazısı sırayla eler. Sitenizde beklenmeyen şifresiz kaynaklar ortaya çıkıyorsa bu bir güvenlik belirtisi olabilir; hacklenen siteyi temizleme yazısı ne aranacağını söylüyor. Tüm başlıklar blog sayfamızda, çalışma alanlarımız ana sayfamızda.

Bu yazıyla ilgili sık sorulan sorular

Sertifika kurdum ama kilit işareti çıkmıyor, sebebi ne olabilir?

Neredeyse her zaman karışık içerik: HTTPS ile açılan sayfa, içinde http ile çağrılan bir kaynak barındırıyordur. Tarayıcı görsel ve video gibi kaynakları https olarak yükseltmeyi dener, script ve stil dosyalarını ise tamamen engeller. Sayfayı HTTPS ile açıp geliştirici araçlarının konsolunda uyarıları toplamak, hangi adresin suçlu olduğunu doğrudan gösterir.

Hangi karışık içerik engellenir, hangisi yükseltilir?

Yükseltilenler: img, video, audio ve source etiketlerinin src değerleri ile CSS background-image ve border-image. İstisna: kaynak bir IP adresiyse yükseltilmez, engellenir. Engellenenler: script src, link rel=stylesheet, iframe src, object data, img srcset ve picture, ayrıca fetch ve XMLHttpRequest çağrıları. Karışık indirmeler de varsayılan olarak engellenir.

upgrade-insecure-requests karışık içerik sorununu çözer mi?

Belirtiyi örter, sorunu çözmez. Yönerge başlık olarak ya da meta etiketi olarak verilebilir ve sayfadaki şifresiz istekleri yükseltir. Ancak adresler hâlâ yanlıştır; yönerge kaldırıldığında ya da yeni bir sayfa eklendiğinde sorun geri döner. Geçiş gününde nefes almak için kullanılır, sonra adresler düzeltilir.

Sertifika ne sıklıkla yenilenmeli?

Let's Encrypt sertifikalarında varsayılan ömür 90 gündür ve 60 günde bir yenilenmesi önerilir. Altı günlük kısa ömürlü sertifika seçeneği de vardır; onda üç günde bir yenileme önerilir. Joker sertifika destekleniyor ancak DNS-01 doğrulaması zorunlu olduğu için yenileme aracı DNS bölgenize erişebilmelidir.

HSTS başlığını açmanın riski var mı?

Var. HSTS devredeyken kullanıcı sertifika hatasını yine de devam et diyerek geçemez. Preload listesi için max-age en az 31536000 olmalı ve includeSubDomains bulunmalıdır; alt alan adlarınızda sertifika yoksa bu kural onları erişilemez yapar. Başlık yalnızca HTTPS üzerinden gönderilir, bu yüzden yönlendirme önce kurulur.

Konuşalım

Yazıda anlatılanı işletmenizde uygulamak istiyorsanız adresinizi gönderin; ölçüp ne yapılması gerektiğini paylaşalım.