İmzalı URL gerçekte neyi vaat eder
Üç şeyi; ve net olmakta fayda var, çünkü insanlar bir dördüncüsünü bekliyor.
Bağlantının sizden geldiğini kanıtlar. İmza; yolun, son kullanma zamanının ve yalnızca sunucunuzun bildiği bir gizli anahtarın hash'idir. Gizli anahtar olmadan kimse çalışan bir bağlantı uyduramaz.
Süresi dolar. Son kullanma zamanı imzalanan şeyin bir parçasıdır; yani imzayı bozmadan düzenlenemez.
Origin'inize dokunulmadan kontrol edilir. CDN edge'inde imzasız bir istek edge'de reddedilir; sunucunuz onu hiç görmez.
Vaat etmediği şey: bağlantıyı açan kişinin dosyayı kaydedip bir arkadaşına e-postayla göndermeyeceği. İmzalı URL, baytlara değil URL'ye erişimi denetler. İndirmeden sonra da kontrol istiyorsanız aradığınız şey DRM'dir; o da başka ve çok daha ağır bir üründür.
İki aile: edge imzaları ve presigned URL'ler
Edge'deki yol imzaları — CDN'in size verdiği şey. Uygulamanız bir yol ve bir son kullanma zamanı için imza hesaplar; edge de geldiğinde onu doğrular. Dosya, CDN'in ulaşabildiği herhangi bir yerde durabilir ve kontrol ziyaretçiye yakın bir yerde yapılır.
Object storage'ın ürettiği presigned URL'ler — S3 ve S3 uyumlu depolamanın size verdiği şey. Geçici URL'yi, erişim anahtarınızla imzalayarak depolama servisinin kendisi üretir ve genelde dakikalarla ölçülen bir geçerliliği olur. İmza sorgu dizesinde X-Amz-Signature ve arkadaşları olarak gider.
Bunlar rakip değil. Yaygın ve makul bir düzen, object storage'ı bir CDN'in arkasına koymak, genel URL'yi edge imzasıyla korumak ve kimse edge'i atlayamasın diye bucket'ı gizli tutmaktır. Yapmamanız gereken şey, bir presigned depolama URL'sini doğrudan herkese açmak ve CDN'in onu koruduğunu varsaymaktır — bağlantı bucket'ı gösteriyorsa edge zaten yolun üzerinde değildir.
cdn.com.tr'de nasıl çalışır
Bu bir dağıtım kuralı ayarıdır; yani sitenin geri kalanı herkese açık kalırken /downloads yolunu koruyabilirsiniz. O kural için süresi dolan bağlantıları açın, bir gizli anahtar belirleyin ve bağlantıları uygulamanızda üretin.
İmza; son kullanma zamanı, yol ve önünde tek boşluk bulunan gizli anahtar birleştirildikten sonra alınan ham MD5'in base64url biçimidir.
``` $uri = "/downloads/report.pdf"; $expires = time() + 600; // ten minutes $secret = "your-long-random-secret";
$token = rtrim(strtr(base64_encode( md5($expires . $uri . " " . $secret, true) ), "+/", "-_"), "=");
$url = "https://cdn.example.com{$uri}?md5={$token}&expires={$expires}"; ```
Üç sonuç var ve loglarınız birbirinden ayırabilsin diye bilerek farklı tutuldular:
| İstek | Yanıt | |---|---| | Geçerli imza, süresi dolmamış | dosya, normal şekilde önbelleğe alınır | | İmza yok ya da yanlış | 403 | | Doğru imza, süresi dolmuş | 410 |
410, göründüğünden önemlidir. Bir müşteri "bağlantınız bozuk" dediğinde, tek başına durum kodu size ona hatalı bir bağlantı mı gönderildiğini yoksa sadece çok mu beklediğini söyler — üstelik ondan hiçbir şey istemeden.
Size CDN'i kaybettiren önbellek tuzağı
Çoğu belgede eksik olan kısım burası ve canınızı yakan da bu.
Her imzalı bağlantı benzersizdir: her ziyaretçi ve her üretim için farklı bir md5 ve farklı bir expires. Önbellek anahtarınız sorgu dizesini içeriyorsa — ki yaygın varsayılan budur ve siz değiştirmedikçe bizdeki de öyledir — imzalı her istek ayrı bir önbellek kaydı olur. Korumalı dosyalarda isabet oranı sıfıra iner, her indirme origin'inizden çekilir ve proxy gibi davranan bir CDN'in parasını ödemiş olursunuz.
Çözüm tek bir ayar. Dağıtım kuralında sorgu dizesi modunu, imza parametreleri önbellek anahtarına girmeyecek şekilde ayarlayın:
- Yoksayma listesi — md5 ve expires yok sayılsın, anlamlı olan diğer her şey kalsın. Aynı dosya gerçek parametrelerle de çekiliyorsa doğru tercih budur.
- Tümünü yoksay — korumalı yollar hiçbir anlamlı parametre almıyorsa en basit seçenek; indirmelerde genelde durum budur.
Varsaymak yerine sonradan kontrol edin: aynı dosyayı iki farklı geçerli imzayla iki kez isteyin ve önbellek durumu başlığına bakın. İkincisi isabet olmalı. İkisi de ıskaysa anahtar hâlâ imzayı içeriyordur.
Süreyi seçmek
Sızan bir bağlantı değersiz kalacak kadar kısa; kötü bir bağlantıda indirme bitecek kadar uzun.
Belgeler ve görseller: beş ila on beş dakika. Tıklamadan hemen sonra çekilirler.
Büyük videolar ve arşivler: bir ila altı saat. Yavaş bir mobil bağlantıda iki gigabaytlık bir dosya insanların beklediğinden uzun sürer ve indirmenin ortasında dolan bir süre, bozulma gibi görünen bir destek talebi üretir.
Yayın manifestleri dikkat ister. HLS'te oynatıcı önce manifesti, sonra oynatma boyunca çok sayıda segmenti çeker. Her segmenti kısa süreyle imzalarsanız uzun bir videoda oynatma ortada kesilir. Bütün oturumu kapsayan bir süreyle imzalayın ya da manifesti imzalayıp segmentleri başka bir kontrolle koruyun.
Yapamayacağınız tek şey, üretilmiş tek bir bağlantıyı iptal etmektir. Süresi dolana kadar geçerlidir, o kadar. Anında iptal gerekiyorsa gizli anahtarı değiştirin — bu da o ana kadar ürettiğiniz bütün bağlantıları geçersiz kılar.
Gizli anahtarı sızdıran hatalar
Tarayıcıda imzalamak. Gizli anahtar JavaScript'in içindeyse o anahtar herkese açıktır. İmzalama her zaman sunucuya aittir. Kulağa apaçık geliyor ve anahtarların kaçmasının tek en yaygın yolu bu.
Bağlantıları build sırasında üretmek. Statik bir build sırasında üretilen bağlantı, build anında konmuş bir son kullanma zamanı taşır ve sayfa hâlâ yayındayken ölür. İstek anında üretin ya da yönlendirme yapan küçük bir uç üzerinden verin.
Saat kayması. Son kullanma zamanı edge'in saatiyle karşılaştırılır. Uygulama sunucunuz dakikalarca gerideyse bağlantılar ölü doğar. NTP'yi çalışır tutun; bir bağlantı üretildiği anda başarısız oluyorsa koddan önce saate bakın.
Gizli anahtarı depoya koymak. Ona bir kimlik bilgisi gibi davranın: sürüm kontrolüne değil ortam değişkenine. Ekipten biri ayrıldığında değiştirin.
Değiştirmenin herkesi etkilediğini unutmak. Gizli anahtarı değiştirmek, beş dakika önce gönderilen e-postalardakiler dahil, dolaşımdaki bütün bağlantıları tek seferde geçersiz kılar. Bir olay sırasında tam olarak istediğiniz, cuma öğleden sonra kazayla yaptığınızda ise hiç istemediğiniz şey budur.
İmzalı URL SSS
İmzalı URL ile presigned URL arasındaki fark nedir?
Çoğunlukla kontrolün nerede yapıldığı. "Presigned URL", depolama servisinin ürettiği ve yine kendisinin doğruladığı geçici bağlantı için kullanılan S3 terimidir. CDN edge'indeki imzalı URL ise ziyaretçiye yakın bir yerde, edge'de doğrulanır ve yalnızca bir bucket için değil herhangi bir origin için çalışır. Kavram aynı: sorgu dizesinde bir imza ve bir son kullanma zamanı.
Biri imzalı bir bağlantıyı paylaşabilir mi?
Evet, süresi dolana kadar. İmza, bağlantıyı sizin ürettiğinizi kanıtlar; onu kimin elinde tuttuğu hakkında bir şey söylemez. Kısa süreler zararı sınırlar. Bağlantının tek bir kişiye bağlı olması gerekiyorsa imzalanan yola kimliğe dair bir şey koyup kendi tarafınızda kontrol edin ve kararlı bir paylaşımcının indirdiği dosyayı yine de iletebileceğini kabul edin.
İmzalama önbelleklemeye zarar verir mi?
Yalnızca imzanın önbellek anahtarına girmesine izin verirseniz; o zaman da fena zarar verir — her benzersiz bağlantı kendi önbellek kaydı olur ve her indirme origin'inize gider. Sorgu dizesi modunu imza parametrelerini yok sayacak şekilde ayarlayın; dosya normal şekilde önbelleğe alınır ve geçerli bağlantısı olan herkes arasında paylaşılır.
Tek bir bağlantıyı iptal edebilir miyim?
Tek tek edemezsiniz. İmza süresi dolana kadar geçerlidir, çünkü doğrulama durum tutmaz — çıkarılacağı bir liste yoktur. Elinizdeki kontroller kısa bir süre ve gizli anahtarı değiştirmektir; ikincisi her şeyi tek seferde geçersiz kılar.
MD5 bunun için kırılmış değil mi?
MD5, çakışma direnci açısından kırılmıştır; bu da saldırganın iki mesajı da seçebildiği durumlarda önem taşır. Burada saldırganın, elinde olmayan bir gizli anahtarı içeren bir metnin hash'ini üretmesi gerekir; bu bir çakışma değil ön görüntü problemidir. Pratikteki risk, gizli anahtarın sızması ya da tahmin edilebilir olmasıdır — uzun ve rastgele bir anahtar kullanın, sunucu tarafında tutun ve belirli aralıklarla değiştirin.
HLS video için bunu kullanmalı mıyım?
Oturum süresi çekincesiyle çalışır: sürenin yalnızca manifest isteğini değil oynatmanın tamamını kapsaması gerekir, yoksa oynatma ortada durur. Uzun içerikte, oynatıcıyı bozan çok kısa bir süre yerine cömert bir süreyi rate limiting ile birlikte kullanın.