Aylık bant genişliğine bakıyorsun ve geçen aya göre üç kat tüketildiğini görüyorsun. Sitenin trafiği artmamış, loglarda bir saldırı da yok, ama görsel dosyaların başka siteler için senin sunucundan sunuluyor. Bu tam olarak hotlink protection'ın çözmek için yapıldığı şeydir: başka sitelerin görsellerini doğrudan kendi sayfalarında yükleyip bant genişliğini tüketmesini önlemek.
Herhangi bir şey yapmadan önce, sorunun gerçekten hotlink olup olmadığından emin olmalısın. Hızlı bir yol: sunucu erişim logunda Referer'ı kendi alan adın olmayan istekleri ara.
grep -i "\.jpg\|\.png\|\.webp" /var/log/nginx/access.log | awk '{print $11}' | sort | uniq -c | sort -rn | head -20
Listede yabancı alan adları başta ise sorun doğrulanır. Eğer sadece kendi alan adın ve arama motorları varsa, başka bir yere bakmalısın; örneğin scraping botları veya katman 7 DDoS saldırısı.
Hotlink protection neden Apache ve Nginx'te farklıdır
Apache'de ana araç .htaccess dosyasıdır. Nginx'te bu iş location bloğunda yapılır ve .htaccess hiç okunmaz. Linux paylaşımlı hostingdeysen neredeyse her zaman Apache veya LiteSpeed ile karşı karşıyasın ve .htaccess çalışır. Nginx'li özel sunucuda ise doğrudan konfigürasyonu düzenlemelisin.
Apache'de htaccess ile
Bu bloğu sitenin kök dizinine veya görseller klasörüne koy:
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?example\.com [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?google\. [NC]
RewriteCond %{HTTP_REFERER} !^https?://(www\.)?bing\. [NC]
RewriteRule \.(jpe?g|png|gif|webp|svg)$ - [F,NC,L]
İlk satır, Referer'ı olmayan istekler için koşulu devre dışı bırakır. Bu önemlidir çünkü bazı kullanıcılar tarayıcıda Referer'ı kapatır ve o satırı silersen görsel onlara yüklenmez. Sonraki satırlar kendi alan adını ve arama motorlarını istisna tutar. Son satır 403 Forbidden koduyla geri kalanı engeller.
Paylaşımlı hostingdeysen ve planında hangi .htaccess komutlarının etkin olduğundan emin değilsen, Linux hosting için eksiksiz htaccess komutları referansı desteklenen modüllerin tam listesini içerir.
Nginx'te
location ~* \.(jpe?g|png|gif|webp|svg)$ {
valid_referers none blocked server_names
*.example.com
*.google.* *.bing.*;
if ($invalid_referer) {
return 403;
}
}
valid_referers komutu aynı anda birkaç durumu kapsar: Referer'ı olmayan istek için none, bozuk Referer için blocked ve konfigürasyonda tanımlı alan adları için server_names. Her değişiklikten sonra nginx -t çalıştır, ardından systemctl reload nginx. Eğer nginx -t hata verirse ve reload yapmazsan, siten eski konfigürasyonla ayakta kalır ve değişikliklerin uygulanmadığını düşünürsün.
Herkesi şaşırtan yan etki: sosyal ağ önizlemeleri
İşte birçok kişinin sorun yaşadığı yer burası. Biri makale linkini Telegram, WhatsApp veya LinkedIn'de gönderdiğinde, o platformun sunucusu öne çıkan görseli (og:image) senin sitenden çeker. Bu isteğin Referer'ı ya boştur ya da platformun kendi alan adıdır. Nginx'te none'u kaldırdıysan veya Apache'de !^$ satırını sildiysen, o istek 403 ile reddedilir ve linkin görsel önizleme olmadan gösterilir.
Belirtisi şudur: kullanıcı "linki gönderdim ama resmi yoktu" der. Sen kendi tarayıcında görseli görürsün çünkü Referer'ın var. Bu fark, tam olarak teşhisi zorlaştıran şeydir.
Çözüm: bilinen önizleme alan adlarını istisna tut. Apache için:
RewriteCond %{HTTP_REFERER} !^https?://([^.]+\.)?(facebook|telegram|whatsapp|linkedin|twitter|x)\. [NC]
Nginx için ise onları valid_referers listesine ekle. Platform sayısı artar ve listeyi korumak zorlaşırsa, diğer seçenek 403 yerine küçük bir yedek görsel döndürmektir:
RewriteRule \.(jpe?g|png|gif|webp)$ /images/blocked.webp [R=302,L]
Bu yöntem orijinal görselden daha az bant genişliği tüketir ve aynı zamanda saldırgan sitenin sayfasını bozmaz. Ancak bir maliyeti vardır: her hotlink isteği hâlâ bir TCP bağlantısı ve bir HTTP yanıtı alır. Yabancı isteklerin hacmi çok yüksekse, aynı 403 daha hafiftir çünkü yanıt gövdesi yoktur.
Burada hata yapıyorlar
Destek taleplerinde gördüğüm en yaygın hata, site yöneticisinin tüm uploads klasörünü kilitleyip sonra "PDF dosyaları ve site videoları açılmıyor" diye şikayet etmesidir. Sebebi, RewriteRule kalıbını sadece görsellere değil tüm uzantılara uygulamış olmasıdır. Kendi alan adından yüklenen bir video veya PDF'in varsa sorun çıkmaz, ancak video oynatıcı ayrı bir CDN kullanıyorsa, o CDN de yabancı alan adı olarak görülür ve dosya engellenir.
Belirtisi şudur: kendi tarayıcında her şey doğrudur, ama kullanıcılar video oynamıyor der. Tarayıcının Network sekmesinde .mp4 dosyası üzerinde 403 yanıtı görürsün ve Referer o CDN'dir. Çözüm: CDN alan adını da istisna listesine ekle.
Yöntemlerin karşılaştırması
| Yöntem | Avantaj | Maliyet |
|---|---|---|
| htaccess ile 403 | Hafif, yanıt gövdesi yok | none kaldırılırsa sosyal ağ önizlemeleri bozulur |
| Yedek görsele yönlendirme | Saldırgan sayfası bozulmaz, dolaylı mesaj verir | Hâlâ bant genişliği tüketilir |
| Token ile URL imzalama | En hassas kontrol, CDN için uygun | Uygulama kodunda değişiklik ve token süresi yönetimi gerekir |
| Görsellere watermark | Marka değerini korur | Bant genişliğini azaltmaz, sadece hırsızlığın etkisini azaltır |
Sadece bant genişliğini kurtarmak istiyorsan, htaccess ile 403'ü seçerim. Görsellerin ticari değere sahipse ve kimsenin sağlam bir kopyasını bile alamamasını istiyorsan, token ile URL imzalama tek gerçek yoldur, ancak uygulama maliyetini kabul etmelisin.
Etkinleştirdikten sonra neyi kontrol etmelisin
- Bir test hotlink sitesinde sitenden bir görsel koy ve 403 aldığını gör.
- Aynı linki Telegram'da gönder ve önizlemenin görseli olduğundan emin ol.
- Search Console'da Googlebot'un görselleri indekslediğini kontrol et.
- 24 saat sonra sunucu loguna bak ve bant genişliği tüketiminin ne kadar düştüğünü gör.
Üçüncü adım için, Googlebot'un hangi IP'lerden geldiğinden emin değilsen, DNS ve ağ sorgulama işine yarar. Ve bant genişliği tüketimini daha hassas izlemek istiyorsan, ücretsiz web yöneticisi araçları iyi analitik raporlar sunar.
Pratik bir not: siten paylaşımlı hostingdeyse ve görsel trafiğin yüksekse, hotlink protection'ı etkinleştirdikten sonra bile bant genişliğin yüksek kalabilir, çünkü scraping botları sahte Referer gönderir. Bu durumda özel sunucuya geçmeyi veya CDN kullanmayı düşünmelisin. Küçük ve orta ölçekli siteler için, .htaccess'i tam destekleyen Linux hosting yeterlidir ve altyapıyı değiştirmene gerek yoktur.
Etkinleştirdikten sonra siten 500 hatasıyla açılmazsa, muhtemelen .htaccess'te bir sözdizimi hatası vardır. Dosyayı FTP üzerinden önceki durumuna döndür ve daha küçük bir blokla tekrar test et. Daha fazla komut öğrenmek için, ServerNet dokümantasyonu ve bilgi bankası iyi bir referanstır.
Sık sorulan sorular
Hotlink protection'ın SEO'ya olumsuz etkisi var mı?
Arama motorlarını istisna tutarsan, hayır. Googlebot görselleri kendi Referer'ıyla ister ve Google alan adı izin listesindeyse görseller yine indekslenir. Sorun, Referer'ı olmayan tüm istekleri engellediğinde ortaya çıkar; bu durumda bazı tarayıcılar görselleri göremeyebilir.
Etkinleştirdikten sonra Telegram ve WhatsApp'ta link önizlemesi neden bozuldu?
Çünkü bu platformların sunucuları öne çıkan görseli boş Referer veya kendi alan adlarıyla ister ve senin izin listende değildir. Önizlemenin geri gelmesi için telegram.org, whatsapp.com, facebook.com ve linkedin.com alan adlarını istisna listesine ekle.
Sadece belirli bir klasör için hotlink protection etkinleştirebilir miyim?
Evet. .htaccess dosyasını sitenin kök dizinine değil, o klasörün içine koy. .htaccess komutları alt klasörlere de özyinelemeli olarak uygulanır, yani sadece images klasörünü korumak istiyorsan, dosyayı oraya koy ve kökten sil.
Hotlink protection ile istek hızı sınırlaması arasındaki fark nedir?
Hotlink protection Referer'a göre karar verir, yani isteğin kaynağını inceler. İstek hızı sınırlaması (rate limiting) belirli bir zaman aralığındaki istek sayısına göre çalışır ve Referer ile ilgilenmez. Bu ikisi birbirini tamamlar: ilki bant genişliği hırsızlığını önler, ikincisi hacim saldırısını.