Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

.NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu

Merhaba,

Depolama, bilgi işlem ve veritabanları gibi AWS servislerine erişim maksatlı authentication yapabilmek için kullandığımız ve AWS’nin güvenlik modelinin temel bir parçası olan AWS Credentials, korumalı hizmetlere erişim için geliştiricilerin .NET uygulamalarını/ortamlarını gerekli kimlik bilgileriyle yapılandırma ihtiyaçlarına karşın çalışma süreçlerinde bizlere eşlik etmekte ve türlü yöntemler sağlamaktadır. Bu içeriğimizde .NET uygulamaları için AWS Credentials konfigürasyonu ve yönetimi açısından olabildiğince best practices yöntemleri ele alıyor olacak ve çalışma süreçlerindeki uygulama ayarlarını, environment variable’ları, AWS CLI profiles değerlerini ve IAM role’lerini kullanarak AWS Credential bilgilerini güvence altına almanın çeşitli yollarını inceliyor olacağız. Ve tüm bunların yanında AWS kimlik bilgileri oluşturmaya, oluşturulan bu kimliklere/kullanıcılara karşın politikalar yani izinler vermeye değineceğiz. O halde gelin buyurun başlayalım…

IAM İle Kullanıcı ve Kimlik Bilgileri Oluşturma

.NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuAWS Identity and Access Management(IAM), AWS kaynaklarına erişimi yönetmek ve denetlemek için kullanılan, kimlik doğrulama ve yetkilendirme yönetimini sağlayan bir servistir..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuBu serviste, yukarıdaki görselde olduğu gibi ‘Users’ sekmesi üzerinden mevcut kullanıcılara erişebilir ya da yeni kullanıcı oluşturma gibi işlemleri gerçekleştirebilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuMisal olarak, yukarıdaki ekran kaydına bakarsanız eğer ‘gncy.yldz’ isimli bir kullanıcı, o anda ‘S3’ politikalarıyla ilişkilendirilerek oluşturulmuş olan ‘test-group’ isimli bir gruba direkt eklenerek oluşturulmaktadır.

Bu işlemden sonra tekrar ‘Users’ sekmesine gelirseniz, oluşturulan kullanıcının listelendiğini görebilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonuİlgili kullanıcıya tıkladığınızda, kullanıcıyla ilgili yetkilerin ve grup bilgilerinin olduğu detaylara erişeceksiniz. Gelecek olan ekran üzerinden ‘Security credentials’ sekmesine geldiğinizde kullanıcının erişimleriyle ilgili birkaç seçenekle karşılaşacaksınız. Bu seçeneklerden özellikle ‘Access keys’ bölümü, ilgili kullanıcıya AWS CLI’dan, powershell tool’larından, AWS SDK’den ve AWS API request’lerinden erişim süreçleri için oldukça önem arz eden access key sağlamaktadır..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuYukarıdaki ekran kaydında görüldüğü üzere bir access key üretip, elde etmekteyiz. Tabi bu süreçte ister bir açıklama satırı da ekleyebilirsiniz ve üretilen access key’i de .csv dosyası olarak elde edebilirsiniz.

Şimdi elimizde bulunan bu access key eşliğinde, AWS S3 politikalarına erişim yetkilerine sahip olduğumuzu biliyoruz. Haliyle şöyle aşağıdaki gibi basit bir uygulama üzerinden S3 servisindeki mevcut bucket’ları listeleyen bir çalışmayla access key’in kullanımını örneklendirebiliriz.

Gerekli olan kütüphaneler;

.NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu‘Program.cs’;

using Amazon.S3;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDefaultAWSOptions(builder.Configuration.GetAWSOptions());
builder.Services.AddAWSService<IAmazonS3>();

var app = builder.Build();

app.MapGet("/", async () =>
{
    var s3Client = new AmazonS3Client("***Access Key***", "***Secret Key***");
    var data = await s3Client.ListBucketsAsync();
    var buckets = data.Buckets.Select(b => b.BucketName);
    return buckets;
});

app.Run();

.NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuGörüldüğü üzere access key sayesinde gereken response’u alabilmekteyiz.

Dikkat ! Burada basit bir örneklendirme yapıldığı için kod içerisinde access key ve secret key değerlerinin usulsüzce kullanımına göz yumulduğunu, bu durumun örnek teşkil etmemesi gerektiğini önemle vurgularım. Vurgularım çünkü kod içerisinde tanımlanmış olan bu tarz kritik bilgiler developer tarafından farkında olmaksızın remote repository’lere gönderilip, oralara erişebilen iyi/kötü niyetli kişilerin inisiyatifine sunulabilir. Ayrıca bu tarz kod içinde sonradan değiştirilebilecek değerlerin tutulması, kodun aşırı bağımlı olmasına ve ihtiyaç dahilinde tekrardan derlenmesi gerektiğine sebebiyet verecektirler. Haliyle bu tarz bilgileri kod içerisinde barındırmaktansa, Asp.NET Core mimarisinde direkt akla gelen appsettings.json dosyasında tutarak yönetebilirsiniz lakin bu çözüm de ilk duruma karşı kesin bir önlem almamakta ve hala proje içerisinde kritik bilgilerin tutulmasına ve remote noktalara gönderilme riskini taşımaya devam etmektedir. Ha bu durumda da remote repository’e appsettings.json dosyasını göndermemeye özen gösterirsiniz. Belki bu bir çözümdür ama ne kadar çözümdür 🙂

Hocam… madem öyle, o halde Secret Manager’ı kullanalım! dediğinizi duyar gibiyim… Evet, bu yöntem, credentials bilgilerini appsettings.json dosyasında saklamaktan daha güvenlidir. Ne de olsa burada tutulacak bilgilere sade ve sadece developer’ın local’inden erişilebilmektedir ve daha da önemlisi remote noktalara gönderilmemektedir. Çözüm müdür? Aslanlar gibi çözümdür.

Tüm bu yöntemlerin dışında environment variable’ları da kullanabilirsiniz. Ne de olsa yukarıdaki yöntemler yalnızca local development süreçlerinde ihtiyacımızı gidermektedir. Uygulamayı deploy ettikten sonra bu tarz kritik arz eden verileri, kullanıldığı sunucuda environment variable olarak tanımlamak hem daha güvenli hem de daha yönetilebilir olacaktır.

Ama en kral çözümü sorarsanız eğer AWS tarafından sunulmuş olan AWS CLI profile’ları eşliğinde kullanılan AWS Local Storage‘dır diyebilirim. Hatırlarsanız eğer AWS S3 İle Dosya İşlemleri Gerçekleştirme başlıklı makalemizde tecrübe ettiğimiz gibi, AWS IAM’den aldığımız access key ve secret key değerlerini geliştirme sürecinde AWS CLI aracılığıyla geliştiricinin local makinesinde gayet güvenli bir şekilde depolayabilmekte ve kod içerisinde herhangi bir kritik değer tutmaksızın operasyonlarımızı yürütebilmekteyiz. Tabi bunun için referans ettiğimiz içeriğimizde olduğu gibi önce AWS CLI’ı bilgisayarınıza yüklemeli, ardından da aşağıdaki talimat neticesinde AWS Local Storage’da access key ve secret key’i depolayan bir profil oluşturulmalıdır..NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonuİşte bu kadar.
.NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu
Bu talimat neticesinde ilgili bilgilerin C:\Users\{name}\.aws dizininde, yan görseldeki dosyalar içerisinde aşağıdaki gibi tutulduğunu görebilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuEe haliyle bu vaziyette kodu inşa etmek istiyorsanız yapmanız gereken aşağıdaki gibi ‘IAmazonS3’ interface’ini inject etmek ve gelecek olan instance üzerinden operasyonları yürütmektir.

.
.
.
app.MapGet("/", async (IAmazonS3 s3Client) =>
{
    var data = await s3Client.ListBucketsAsync();
    var buckets = data.Buckets.Select(b => b.BucketName);
    return buckets;
});.
.
.

AWS SDK, developer local’inde çalışacak olan bu kodun ihtiyaç duyacağı access key ve secret key değerlerini AWS profile’larından alacağını bilecektir. Burada tarafımızca tek yapılması gereken şey hangi profile bilgisi olduğunu appsettings.json üzerinden aşağıdaki gibi bildirmektir.

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "AWS": {
    "Profile": "my-profile",
    "Region": "us-east-1"
  }
}

İşte bu kadar… Böylece AWS Local Storage sayesinde, aynı kullanıcı yetkilerine ihtiyaç olan farklı projelerde sürekli access key ve secret key değerleriyle uğraşmaya gerek kalmaksızın rahatlıkla çalışmalarınızı gerçekleştirebilirsiniz.

Görüldüğü üzere AWS dünyası dışındaki bir uygulamaya erişim izni bu kadar basit bir şekilde gerçekleştirilmektedir ve bu izin neticesinde elde edilen konfigürasyonel değerleri, yazılımla ilişkilendirme sürecinde sergileyebileceğimiz davranışlarda incelediklerimizden ibarettir.

Şimdi de AWS altyapısında barındırılacak uygulamalar açısından olayı değerlendirmeye geçelim ve örneğin bir AWS Lambda’nın, S3 servisindeki mevcut bucket’ları listeleyebilmesi için nasıl bir yol haritası izlenmesi gerektiğini gözlemleyelim.

IAM Rolleri

Şimdi bunun için AWS Lambda İle Serverless Computing, Lambda Authorizer İle Amazon API Gateway’in Güvenliğini Sağlama ve AWS Lambda İle Serverless REST API Geliştirme (Asp.NET Core API) başlıklı makalelerimizde tecrübe ettiğimiz gibi bir AWS Lambda projesi oluşturalım ve S3 servisleriyle çalışmasını kurguladıktan sonra AWS’ye deploy edelim..NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu

using Amazon.Lambda.Core;
using Amazon.S3;

// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace AWS_Credentials_Configurations_Example_Lambda;

public class Function
{

    /// <summary>
    /// A simple function that takes a string and does a ToUpper
    /// </summary>
    /// <param name="input"></param>
    /// <param name="context"></param>
    /// <returns></returns>
    public async Task<IEnumerable<string>> FunctionHandler(ILambdaContext context)
    {
        var s3Client = new AmazonS3Client();
        var data = await s3Client.ListBucketsAsync();
        var buckets = data.Buckets.Select(b => b.BucketName);
        return buckets.ToList();
    }
}

Yukarıda referans edilen içeriklerden de hatırlayacağınız üzere AWS Lambda projelerinde, profile ve region parametreleri ‘aws-lambda-tools-defaults.json’ dosyasında tutulmaktadır. Tabi bu dosyadaki değerler, AWS Local Storage‘da yapılandırdığımız değerler tarafından ezileceğinden dolayı tekrardan o noktalara girme gereği görmüyorum. Velhasıl, oluşturduğumuz projeyi Lambda Mock aracıyla çalıştırıp aşağıdaki gibi test edebiliriz.

.NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu

.NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu

.NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuUygulamanın local’de çalıştığını gördüğümüze göre artık AWS’ye aktarabiliriz. Bunun için yandaki gibi ‘Publish to AWS Lambda…’ sekmesi üzerinden süreci başlatabiliriz.

Tam aşağıdaki gibi yapılandırmayı gerçekleştirirken hiç beklenmedik bir şekilde IAM rolleri ve listesine dair; Failed to retrieve list of iam roles and policies. hatasıyla da karşılabilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuBu hatayı aşabilmek için AWS’de IAM servisi üzerinden ilgili kullanıcıya aşağıdaki gibi AdministratorAccess politikasının verilmesi yeterli olacaktır..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuBu hatayı da aştıktan sonra AWS Lambda’yı gönderirken karşımıza çıkan ‘Role Name’ kısmında, S3 servislerine temel GET/PUT request izinlerini ve Cloudwatch loglama davranışını barındıran ‘AWSLambdaExecute’ rolünün seçilmesi yeterli olacaktır. .NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuBu vaziyette projenizi AWS Lambda’ya upload edebilir ve bunu da Lambda platformundan gözlemleyebilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuAWS’ye yüklediğimiz bu function’ı arayüz üzerinden test ederseniz eğer aşağıdaki gibi ‘Access Denied’ hatasıyla karşılaşacaksınız..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuEvet, görüldüğü üzere AWS Lambda servisinde bulunan function üzerinden S3 servisine erişimin reddedildiğini gözlemliyoruz. Biz biraz önce ‘AWSLambdaExecute’ rolünü vermiş olsak da bu rol, S3 servislerine erişebilmek için gerekli izinlere sahip değildir. İşte bunun için bu izinlere sahip olan rolü ilgili function’a tanımlamamız gerekmektedir. Bunun için de yine AWS arayüzünden function detayında, ‘Configuration’ sekmesi üzerinden ‘Permissions’ menüsüne gelerek tanımlanmış olan role erişebilir ve bu rol üzerinde S3 servislerine gerekli erişim izinlerini verebilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials Konfigürasyonu.NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuGerekli izinleri verdikten sonra tekrardan test ederseniz eğer function tarafından S3 servislerine rahatlıkla erişim gerçekleştirilebildiğini ve başarıyla sonucun elde edildiğini gözlemleyebilirsiniz..NET Uygulamaları İçin Detaylı AWS Credentials KonfigürasyonuBuradan da anlıyoruz ki, AWS altyapısında barındırılan uygulamalar tarafından AWS servislerine erişilebilmesi için gerekli rol ve politika tanımlarının gerçekleştirilmesi gerekirken, AWS altyapısının dışında bulunan uygulamalar tarafından da yetkilendirilmiş access key ve secret key değerlerine ihtiyaç söz konusudur.

Böylece .NET uygulamalarında AWS Credentials konfigürasyonları hakkında ayrıntılı bir incelemede bulunmuş olduk ve ayrıca access ve secret key’ler ile birlikte politikalarla rollerin ne manaya geldiğini, hangi durumlara istinaden davranışsal farkların söz konusu olduğunu değerlendirmiş olduk.

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Not : Örnek çalışmaya aşağıdaki github adresinden erişebilirsiniz.
https://github.com/gncyyldz/AWS_Credentials_Configurations_Example

Bunlar da hoşunuza gidebilir...

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir