কম্পিউটার টিউটোরিয়াল

AWS EC2 ইনস্ট্যানসে অ্যাপ্লিকেশন সিক্রেট সিকিউরলি ম্যানেজ করুন

আপনি যখন আপনার অ্যাপ্লিকেশন EC2-এ ডিপ্লয় করেন, autoscaling groups ব্যবহার করা একটি ভালো আইডিয়া। Autoscaling groups আপনার অ্যাপ্লিকেশনকে ডিমান্ড মিট করতে বা ফেইল্ড ইনস্ট্যানস থেকে রিকভার করতে স্কেল আপ এবং ডাউন করতে দেয়, কোনো ম্যানুয়াল ইন্টারভেনশন ছাড়া। সেগুলো কাজ করতে দেয়া জন্য, নিশ্চিত করতে হবে প্রতিটি ইনস্ট্যান্স বুট শেষ হলে লাইভ ট্রাফিক সার্ভিস করার জন্য ফুলি রেডি। এটি শুধু অ্যাপকে একটি সার্ভারে ডিপ্লয় করার চেয়ে কিছুটা বেশি प्रयাস চায়, যদি আপনি নতুন সার্ভারে কিছু পরিবর্তন করেন বা ক্যাপিস্ট্রানোর মাধ্যমে ইনিশিয়াল ডিপ্লয় করার আগে সেটি রেডি না হয়।

উদাহরণস্বরূপ, আমাদের একটি ইউজার-ফেসিং ওয়েব অ্যাপ্লিকেশন আছে যা রেইলস দিয়ে বানানো। বুট শেষ হলে, প্রতিটি ইনস্ট্যান্সে ওই রেইলস অ্যাপ রেডি এবং ওয়েটিং থাকতে হবে লোড ব্যালেন্সার দ্বারা ফরোয়ার্ড করা রিকোয়েস্ট রেসপন্ড করার জন্য। এটা হাসিল করতে, আমি প্রথমে একটি কাস্টম AMI তৈরি করলাম Ansible দিয়ে প্রোভিশন করা একটি ইনস্ট্যান্সের স্ন্যাপশট নিয়ে অ্যাপ, nginx, ইত্যাদির সাথে। তারপর autoscaling group কনফিগার করলাম userdata দিয়ে যা একটি স্ক্রিপ্ট ইনভোক করে যা ক্যাপিস্ট্রানো ডিপ্লয়েশনের জন্য যা করে—সেটি গিট থেকে লেটেস্ট কোড পুল করে, bundler রান করে, ইত্যাদি। তো অ্যাপ এবং এর সব ডিপেন্ডেন্সি জায়গায় থাকার পর, কী বাকি?

অ্যাপ্লিকেশন সিক্রেট: ডিপ্লয়ারর অভিশাপ

অ্যাপ্লিকেশন সিক্রেট একটি চ্যালেঞ্জ উপস্থাপন করে: আপনি সেগুলো সেখানে থেকে দূরে রাখতে চান যেখানে সেগুলো এক্সপোজ হতে পারে (যেমন, আপনার গিট রেপোতে), কিন্তু আপনার অ্যাপ রান করার সময় সেগুলো উপলব্ধ থাকতে হবে। এবং autoscaling-এর কারণে, আপনি একজন মানুষের ওপর নির্ভর করতে পারবেন না যেটি আপনার অ্যাপকে সিক্রেট দিবে যখন সেটির দরকার।

এই সমস্যার একটি সমাধান হচ্ছে Hashicorp-এর Vault। এটি একটি চমৎকার সফটওয়ার যা স্পেসিফিক্যালি এই সমস্যাটি সমাধান করার জন্য লিখা হয়েছে—আপনার সিক্রেটগুলো গোপন রাখা যতক্ষণ না আপনার অ্যাপ সেগুলো দরকার করে। কিন্তু ডাউনসাইড হচ্ছে আপনাকে Vault প্রোভিশন এবং ম্যানেজ করতে হবে—এটি আরও একটি সার্ভিস যা আপনাকে চালিয়ে রাখতে হবে।

একটি অপশন হচ্ছে সিক্রেটগুলো শেয়ার্ড স্টোরেজে (S3, স্বাভাবিকভাবেই) সংরক্ষণ করা, এবং নিশ্চিত করা যে শুধু আপনার ইনস্ট্যান্সগুলোকে সেই বাকেট এবং/অথবা কী-এ অ্যাক্সেস আছে। এটি IAM রোল ব্যবহার করে করা যায়, যেগুলোর সাথে পলিসি অ্যাটাচ করা যায় যেগুলো রেস্ট্রিক্টেড S3 রিসোর্সে অ্যাক্সেস দেয়। তবে এটিও আপনাকে অনিচ্ছাকৃত এক্সপোজারেরリス্কে ফেলে, যদি আপনি সকল সিক্রেট প্লেইনটেক্সটে S3-এ সংরক্ষণ করেন। এটিকে অকস্মাতে অন্যদের কাছে উপলব্ধ করে দেওয়া সম্ভব যাদের সেই বাকেট বা পুরো ওয়ার্ল্ডে অ্যাক্সেস আছে।

কতটা ভালো হতো যদি আপনি আপনার সিক্রেটগুলো এনক্রিপ্ট করে S3-এ সংরক্ষণ করতে পারতেন, এবং আপনার অ্যাপে দরকার হলে সেগুলো লোড এবং ডিক্রিপ্ট করতে পারতেন?

সিক্রেট ইнг্রিডিয়েন্ট: আমাজনস কী ম্যানেজমেন্ট সার্ভিস

Amazon Key Management Service (KMS) এনক্রিপশন কী-এর সাথে ইন্টারঅ্যাক্ট করার জন্য একটি API প্রদান করে। IAM রোল এবং Aws::S3::Encryption মডিউলের সাথে কম্বাইন করলে, আপনার সিক্রেটগুলো আপনার অ্যাপ্লিকেশনে লোড করতে শুধু কয়েক লাইন কোড লাগে—S3-এ সেগুলো এনক্রিপ্টেড রেখে।

শুরু করার আগে, আমাকে Don Mills-কে ধন্যবাদ জানাতে হবে, যিনি KMS প্লাস S3 ব্যবহার করে সিক্রেট স্টোর করার ওপর একটি চমৎকার পোস্ট লিখেছেন। আমি তার পদ্ধতিকে কিছুটা পরিবর্তন করলাম IAM রোলের ওপর নির্ভর করে এবং KMS কী ID আলাদাভাবে ট্র্যাক করে—S3-এ সিক্রেটের সাথে কী ইনফো স্টোর করার বদলে।

KMS একটি মাস্টার এনক্রিপশন কী জেনারেট এবং অ্যাক্সেস প্রদান করে যা আপনি ডেটা এনক্রিপ্ট এবং ডিক্রিপ্ট করার জন্য ব্যবহার করতে পারেন। আপনি যখন এটিকে কিছু এনক্রিপ্ট করতে বলেন, KMS আপনাকে মাস্টার কী ভিত্তিক একটি টেম্পোরারি কী দেয়, এবং সেই টেম্পোরারি কী এনক্রিপশন বা ডিক্রিপশনের জন্য ব্যবহার করা যায়।

একটি কী জেনারেট করতে, আপনি IAM কনসোলে যান এবং Encryption Keys লিংক বেছে নিন। আপনি যখন একটি কী তৈরি করেন, আপনাকে IAM ইউজার বা রোল স্পেসিফাই করতে বলা হবে যেগুলো এই কী ব্যবহার করতে পারবে। সেই রোলটি সিলেক্ট করুন যা autoscaling group-এ অংশ হবে EC2 ইনস্ট্যান্সগুলোর জন্য অ্যাসাইন করা হবে। কী-র ARN নোট করুন—আপনি পরে সেটি ব্যবহার করবেন।

রুক্স বানানো: সমান অংশ KMS এবং IAM

কী তৈরি হলে, IAM কনসোল ব্যবহার করে সেই IAM রোলটি এডিট করুন যা আপনি সিলেক্ট করেছেন। সিক্রেট সংরক্ষণ করা বাকেটে অ্যাক্সেস দিতে নিচের মতো একটি পলিসি অ্যাটাচ করুন:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "Stmt1476277816000",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:PutObjectAcl",
        "s3:HeadObject"
      ],
      "Resource": [
        "arn:aws:s3:::yourbucket/secrets.yml"
      ]
    }
  ]
}

কী কনফিগার হলে এবং রোলের সাথে পলিসি অ্যাটাচ হলে, আপনি এখন KMS এবং S3-এর সাথে ইন্টারঅ্যাক্ট করতে পারেন একটি Aws::S3::Encryption::Client ইনস্ট্যান্স দিয়ে। নিচে কিছু স্যাম্পল কোড যা সিক্রেটস ফাইল রিট্রিভ করে এবং এর কন্টেন্ট এনভায়রনমেন্ট ভেরিয়েবলে লোড করে:

begin
  es3 = Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID'])
  YAML.load(es3.get_object(bucket: "yourbucket", key: "secrets.yml").body.read).each do |k, v|
    ENV[k] ||= v # লোকাল ENV সেটিংস ওভাররাইড করবেন না
  end
rescue ArgumentError
  # KMS_KEY_ID ENV-এ না পাওয়া গেলে raise হয়, তখন কিছু করতে হবে না
rescue Aws::S3::Errors::NoSuchKey
  # কোনো সিক্রেটস ফাইল না পাওয়া গেলে, কিছু করতে হবে না
end

প্রথমে আমরা KMS কী আইডি দিয়ে একটি নতুন অবজেক্ট ইনস্ট্যানশিয়েট করি। কী-র ARN (IAM কনসোলে কী তৈরি করার সময় দেখানো হয়) KMS_KEY_ID এনভায়রনমেন্ট ভেরিয়েবলে স্টোর করা থাকে। আপনি যখন কনস্ট্রাক্টরে কী আইডি পাস করেন, এটি আপনার জন্য টেম্পোরারি ডিক্রিপশন কী ফেচ হ্যান্ডেল করে। আপনি এখানে একটি Aws::S3::Client ইনস্ট্যান্স সপেসিফাই করতে পারেন অপশন হিসেবে, যদি আপনি S3-এ আলাদা ক্রেডেনশিয়ালস ব্যবহার করে কথা বলতে চান KMS-র চেয়ে। যদি আপনি আগের মতো IAM রোল সেটআপ করেন, তবে এটার দরকার নেই, কারণ Aws::S3::Encryption::Client আপনার জন্য একটি নতুন Aws::S3::Client ইনস্ট্যান্স তৈরি করবে IAM রোল দ্বারা প্রদত্ত ক্রেডেনশিয়ালস দিয়ে।

এনক্রিপ্টেড S3 ক্লায়েন্ট রেডি হলে, #get_object ব্যবহার করে S3 থেকে ডেটা ফেচ করুন এবং KMS দ্বারা প্রদত্ত কী দিয়ে ডিক্রিপ্ট করুন। একবার ডেটা পেলে, আপনি যা খুশি করুন। আমাদের ডেটা YAML, তাই আমরা সেটি লোড করি এবং কী/ভ্যালু পেয়ারগুলো ENV-এ স্টাফ করি অ্যাপ্লিকেশন কোডের জন্য ব্যবহার করার জন্য।

এই কোডটি আপনার রেইলস অ্যাপ্লিকেশনের একটি ইনিশিয়ালাইজার ফাইলে ড্রপ করুন, এবং আপনি গো টু ゴ। ঠিক, একবার আপনার সিক্রেট S3-এ স্টোর হয়ে যাক, সেটা। :) আপনার যদি সঠিক IAM রোল দিয়ে চলে এমন একটি ইনস্ট্যান্সে IRB কনসোল থাকে, আপনি এরকম কিছু করে আপনার সিক্রেট স্টোর করতে পারেন:

# /path/to/secrets.yml থেকে ডেটা এনক্রিপ্ট করুন এবং S3-এ স্টোর করুন
Aws::S3::Encryption::Client.new(kms_key_id: ENV['KMS_KEY_ID']).put_object(
  bucket: "yourbucket",
  key: "secrets.yml",
  body: File.read("/path/to/secrets.yml")
)

তৎক্ষণাৎ সার্ভ

এখন আপনার সিক্রেট সবসময় উপলব্ধ আপনার autoscaling group-এ যোগ হওয়া যেকোনো নতুন ইনস্ট্যান্সের জন্য, সিক্রেটগুলো এনক্রিপ্টেড রেখে। সবাই জিতল! :)

  1. উইন্ডোজ ১১-এ নোটিফিকেশন ম্যানেজমেন্ট গাইড

  2. KDE-এ অ্যাপ্লিকেশন উইন্ডো ভালোভাবে ম্যানেজ করার উপায়

  3. Amazon EC2 ইনস্ট্যান্সের সিকিউরিটি গ্রুপ কীভাবে ম্যানেজ করবেন

  4. রেইলসে OmniAuth-Twitter দিয়ে টুইটার লগইন ইন্টিগ্রেট করুন: ধাপে ধাপে গাইড