AWS Türkçe Blog

Mevcut nesnelerde Amazon S3 Bucket Keys kullanarak şifreleme maliyetlerini azaltın

Orijinal makale: Link (Mathieu Seguin ve Aditya Badhwar)

Daha fazla kuruluş daha hızlı ve geniş ölçekte çalışmak isterken, kritik uyumluluk gereksinimlerini karşılamanın ve veri güvenliğini iyileştirmenin yollarına ihtiyaç duyuyor. Şifreleme, derinlemesine savunma stratejisinin kritik bir bileşenidir ve doğru kullanıldığında, temel erişim kontrolünün üzerinde ek bir koruma katmanı sağlayabilir. Ancak, milyonlarca veya milyarlarca şifrelenmiş nesneye erişen iş yükleri, yüksek şifreleme/şifre çözme maliyetine yol açabilecek büyük istek hacimleri oluşturabilir. Bunu göz önünde bulundurarak, birçok kuruluş, maliyeti optimize ederken büyük ölçekte veri güvenliğini sağlamanın yollarını arıyor.

Simon Data, büyüme için oluşturulmuş bir çözüm amacı ile pazarlama sonuçlarının daha hızlı elde edilmesini sağlayan bir müşteri veri platformudur. Simon Data, Amazon S3’deki milyarlarca nesnenin şifresinin çözülmesi için AWS KMS’e yapılan API istekleri nedeniyle yüksek AWS Key Management Service (AWS KMS) maliyetlerine maruz kalıyordu. Aralık 2020’de AWS, müşterilerin S3’den KMS’e giden istek trafiğini azaltarak AWS Key Management Service (SSE-KMS) ile sunucu tarafı şifreleme maliyetlerini düşürmelerine yardımcı olmak için Amazon S3 Bucket Keys özelliğini kullanıma sundu. S3 Bucket Keys, KMS şifreli nesneler için ayrı KMS anahtarları yerine KMS tarafından oluşturulan klasör düzeyinde anahtarların kullanılması yoluyla istek trafiğini azaltır; her bir klasör düzeyinde anahtar, bir klasöre eklenen her yeni nesne için benzersiz bir veri anahtarı oluşturur ve böylece şifreleme işlemlerini tamamlamak için ek KMS isteklerine ihtiyaç duyar. Milyarlarca S3 nesnesinin geçiş maliyetini ve işlem süresini en aza indirmek için Simon Data, son üç ay içinde AWS KMS API çağrılarını tetikleyen nesnelerde S3 Bucket Keys’i etkinleştirmeyi seçti.

Bir klasördeki tüm mevcut nesneleriniz aynı KMS anahtarını kullanıyorsa, onlar için S3 Bucket Keys etkinleştirmek nispeten basittir. Ancak, nesneleriniz farklı KMS anahtarları kullanılarak şifrelenmişse, özelliği etkinleştirmek için birkaç ekstra adım gerekir. Simon Data, aynı Amazon S3 klasörlerindeki nesneler için birden fazla müşteri tarafından yönetilen anahtar kullandığından, Amazon S3 Bucket Keys’i etkinleştirmek onlar için kolay olmadı. Ayrıca, özellik etkinleştirilmeden önce oluşturulan nesnelere erişim, AWS KMS’e yönelik istekleri tetiklemeye devam edecektir.

Bu blog yazısında, Simon Data’nın farklı KMS anahtarları kullanılarak şifrelenmiş mevcut nesnelere S3 Bucket Keys uygulayarak AWS KMS aylık harcamalarını yüzde 80’in üzerinde nasıl azalttığını ele alıyoruz. Bu çözüm sayesinde Amazon S3 ve AWS KMS arasındaki talep trafiğini büyük ölçüde azaltabilir ve şifrelenmiş verilerinizi daha az maliyet endişesiyle kullanırken verilerinizin güvenliğini sağlamanıza olanak tanır.

Karışık SSE-KMS anahtar klasörlerinde S3 Bucket Keys etkinleştirme

Aynı klasör içinde farklı SSE-KMS anahtarlarıyla şifrelenmiş varolan nesneler için S3 Bucket Keys’i nasıl etkinleştirebilirsiniz?

Geçiş maliyetlerini kontrol altında tutarken bunu maksimum sonuçla elde etmek için özelliği yalnızca aşağıdaki nesnelerde etkinleştirmek istersiniz:

  • SSE-KMS şifreli
  • S3 Bucket Keys özelliği devre dışı olan
  • sık sık erişilen ve SSE-KMS’ye düzenli olarak istek üreten

S3 Bucket Keys kullanan nesneleri tanımlamak için aşağıdaki yöntemlerden birini kullanabilirsiniz:

  1. Amazon S3 Inventory‘yi kullanarak klasör nesnelerini (ve S3 Bucket Key durumlarını) listeleyin.
  2. AWS CloudTrail günlüklerinden AWS KMS şifresini çözme isteği oluşturan S3 nesnelerinin listesini çıkarmak için Amazon Athena‘yı kullanın.

Simon Data’nın S3 nesne ölçeği göz önüne alındığında, sık erişilen nesneler için yalnızca klasör anahtarlarını etkinleştirmek (yeniden şifrelemek) istedikleri için ikinci seçeneği tercih ettiler ve nesneye son erişim hakkında bilgi AWS CloudTrail’de mevcut. Simon Data, aşağıdaki şekilde çalışan AWS CloudTrail’i tercih etti:

  1. SSE-KMS isteğini Amazon Athena‘yı kullanarak CloudTrail günlüklerini sorgulayarak ve ardından CSV dosyası olarak dışa aktararak son zamanlarda tetikleyen nesneleri belirleriz.
  2. CSV dosyasını S3 Batch Operations için besleriz. Ayrıca, şifrelenmiş nesnelerin farklı KMS anahtarlarına sahip olduğundan yerleşik kopyalama işlemini kullanmak yerine bir AWS Lambda işlevini tetiklemeliyiz.
  3. Listedeki her nesne için Lambda şunları yapacaktır:
    • Geçerli SSE-KMS anahtar ID’si de dahil olmak üzere geçerli nesne özelliklerini döndürür.
    • S3 Bucket Keys’in etkinleştirilip etkinleştirilemeyeceğini ve etkinleştirilmeleri gerekip gerekmediğini tekrar kontrol eder.
    • Nesneyi yerinde kopyalayarak S3 Bucket Keys’i etkinleştirir.

Uygulama

Başlangıç olarak, gerekli altyapıyı nasıl kuracağınıza bir göz atalım.

Aşağıdakilere ihtiyacınız olacak:

  • İki S3 Klasörü (Bucket)
    • İşlenecek dosyaların listesi olan bir klasör
    • S3 Batch Operations çıktı dosyaları için bir klasör
  • IAM rolüyle birlikte bir AWS Lambda işlevi
    • S3 nesnelerimizde tek tek S3 Bucket Keys etkinleştirir
  • S3 Batch Operations için bir IAM rolü
    • AWS Lambda işlevini bir dosya listesinde çalıştırır

Bu parçalar aşağıdaki mimari diyagramında tasvir edilmiştir:

Bu CloudFormation şablonu ile birlikte aşağıdaki adımlar gerekli tüm kaynakları ayarlar.

1. Depoyu yerel diske kopyalayın

$ git clone git@github.com:simon-data/enable-bucket-key-example.git && cd enable-bucket-key-example

2. CloudFormation kullanarak yığın oluşturun

$ aws cloudformation create-stack \
      --stack-name enable-bucket-key-example \
      --template-body file://enable-bucket-key-example-template.cloudformation.yaml \
      --capabilities CAPABILITY_NAMED_IAM \
      --no-cli-pager \
      --output json

Önek değerini şu şekilde yapılandırarak klasör adlarını da özelleştirebilirsiniz:

--parameters ParameterKey=Prefix,ParameterValue=enable-bucket-key-example2

3. (Bucket) aşamasını ayarlama

Ardından, klasör durumunuzu yeniden oluşturun.

S3 Bucket Keys klasör düzeyinde etkinleştirmeden önce bir test dosyası oluşturun ve yükleyin.

$ echo "Before bucket-level Bucket Key enabled" > before.txt

$ aws s3api put-object \
    --bucket enable-bucket-key-example \
    --key before.txt \
    --body before.txt \
    --no-cli-pager

{
"ETag": "\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"",
"ServerSideEncryption": "aws:SSE-KMS",
"SSESSE-KMSKeyId": "arn:aws:SSE-KMS:us-east-1:XXXXXXXXXXXX:key/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
}

Ardından, farkı görmek için varsayılan olarak S3 Bucket Key’i etkinleştirin.

Klasörün sayfasına gidin ve ardından Properties sekmesinde Default encryption bölümüne gidin ve Edit‘i seçin.

S3 Bucket Key kısmında Enable seçin ve Save changes seçin.

Bu yapıldıktan sonra, önceki adımda etkinleştirilen klasör anahtarı özelliğini doğrulamak için ikinci bir dosya yükleyin.

$ echo "After bucket-level S3 Bucket Key enabled" > after.txt

$ aws s3api put-object \
    --bucket enable-bucket-key-example \
    --key after.txt \
    --body after.txt \
    --no-cli-pager

{
"ETag": "\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\"",
"ServerSideEncryption": "aws:SSE-KMS",
"SSESSE-KMSKeyId": "arn:aws:SSE-KMS:us-east-1:XXXXXXXXXXXX:key/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
"BucketKeyEnabled": true
}

Gördüğünüz gibi, bunun BucketKeyEnabled özelliği “true” değerine ayarlanmış.

Diğer dosyamızı tekrar kontrol edersek, S3 Bucket Key’in hala etkinleştirilmediğini fark ederiz (BucketKeyEnabled özniteliği eksik):

$ aws s3api head-object --bucket enable-bucket-key-example --key before.txt --no-cli-pager

{
    "AcceptRanges": "bytes",
    "LastModified": "2022-03-29T20:01:18+00:00",
    "ContentLength": 39,
    "ETag": "\"fdfadb27141cf16b2982d0c826ed9a2f\"",
    "ContentType": "binary/octet-stream",
    "ServerSideEncryption": "aws:kms",
    "Metadata": {},
    "SSEKMSKeyId": "arn:aws:kms:us-east-1:XXXXXXXXXXXX:key/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX"
}

4. AWS Lambda işlevini hazırlama

Şimdiye kadar, iki dosyalı bir klasörümüz var. Birinde S3 Bucket Key etkin, diğerinde ise yok. “before.txt” dosyamız için S3 Bucket Key’i etkinleştirelim!

a. Bağımlılıkları yükleyin

AWS Lambda, aşağıdaki komutu kullanarak yerel bir “paket” dizinine yükleyebileceğimiz boto3 kullanır:

$ python -m pip install --target ./package boto3 botocore

Ayrıca, gerektiğinde otomatik olarak çok parçalı yüklemeler kullanan s3transfer‘e de ihtiyacımız var. Ne yazık ki, bu yazma sırasında s3transfer, BucketKey argümanını desteklemiyor. Bu arada, kendi fork’umuzu kullanabiliriz:

$ rm -Rf package/s3transfer && python -m pip install --target ./package git+https://github.com/simon-data/s3transfer.git@develop
b. AWS Lambda işlevini güncelleyin

Ardından bir .zip dosyası oluşturun ve AWS Lambda işlevinizi güncelleyin:

$ bash package_lambda.sh
$ aws lambda update-function-code \
    --function-name enable-bucket-key-example-function \
    --zip-file fileb://enable-bucket-key-example-function.zip \
    --no-cli-pager \
    --output json

5. S3 Batch Operations kullanarak S3 Bucket Key etkinleştirme

Lambda fonksiyonumuz güncellendiğinde, artık dosyaları işlemeye başlamaya hazırız!

a. S3 Batch Operations bildirimi oluşturma

Tek ihtiyacımız olan, S3 Bucket Key’i etkinleştirmek istediğimiz dosyaların listesiyle birlikte S3 Batch Operations’a beslemek için bir bildirim dosyası.

S3 Batch Operations, aşağıdaki iki sütuna sahip virgülle ayrılmış değerler (CSV) bildirim dosyası bekler:

bucket_name, object_key

before.txt dosyanız için bildirim oluşturun:

$ echo "enable-bucket-key-example,before.txt" > objects_to_enable_bucket_key_for.csv

$ aws s3api put-object \
    --bucket enable-bucket-key-example-batch-ops \
    --key objects_to_enable_bucket_key_for.csv \
    --body objects_to_enable_bucket_key_for.csv \
    --no-cli-pager \
    --output json
b. S3 Batch Operations işini çalıştırın

Son olarak, Batch Operations işinize başlayın!

$ export AWS_ACCOUNT_ID=XXXXXXXXXXXX  # Replace with your account id
$ aws s3control create-job \
    --account-id ${AWS_ACCOUNT_ID} \
    --no-confirmation-required \
    --priority 10 \
    --role-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:role/enable-bucket-key-example-batch-ops-role" \
    --operation '{
  "LambdaInvoke": {
    "FunctionArn": "arn:aws:lambda:us-east-1:'${AWS_ACCOUNT_ID}':function:enable-bucket-key-example-function:$LATEST"
  }
}' \
    --manifest '{
  "Spec": {
    "Format": "S3BatchOperations_CSV_20180820",
    "Fields": [
      "Bucket",
      "Key"
    ]
  },
  "Location": {
    "ObjectArn": "arn:aws:s3:::enable-bucket-key-example-batch-ops/objects_to_enable_bucket_key_for.csv",
    "ETag": '"$(aws s3api head-object --bucket enable-bucket-key-example-batch-ops --key objects_to_enable_bucket_key_for.csv | jq '.ETag' | sed -n 's/\\\"//gp')"'
  }
}' \
    --report '{"Enabled": false}' \
    --no-cli-pager \
    --output json

İş tamamlandıktan sonra, before.txt dosyamızın başarıyla işlendiğini ve BucketKeyEnabled özelliğinin true olarak ayarlandığını doğrulayabiliriz:

$ aws s3api head-object --bucket enable-bucket-key-example --key before.txt --no-cli-pager

{
    "AcceptRanges": "bytes",
    "LastModified": "2022-03-29T20:03:36+00:00",
    "ContentLength": 39,
    "ETag": "\"fdfadb27141cf16b2982d0c826ed9a2f\"",
    "ContentType": "binary/octet-stream",
    "ServerSideEncryption": "aws:kms",
    "Metadata": {},
    "SSEKMSKeyId": "arn:aws:kms:us-east-1:XXXXXXXXXXXX:key/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXX",
    "BucketKeyEnabled": true
}

Ölçekte uygulama

Aşağıdakiler, günlüklerinizi sorgulamak için bir Athena tablosunun yanı sıra yapılandırılmış varolan bir iziniz olduğunu varsayar.

Örnekte oluşturulan mimari zaten ölçeklenebilir. Bu değişikliği yüz milyonlarca dosyaya uygulamak için dahili olarak kullandığımız aynıdır.

Daha önce de belirtildiği gibi, benzersiz S3 istekleri ve Lambda maliyetleri önemsiz olsa da, büyük ölçekte hızla toplanabilirler. Bu nedenle, geçiş çalışmalarımızı son birkaç ayda SSE-KMS şifre çözme isteklerini tetikleyen dosyalara odaklamak istiyoruz.

Aşağıdaki Athena sorgusunu kullanarak SSE-KMS şifre çözme isteklerini tetikleyen nesnelerin bir listesini alabiliriz (sorgu önceki günün bağlamını alır – kullanım durumunuza uyan herhangi bir pencereye bakmak için sorguyu değiştirebilirsiniz).

SELECT
   REGEXP_EXTRACT(obj_arn, ':::([^\/]+)', 1) as bucket,
   REGEXP_EXTRACT(obj_arn, '[^\/]+\/(.*)', 1) as path
FROM (
   SELECT
       DISTINCT CAST(json_extract(requestparameters, '$.encryptionContext.aws:s3:arn') as VARCHAR(255)) as obj_arn
   FROM cloudtrail_logs_part as logs
   CROSS JOIN UNNEST(logs.resources) unnested (resources_entry)
   WHERE eventsource='SSE-KMS.amazonaws.com'
     AND year = CAST(EXTRACT(year FROM current_date - interval '1' day) as VARCHAR(4))
     AND month = CAST(EXTRACT(month FROM current_date - interval '1' day) as VARCHAR(2))
     AND day = CAST(EXTRACT(day FROM current_date - interval '1' day) as VARCHAR(2))
)
WHERE obj_arn LIKE '%/%'

Ardından, bir CSV dosyası almak için Download Results‘ı seçebilir, dosyayı S3 Batch Operations’a besleyebilir ve oradan işlemesini sağlayabilirsiniz!

S3 Bucket Keys’de dikkat edilmesi gereken noktalar

S3 Bucket Keys’i etkinleştirmeden önce göz önünde bulundurmanız gereken birkaç şey vardır:

Geçiş maliyetleri

  • S3 Batch operations, SSE-KMS ve Lambda işlenen nesne sayısına göre maliyetlere neden olur.
  • S3 Versioning: S3 Versioning etkinleştirilmişse, eski sürümleri kaldırmazsanız, işlenen nesneler için barındırma maliyetlerinizi etkili bir şekilde iki katına çıkararak S3 Bucket Key’i etkinleştirdiğiniz her nesne için yeni bir sürüm oluşturursunuz.

S3 Inventory yapılandırmaları

S3 Inventory listeleri, bir klasörden nesnelerin listesini çıkarmanın harika bir yoludur. Klasördeki veya belirli bir önek içindeki tüm mevcut nesneleri işlemek istiyorsanız tercih edilen yaklaşım budur.

Yalnızca amacınız son zamanlarda AWS KMS şifresini çözme isteği yapan nesneleri işlemekse CloudTrail çözümünü tercih edin. Bu seçeneğin CloudTrail’in önceden kurulmasını gerektirdiğini unutmayın.

Emniyetli devreye alma planı ve geri alma mekanizması

Geçişlerinizin başarılı olmasını sağlamak için başarısız olacağını varsayın.

En basit geri alma uygulaması, klasörünüzde sürüm oluşturmayı (versioning) etkinleştirmek ve önceki sürümü geri yüklemeniz gerektiğinde en son sürümü silmeye hazır bir komut dosyasına sahip olmaktır.

Temizlik

Bu blog gönderisinde açıklanan adımların, ücretli olabilecek kaynakları AWS hesabınıza dağıtacağını unutmayın. Klasörleri (bucket) boşaltarak ve CloudFormation yığınını silerek oluşturulan altyapıyı kolayca devre dışı bırakabilirsiniz.

Sonuç

Bu blogda, aynı klasör içinde farklı AWS KMS anahtarlarına sahip nesneler için Amazon S3 Bucket Keys’i uygulamak üzere Simon Data’nın izlediği adımları inceledik. Bunu yaparak Simon Data, Amazon S3’den AWS KMS’e giden istek trafiğini önemli ölçüde azaltarak AWS KMS maliyetlerini yüzde 80 oranında azalttı.

Gösterilen çözümle, mevcut nesneler orijinal olarak farklı KMS anahtarlarıyla yönetilse bile, istekler ve şifreleme işlemleriyle ilişkili ücretleri azaltarak AWS KMS maliyetini azaltmak için Amazon S3 Bucket Keys’i etkili bir şekilde uygulayabilirsiniz. S3 Bucket Keys’i kullanarak, verilerinize daha uygun maliyetli erişime izin verirken, verilerinizden en iyi şekilde yararlanmanız için size daha fazla esneklik ve teşvik sağlarken, aynı zamanda güvenliği korurken nesnelerinizi şifrelemeye devam edebilirsiniz.

Bu blog gönderisini okuduğunuz için teşekkürler!