AWS S3 Presigned URL ve CloudFront Signed URL ile Güvenli Dosya Erişimi

Amazon Web Services (AWS), çeşitli uygulamaları bulut servislerinde dağıtmayı sağlayan; depolama, analiz gibi çeşitli hizmetler sunan bir bulut bilişim servisidir. S3 ve Cloudfront sunulan bu hizmetlerden bazılarıdır.

Amazon S3  (Simple Storage Service) her yerden, her boyutta veri almak ve bulut tabanlı dosya depolamak için oluşturulmuş bir nesne depolama hizmetidir.

CloudFront, AWS’nin içerik dağıtım ağı (CDN) servisidir. S3 gibi kaynaklardaki içeriği kullanıcılara düşük gecikme ile ulaştırmak için optimize edilmiştir.

Bu servislerde depolanan dosyalara güvenli ve zaman sınırlı erişim sağlamak için Presigned URL ve Signed URL gibi yöntemler kullanılır.

Presigned URL, S3 üzerindeki özel dosyalara geçici erişim izni veren şifreli bağlantıdır. Kimlik doğrulama içerir, süresi dolunca erişim kapanır. Signed URL ise CloudFront dağıtımları üzerinde yetkili kullanıcılar tarafından erişilebilen güvenli bağlantılardır. Sadece yetkili anahtarla imzalanmış linkler çalışır.

Bu yazıda AWS platformundaki dosyalara güvenli link ile erişme aşamalarını ele alacağız. Sırasıyla S3’te bucket oluşturup içindeki dosya için presigned url oluşturma, S3-CloudFront bağlantısı kurma ve CloudFront’te signed url oluşturma aşamalarına değinilecek. Her şeyden önce eğer bulunmuyorsa AWS hesabı oluşturup giriş yapmanız gerekiyor.

 

S3 Presigned Url

S3 özelliğini kullanmak için öncelikle AWS konosunda S3 sayfasında bucket oluşturmak gerekiyor. Bucket, Amazon S3’te dosya depolamak için kullanılan en üst düzey klasörlere denir. Bucketların barındırdığı dosyalar için tüm erişim, yetkilendirme gibi işlemler bu bucket üzerinden yönetilir.

Bucketımızı oluşturmak için “Genel amaçlı” türünü seçtikten sonra bucket adını giriyoruz.

Bucket oluşturma ayarları genel

Nesne sahipliğinde önerilen ad, genel erişim ayarlarında herkese açık erişim engelini seçiyoruz. Bu şekilde presigned url olmadan içeriğe erişilemez.

Bucket oluşturma ayarları erişim

Daha sonra varsayılan şifreleme bölümünde de varsayılan seçili ayarlar tutularak “Bucket oluştur” ile bucket oluşturuluyoruz. Bu aşamadan sonra oluşan bucket, Bucketlar sayfasında görülebilir.

Oluşan bucketa tıkladıktan sonra içeriği görülebiliyor. Henüz içine bir şey yüklemedik. Test görseli yüklemek için "Yükle" butonuna basıyoruz. Test yapmak için bucket’ın içine “aws foto” isimli png uzantılı örnek bir görsel yüklüyoruz.

Boş test bucketı

Yüklenen görsel Bucket içeriğinde görülebilir.

Dolu test bucketı

Güvenli link oluşturmak için yerelde bir proje dosyası oluşturmamız gerekiyor. Php dosyası oluşturduktan sonra Php sürümümüze uygun olan Php Sdk’yı indirip oluşturduğumuz proje dizinine ekliyoruz.

Buraya tıklayarak size uygun sdk sürümünü indirebilirsiniz.

İndirilen kütüphanemizi projeye dahil ediyoruz.

Php sdk dahil etme

Daha sonra AWS konsolunda IAM sayfasından IAM kullanıcısı oluşturmamız gerekiyor. "Kullanıcı oluştur" düğmesine bastıktan sonra varsayılan ayarlar ile yeni bir IAM kullanıcısı oluşturuluyor.

IAM kullanıcı oluşturma izinleri

IAM kullanıcı erişimi

Oluşturduğumuz bu kullanıcı için “güvenlik kimlik bilgileri” sekmesinden bir erişim anahtarı oluşturmak gerekiyor. Kullanım durumu olarak “AWS dışında çalışan uygulama”yı seçiyoruz. İsteğe bağlı açıklama ekleyebilirsiniz.

IAM erişim anahtarı oluşturma

Panel, erişim anahtarı ve gizli erişim anahtarı olmak üzere 2 tane anahtar veriyor. Oluşan erişim anahtarının CSV dosyasını indirmemiz gerekiyor çünkü ilk oluşturma anı dışında bir daha görüntüleme/indirme işlemine izin verilmiyor.

Erişim anahtarı oluşturuldu

Şimdi elimizde S3 bucketı ve IAM kullanıcısı bulunuyor.

Bu bilgilerle presigned URL oluşturmak için aşağıdaki kodu yazdım. Bu bir şifreleme mekanizması olduğu için  istek göndermeden çalışıyor.

Koddaki "credentials"daki "key" ve "secret" bilgileri önceki aşamada oluşan erişim anahtarı ve gizli erişim anahtarı. "Region", AWS konsolunda üstten seçilen bölge. "Bucket" ve "key" ise sırasıyla dosyanın yüklendiği bucket ile dosyanın tam adı. "Expires" linkin geçerlilik süresi. Presigned urllerin link geçerliliği maksimum 1 hafta yani koddaki gibi 604800 saniye olabiliyor. Eğer süresi geçmiş bir linkle içeriğe ulaşılmaya çalışılırsa "expired" uyarısı alınır.

require_once __DIR__ . '/aws/aws-autoloader.php';

//S3 presigned url

use AwsS3S3Client;

$s3 = new S3Client([
    'version' => 'latest',
    'region'  => 'eu-north-1',
    //IAM kullanıcısının erişim anahtarı ve gizli erişim anahtarı
    'credentials' => [
        'key'    => '***',
        'secret' => '***',
    ],
]);

$cmd = $s3->getCommand('GetObject', [
    //bucket adı
    'Bucket' => '***',
    //buckettaki dosya adı
    'Key'    => '***'
]);

$expires = '+604800 seconds'; //geçerlilik süresi (maksimum değeri 1 hafta)

$request = $s3->createPresignedRequest($cmd, $expires);

$presignedUrl = (string) $request->getUri();

echo "$presignedUrl";

Bu şekilde direkt olarak kendi adresine erişilemeyen ama aşağıdaki haliyle açılan bir link oluşuyor. Buna presigned url deniyor.

https://testbucketberkayv2.s3.eu-north-1.amazonaws.com/aws%20foto.png?X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=***********%2F20250618%2Feu-north-1%2Fs3%2Faws4_request&X-Amz-Date=20250618T064205Z&X-Amz-SignedHeaders=host&X-Amz-Expires=604800&X-Amz-Signature=******************

Buradaki parametrelerin özellikleri şu şekilde:
X-Amz-Content-Sha256: Yapılan isteğin body içeriğinin hash değeri.
X-Amz-Algorithm: Signature’u oluşturmak için kullanılan algoritma.
X-Amz-Credential: Erişim anahtarı bilgisi.
X-Amz-Date: Linkin oluşturulma tarihi.
X-Amz-SignedHeaders: Signature’u hesaplamak için kullanılan headerlar.
X-Amz-Expires: Linkin geçerlilik süresi (tarih değil süre cinsinden).
X-Amz-Signature: Linkin anahtarı gibi  denebilir.

 

CloudFront Signed URL

Cloudfront’u kullanmak için CloudFront sayfasından “create a distribution” butonuna basıyoruz. Distribution ismini girildikten sonra “Distribution options”tan single website or app seçeneğini seçiyoruz.

Cloudfront oluşturma ayar 1

Cloudfront oluşturma ayar 2

Origin tipi olarak S3 seçip S3 origin olarak daha önce oluşturduğumuz S3 originini seçiyoruz.

Cloudfront origin tipi

Ardından CloudFront distribution sayfasında last modified kısmında “deploying” yazması gerekiyor. Bu işlem biraz sürebilir. İşlem tamamlandığında o kısımda tarih yazmalı. Böylece S3 bucketıyla CloudFront bağlantısı oluşmuş oluyor.

Cloudfront bağlantı sonuç

Cloudfront’un önceki versiyonunda bu aşamadan sonra aşağıdaki gibi bir bildirim çıkıyordu ve buradaki bucket politikasını kopyalayıp S3’ün bucket politiksasına yapıştırmamız gerekiyordu. Ama bu artık otomatik gerçekleştiği için bu aşamada bir şey yapmaya gerek yok. Yine de S3 bucketına gidip bucket politikası güncellenmiş mi kontrol etmenizde fayda var.

S3 policy uyarı

Şimdi distributionda kullanılacak anahtar çiftini oluşturmamız gerekiyor.

AWS konsolu üzerinden de anahtar çifti oluşturulabilse de bu güvenli bir yöntem olmadığından dolayı Cloudfront anahtar çifti için bilgisayarın komut satırına sırasıyla aşağıdaki komutları yazmamız gerekiyor.

opensssl gensra -out private_key.pem 2048

openssl rsa -pubout -in private_key.pem -out public_key.pem writing RSA key

Bu işlemden sonra public ve private olmak üzere anahtar çifti kullanıcılar kısmında oluşuyor.

Public private key

Private olan anahtar kullanmak için dosya dizinimize ekliyoruz. Burada iki anahtarların da başı ve sonundaki şu kısımları tutmak önemli:

-----BEGIN PRIVATE KEY-----

***************************

-----END PRIVATE KEY-----

Public olan anahtarı ise AWS konsolunda Cloudfront sayfasındaki “public keys” kısmına yüklüyoruz.

Public keys

Oluşturulan bu anahtarları kullanmak için Cloudfront sayfasından “key groups” sayfasına gidip “create key group”tan grup oluşturuyoruz. Bu aşamada grup adı, grubun opsiyonel açıklaması ve kullanılacak anahtar/anahtarları seçmemiz gerekiyor.

Key group oluşturma

Distributiondaki deploy işlemi tamamlanınca bu distribution’ın behaviors sayfasına gelip aşağıdaki gibi seçilip "edit" butonuna basılıyor.

Behaviors

Açılan sayfada diğer hiçbir ayarı değiştirmeden sadece “restrict viewer access” seçeneğini evet olarak işaretleyip kısıtlama yapıyoruz. Trusted key groups kısmından önceki aşamalarda oluşturulan key group'u seçip ve kaydediyoruz. Bu şekilde key group içeren signed url kullanılmadığı sürece dağıtıma erişim kapanmış oluyor.

Erişim kısıtlama

S3 için olduğu gibi CloudFront'ta da signed url oluşturmak için aşağıdaki kodu yazdım.

//Cloudfront signed url
use AwsCloudFrontUrlSigner;

//cloudfront public key idsi
$keyPairId = '***';
//private key
$privateKeyPath = __DIR__ . '***';

$urlSigner = new UrlSigner($keyPairId, $privateKeyPath);

//cloudfront domaini
$cloudFrontDomain = '***';
//dosya adı
$resourceKey = '***';
//son geçerlilik zamanı
$expire = time() + 604800;

$signedUrl = $urlSigner->getSignedUrl("$cloudFrontDomain$resourceKey", $expire);

echo "$signedUrl";

Buradaki keypairId değeri oluşturulan anahtar çiftinden CloudFront “public keys” sayfasına yüklenenin ID değeri.
privateKeyPath, proje dizinine dahil ettiğimiz private keyin dosya yolu.
Daha sonra CloudFront domaini ve buckettaki dosyanın adı ile expire yani geçerlilik tarihini yazıyoruz. Buradaki expire değerinin S3’tekinden farkı süre olarak değil de tarih olarak kullanılması.
Bütün bu girilen değerlerle signed url oluşup ekrana yazdırılıyor.

https://d2zgiskr6511r7.cloudfront.net/aws%20foto.png?Expires=1749537221&Signature=***********__&Key-Pair-Id=********

Oluşan örnek linkteki parametrelerin açıklamaları şu şekilde:
Expires: Linkin son geçerlilik tarihi.
Signature: Linkin anahtarı.
Key-Pair-Id: CloudFront anahtar çifti IDsi.

 

Anlattığımız bu 2 yöntem sayesinde, hassas verilerinizin yetkisiz erişime karşı korunması ve kullanıcıların yalnızca belirli bir süre boyunca içeriklere ulaşabilmesini sağlayabilirsiniz.

Eğer bulut tabanlı güvenli dosya paylaşımına ihtiyacınız varsa, bu rehberdeki adımları takip ederek kendi uygulamalarınızda AWS'in bu özelliklerini rahatlıkla kullanabilirsiniz.

 

Yazar: Berkay UZUN

15.07.2025 8

Yorumlar

Bu sayfalarda yer alan okur yorumları kişilerin kendi görüşleridir. Yazılanlardan Sanal Yazılım Ltd. veya sanal.mobi sorumlu tutulamaz. Yorumda ad-soyadınız anonimleştirilerek gösterilir, e-posta adresiniz ise yayınlanmaz.
Kullanıcı deneyimini geliştirmek, site kullanımını analiz etmek ve pazarlama çabalarımıza yardımcı olmak için çerezleri kullanıyoruz. Sitemize göz atmaya devam ederek veya bu bilgilendirmeyi kapatarak, Çerez Politikası`nı okuduğunuzu ve kabul ettiğinizi onaylamış olursunuz.