مقدمة
في هذا البرنامج التعليمي، ستتعلم كيفية تكوين حل أمان AWS باستخدام Terraform. ستستخدم خدمات Amazon GuardDuty وAmazon SNS وAWS Lambda وAmazon EvenBridge.
قد يكون اكتشاف التهديدات والاستجابة للحوادث (TDIR) عملية يدوية تستغرق وقتًا طويلاً في العديد من المؤسسات. وهذا يؤدي إلى عمليات استجابة غير متسقة، ونتائج أمنية غير متسقة، وزيادة المخاطر. في هذا البرنامج التعليمي، ستتعلم كيفية أتمتة نتائج اكتشاف التهديدات وأتمتة عملية الاستجابة للحوادث، مما يقلل من وقت الاستجابة للتهديدات. ونظرًا لأن العديد من المؤسسات تفضل استخدام أدوات البنية التحتية كرمز (IaC) القياسية لضمان تناسق التكوينات بين الموردين، يوضح هذا البرنامج التعليمي كيفية تكوين هذا الحل باستخدام Terraform.
المتطلبات الأساسية
- حساب AWS
نبذة عن Amazon GuardDuty
قبل التعمق في هذا البرنامج التعليمي، من المفيد فهم الوظائف الأساسية لبعض الأدوات التي سنستخدمها. توفر Amazon GuardDuty خاصية الكشف عن التهديدات، مما يتيح لك مراقبة وحماية حسابات AWS وأحمال العمل والبيانات المخزنة في Amazon Simple Storage Service (S3) بشكل مستمر. يحلل GuardDuty تدفقات البيانات الوصفية المستمرة الناتجة عن نشاط حسابك وشبكتك، والموجودة في أحداث AWS CloudTrail، وسجلات تدفق Amazon Virtual Private Cloud (VPC)، وسجلات نظام اسم النطاق (DNS). كما يستخدم GuardDuty ذكاءً متكاملاً للتهديدات، مثل عناوين IP الضارة المعروفة، واكتشاف الشذوذ، والتعلم الآلي (ML)، لتحديد التهديدات بدقة أكبر.
تعمل GuardDuty بشكل مستقل تمامًا عن مواردك، لذا لا يوجد أي خطر على أداء أو توافر أحمال عملك. تُدار الخدمة بالكامل من خلال ذكاء التهديدات المتكامل، واكتشاف الشذوذ، والتعلم الآلي. تقدم Amazon GuardDuty تنبيهات دقيقة وقابلة للتنفيذ، تتكامل بسهولة مع أنظمة إدارة الأحداث وسير العمل الحالية. لا توجد تكاليف مسبقة، وتدفع فقط مقابل تحليل الأحداث، دون الحاجة إلى برامج إضافية للنشر أو اشتراكات في موجز معلومات التهديدات.
حول Terraform وCloud9
Terraform هي أداة بنية تحتية ككود (IaC) من تطوير Hashicorp، تتيح لك إدارة البنية التحتية باستخدام ملفات التكوين بدلاً من واجهة المستخدم. باستخدام Terraform، يمكنك بناء بنيتك التحتية وتعديلها وتدميرها باستخدام ملفات تكوين تعريفية سهلة القراءة. نعم، يمكنك أيضًا بناء بنية AWS التحتية وتعديلها وتدميرها باستخدام Terraform، وذلك باستخدام مكون Terraform الإضافي المسمى Provider. يتيح Provider لـ Terraform التفاعل مع واجهة برمجة تطبيقات AWS (API).
يستخدم هذا البرنامج التعليمي AWS Cloud9 لتكوين Terraform. AWS Cloud9 هي بيئة تطوير سحابية متكاملة (IDE)، تُمكّنك من كتابة وتشغيل وتصحيح أخطائك البرمجية باستخدام متصفح الإنترنت فقط. تتضمن محرر أكواد، ومصحح أخطاء، وطرفية. تأتي Cloud9 مُجهزة مسبقًا بأدوات أساسية للغات البرمجة الشائعة، بما في ذلك JavaScript وPython وPHP وTerraform، لذا لن تحتاج إلى تثبيت أي ملفات أو تهيئة جهاز التطوير الخاص بك لبدء هذه الورشة. تعمل Cloud9 على نسخة EC2 مُنشأة خصيصًا لك عند بدء هذه الورشة.
ماذا ستفعل
- يتفاعل مضيف "جهة الاتصال" مع مضيف "معرض للخطر"، مما يتسبب في قيام GuardDuty بالإبلاغ عن نتيجة.
- سيتم مطابقة هذه النتيجة في قاعدة EventBridge التي ستنشئها باستخدام Terraform. تقوم قاعدة EventBridge بوظيفتين:
- يُنشئ قاعدة SNS التي ستُنشئها باستخدام Terraform. تُرسل هذه القاعدة بريدًا إلكترونيًا إلى مسؤول مُحدد، مع نص واضح يُوضح النتائج.
- يُفعّل هذا دالة لامدا التي ستُنشئها باستخدام Terraform. تُمرّر دالة لامدا المضيف المُعرّض للخطر إلى مجموعة أمان جنائية، حيث يُعزل لمزيد من التحقيق.
الخطوة 1. تنزيل الإعدادات الأولية
يستخدم هذا البرنامج التعليمي قالب AWS CloudFormation لتوفير الموارد الأولية. يهدف هذا إلى التركيز فقط على التكوين الأساسي لحل الأمان الخاص بك. يُنشئ قالب CloudFormation حزمة. تتكون الحزمة من مثيل AWS Cloud9 IDE. نستخدم هذا المثيل من Cloud9 ليحظى كل من يُشغّل هذا البرنامج التعليمي بنفس تجربة التحرير والنشر. بالإضافة إلى ذلك، عند نشر الحزمة في US-WEST-2، فإنك تضمن وجود مثيل t3.small. إذا تم نشر القالب في مناطق أخرى، فقد تحتاج إلى تعديله لاستخدام نوع مثيل مختلف إذا لم يكن t3.small متاحًا.
1.1. انتقل إلى AWS CloudFormation في وحدة التحكم الإدارية في AWS وقم بإنشاء مجموعة من خلال النقر فوق الزر "إنشاء مجموعة".

١.٢. اختر "تحميل ملف قالب" ثم حمّل ملف gd-iac-initial.yml من مستودع الكود النموذجي المذكور أعلاه. ثم انقر على "التالي".

1.3. أدخل اسم المكدس ثم انقر فوق التالي.

1.4. في صفحة تكوين خيارات المكدس، انقر فوق التالي.

1.5. في صفحة المراجعة، قم بالتمرير لأسفل وانقر فوق مربع الاختيار لتأكيد أن AWS CloudFormation قد يقوم بإنشاء موارد IAM، ثم انقر فوق التالي.

1.6. تأكد من أن المكدس في حالة تم إنشاؤها بالكامل.
في هذه المرحلة، تكون قد نشرت الموارد الأولية التي ستستخدمها لمتابعة هذا البرنامج التعليمي بنفسك. في الخطوة التالية، ستتمكن من الوصول إلى نسخة Cloud9 التي أنشأت المكدس، وبدء تشغيل Terraform.
الخطوة 2. الوصول إلى Cloud9 وتشغيل Terraform
2.1 افتح AWS Cloud9 في وحدة التحكم الإدارية AWS وافتح البيئة في Cloud9 IDE.

2.2. في تفضيلات Cloud9، قم بتعطيل استخدام بيانات الاعتماد المؤقتة المُدارة بواسطة AWS.

2.3. من المحطة الطرفية على نسخة Cloud9، قم بمحاكاة مستودع الكود المصدر.
git clone https://github.com/build-on-aws/automating-amazon-guardduty-with-iac.git
2.4. انتقل إلى دليل automating-amazon-guardduty-with-iac وقم بتشغيل Terraform init وterraform plan وterraform apply.
سيبدو الطلب الناجح كما يلي:

2.5. تأكد من وجود حالتين جديدتين من EC2، واحدة باسم IAC Tutorial: Compromised Instance والأخرى باسم IAC Tutorial: Malicious Instance.
في هذه المرحلة، تكون قد نشرتَ شبكة افتراضية خاصة (VPC) ومثيلين من EC2. يتواصل مثيلا EC2 مع بعضهما البعض، وعند إضافة عنوان IP من أحد مثيلي EC2 Elastic إلى قائمة التهديدات، يُفعّل GuardDuty عملية إنشاء نتيجة. من هذه النقطة، ستُنشئ جميع الموارد التي تُشكّل جزءًا من حل الأمان الفعلي.
الخطوة 3: إنشاء دلو S3 لتخزين قائمة التهديدات
يمكن لـ GuardDuty الإشارة إلى نوعين من القوائم: قائمة عناوين IP الموثوقة وقائمة عناوين IP المهددة. لا يُنشئ GuardDuty نتائج لعناوين IP المدرجة في قوائم عناوين IP الموثوقة، ولكنه يُنشئ نتائج لعناوين IP المدرجة في قوائم عناوين IP المهددة. ولأننا نريد فرض نتيجة في هذا البرنامج التعليمي، سنستخدم قائمة عناوين IP المهددة.
3.1. ابدأ بإنشاء متغير في modules/s3/variables.tf لـ vpc_id.
variable "vpc_id" {
}
3.2. بعد ذلك، في الملف modules/s3/main.tf، احصل على رقم حساب AWS الحالي وقم بإنشاء مورد دلو S3.
# GET CURRENT AWS ACCOUNT NUMBER
data "aws_caller_identity" "current" {}
# CREATE TWO S3 BUCKETS
resource "aws_s3_bucket" "bucket" {
bucket = "guardduty-example-${data.aws_caller_identity.current.account_id}-us-east-1"
force_destroy = true
}
resource "aws_s3_bucket" "flow-log-bucket" {
bucket = "vpc-flow-logs-${data.aws_caller_identity.current.account_id}-us-east-1"
force_destroy = true
}
٣.٣. ثم فعّل سجلات VPC Flow في حزمة S3. هذا ليس ضروريًا، ولكنه يسمح لنا برؤية السجلات التي يراها GuardDuty.
# VPC FLOW LOGS
resource "aws_flow_log" "flow_log_example" {
log_destination = aws_s3_bucket.flow-log-bucket.arn
log_destination_type = "s3"
traffic_type = "ALL"
vpc_id = var.vpc_id
}
3.4. أخيرًا، قم بإخراج قيم bucket_id وbucket_arn في الملف modules/s3/outputs.tf.
# S3 Bucket id
output "bucket_id" {
value = aws_s3_bucket.bucket.id
description = "Output of s3 bucket id."
}
# S3 Bucket arn
output "bucket_arn" {
value = aws_s3_bucket.bucket.arn
description = "Output of s3 bucket arn."
}
3.5. الآن ارجع إلى الملف root/main.tf وأضف دلو S3.
# CREATES S3 BUCKET
module "s3_bucket" {
source = "./modules/s3"
vpc_id = module.iac_vpc.vpc_attributes.id
}
في هذه المرحلة، تكون قد أنشأتَ حصتين من S3. إذا كنت ترغب في التحقق منهما بنفسك، فإن الحصة الأولى مخصصة لسجلات تدفق VPC. أما الحصة الثانية فتحوي قائمة التهديدات التي ستنشئها في الخطوة التالية.
الخطوة 4: إنشاء وحدات GuardDuty Terraform
٤.١. تم إنشاء ملفات وحدة GuardDuty لك، ولكنها فارغة مثل ملفات S3. ابدأ بملف modules/guardduty/variables.tf. هنا، ستحتاج إلى إنشاء متغيرين. الأول هو متغير يُسمى "bucket" والذي سنستخدمه لتحديد تفاصيل قائمة تهديدات دلو S3. والثاني هو عنوان IP الخبيث الذي أضفناه إلى الدلو.
variable "bucket" {
}
variable "malicious_ip" {
}
4.2. ثم انتقل إلى الملف modules/guardduty/main.tf.
في هذا الملف، ستضيف ثلاثة مصادر. المصدر الأول هو كاشف GuardDuty. ستلاحظ في وثائق الموفر أن جميع الخيارات اختيارية - لا يلزم أي شيء آخر سوى إعلان المصدر. مع ذلك، سنضبط قيمة التفعيل على "صحيح" في مثالنا، وسنغير أيضًا تردد النشر إلى 15 دقيقة. القيمة الافتراضية هي ساعة واحدة.
# ENABLE THE DETECTOR
resource "aws_guardduty_detector" "gd-tutorial" {
enable = true
finding_publishing_frequency = "FIFTEEN_MINUTES"
}
٤.٣. بعد ذلك، نرفع ملفًا إلى دلو S3 الذي أنشأناه في الخطوة السابقة. هذا ليس ضروريًا، ولكن لأغراض التوضيح، نريد استخدام عنوان IP لإحدى نسخ EC2 لضمان توليد النتائج في هذا البرنامج التعليمي. في الكود أدناه، نرفع ملفًا نصيًا إلى دلو S3، والذي سنسميه MyThreatIntelSet، وسيكون محتوى الملف هو عنوان IP الموجود في المتغير var.malicious_ip.
# ADD THE EIP/MALICIOUS IP TO THE BUCKET AS A TEXT FILE.
resource "aws_s3_object" "MyThreatIntelSet" {
content = var.malicious_ip
bucket = var.bucket
key = "MyThreatIntelSet"
}
4.4. أخيرًا، سنقوم بإنشاء مورد يسمى aws_guardduty_threatintelset والذي يخبر GuardDuty باستخدام الملف الموجود في الموقع المحدد (هذا ما يفعله activate = true).
# HAVE GUARDDUTY LOOK AT THE TEXT FILE IN S3
resource "aws_guardduty_threatintelset" "Example-Threat-List" {
activate = true
detector_id = aws_guardduty_detector.gd-tutorial.id
format = "TXT"
location = "https://s3.amazonaws.com/${aws_s3_object.MyThreatIntelSet.bucket}/${aws_s3_object.MyThreatIntelSet.key}"
name = "MyThreatIntelSet"
}
٤.٥. ثم انتقل إلى ملف root/main.tf واستدعِ وحدة GuardDuty. نحتاج إلى توفير معرف الحاوية وعنوان IP الخبيث. يمكنك أن ترى أن هذه البيانات تأتي من وحدة S3 ووحدة الحوسبة.
# Enable GuardDuty
module "guardduty" {
source = "./modules/guardduty"
bucket = module.s3_bucket.bucket_id
malicious_ip = module.compute.malicious_ip
}
في هذا القسم، فعّلتَ GuardDuty، وأنشأتَ قائمة التهديدات، وأضفتَ عنوان IP المرن لنسخة EC2 الخبيثة إلى تلك القائمة. بعد ذلك، أنشئنا قاعدة SNS.
الخطوة 5: إنشاء وحدة Terraform الخاصة بـ SNS
في هذا القسم، سنستخدم Terraform لإنشاء قاعدة SNS. SNS هي خدمة إشعارات بسيطة تتيح لك إرسال إشعارات عند استيفاء معايير معينة. SNS بحد ذاته لا يتوافق مع إجراء إرسال رسالة. سنستخدم EventBridge لذلك. ولكن، بما أن EventBridge يتطلب قاعدة لإرسال الإشعارات، فعلينا إنشاء قاعدة SNS أولاً.
٥.١. أولًا، في ملف modules/sns/variables.tf، عليك إنشاء متغيرين:
- sns_name لتسمية موضوع SNS الذي سنقوم بإنشائه.
- البريد الإلكتروني لحمل عنوان البريد الإلكتروني الذي نستخدمه للاشتراك في إشعاراتنا.
فيما يلي مثال لمتغيراتنا الخاصة بـSNS.
variable "sns_name" {
description = "Name of the SNS Topic to be created"
default = "GuardDuty-Example"
}
variable "email" {
description = "Email address for SNS"
}
5.2. ثم نقوم بإنشاء موضوع SNS والاشتراك في الملف modules/sns/main.tf.
ابدأ بإنشاء مورد موضوعي.
# Create the SNS topic
resource "aws_sns_topic" "gd_sns_topic" {
name = var.sns_name
}
في الكود أعلاه، تقوم بإنشاء مورد يُسمى gd_sns_topic بواسطة Terraform. في وحدة تحكم AWS، يُسمى "GuardDuty-Example". هذا لأننا نستدعي المتغير var.sns_name، وإعداده الافتراضي هو "GuardDuty-Example".
٥.٣. بعد ذلك، أنشئ مورد سياسة SNS. قيمتا arn وPolicy مطلوبتان. السياسة المُنشأة هنا هي وثيقة سياسة AWS IAM. تسمح هذه الوثيقة لمدير الخدمة events.amazonaws.com بالنشر على الموضوع المعني.
resource "aws_sns_topic_policy" "gd_sns_topic_policy" {
arn = aws_sns_topic.gd_sns_topic.arn
policy = jsonencode(
{
Id = "ID-GD-Topic-Policy"
Statement = [
{
Action = "sns:Publish"
Effect = "Allow"
Principal = {
Service = "events.amazonaws.com"
}
Resource = aws_sns_topic.gd_sns_topic.arn
Sid = "SID-GD-Example"
},
]
Version = "2012-10-17"
}
)
}
٥.٤. بعد ذلك، أنشئ اشتراك الموضوع. يستدعي اشتراك الموضوع رقم ARN، ويحدد البروتوكول المُستخدم - في هذه الحالة البريد الإلكتروني - وعنوان البريد الإلكتروني الذي سيتم إرسال الإشعار إليه. عنوان البريد الإلكتروني مُبرمج مسبقًا في هذه الحالة، ولكن يمكنك تهيئته ليطلب عنوان البريد الإلكتروني عند تطبيق Terraform. أيضًا، يؤدي ضبط endpoint_auto_confirm إلى "خطأ" إلى تلقي مالك البريد الإلكتروني رسالة بريد إلكتروني تحتوي على رابط يجب عليه النقر عليه للاشتراك في الإشعارات.
# Create the topic subscription
resource "aws_sns_topic_subscription" "user_updates_sqs_target" {
topic_arn = aws_sns_topic.gd_sns_topic.arn
protocol = "email"
endpoint = var.email
endpoint_auto_confirms = false
}
5.5. بعد ذلك، في ملف modules/sns/outputs.tf، نريد إخراج ARN للموضوع حتى نتمكن من الرجوع إليه في تكوين EventBridge الذي سنفعله لاحقًا.
output "sns_topic_arn" {
value = aws_sns_topic.gd_sns_topic.arn
description = "Output of ARN to call in the eventbridge rule."
}
٥.٦. أخيرًا، ارجع إلى ملف root/main.tf وأضف موضوع SNS. هنا يمكنك تحديد عنوان البريد الإلكتروني للاشتراك.
# Creates an SNS Topic
module "guardduty_sns_topic" {
source = "./modules/sns"
email = "[email protected]"
}
في هذا القسم، قمت بإنشاء موضوعات SNS حتى يتم إرسال بريد إلكتروني إليك في حالة إنشاء نتيجة معينة.
الخطوة 6: إنشاء وحدة Terraform الخاصة بـ EventBridge
في هذا القسم، ستستخدم Terraform لإنشاء قاعدة EventBridge. تربط قاعدة EventBridge عنصري هذا الحل معًا.
كيف يعمل EventBridge؟ بشكل أساسي، يستقبل EventBridge حدثًا - وهو مؤشر على تغيير في البيئة - ويطبق قاعدة لتوجيه الحدث إلى هدف. تُطابق القواعد الأحداث مع الأهداف بناءً على هيكل الحدث، أو ما يُسمى بنمط الحدث، أو بناءً على جدول زمني. في هذه الحالة، يُنشئ GuardDuty حدثًا إلى Amazon EventBridge عند حدوث تغيير في النتائج. تتم مطابقة الحدث، ويُوجه Amazon EventBridge القاعدة إلى هدف. في هذه الحالة، يكون هدف القاعدة هو خدمة SNS. تأخذ قاعدة SNS البيانات التي تم العثور عليها وتُرسل إشعارًا عبر البريد الإلكتروني إلى المشترك.
٦.١. تتطلب قاعدة EventBridge معلومات حول GuardDuty وSNS. ابدأ بإنشاء متغير يُستخدم لـ ARN موضوع SNS. قم بذلك في ملف modules/eventbridge/variables.tf.
variable "sns_topic_arn" {
}
٦.٢. بعد ذلك، أنشئ مصدر قاعدة الحدث في ملف modules/eventbridge/main.tf. عليك تحديد مصدر ونوع الحدث الذي نريده.
# EVENT RULE RESOURCE
resource "aws_cloudwatch_event_rule" "GuardDuty-Event-EC2-MaliciousIPCaller" {
name = "GuardDuty-Event-EC2-MaliciousIPCaller"
description = "GuardDuty Event: UnauthorizedAccess:EC2/MaliciousIPCaller.Custom"
event_pattern = <<EOF
{
"source": ["aws.guardduty"],
"detail": {
"type": ["UnauthorizedAccess:EC2/MaliciousIPCaller.Custom"]
}
}
EOF
}
٦.٣. بعد ذلك، حدد مصدر هدف الحدث. عند إنشاء هذا المصدر، يمكنك تحسين قابلية قراءة إشعار البريد الإلكتروني من خلال تحديد مُحوّل إدخال. يُخصص هذا ما يُرسله EventBridge إلى هدف الحدث. فيما يلي، نحصل على مُعرّف GuardDuty والمنطقة ومعرف مثيل EC2، ونُنشئ قالب إدخال يشرح بعض المعلومات حول الرسالة. كما هو موضح أدناه، أنشأنا قالب إدخال يستخدم المعلومات المُفصّلة من مُعرّف GuardDuty في رسالة البريد الإلكتروني المُرسلة.
# EVENT TARGET RESOURCE FOR SNS NOTIFICATIONS
resource "aws_cloudwatch_event_target" "sns" {
rule = aws_cloudwatch_event_rule.GuardDuty-Event-EC2-MaliciousIPCaller.name
target_id = "GuardDuty-Example"
arn = var.sns_topic_arn
input_transformer {
input_paths = {
gdid = "$.detail.id",
region = "$.detail.region",
instanceid = "$.detail.resource.instanceDetails.instanceId"
}
input_template = "\"First GuardDuty Finding for the GuardDuty-IAC tutorial. | ID:<gdid> | The EC2 instance: <instanceid>, may be compromised and should be investigated. Go to https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?macros=current&fId=<gdid>\""
}
}٦.٤. في قاعدة الحدث الأولى التي أنشأناها، نبحث عن الحدث GuardDuty-Event-EC2-MaliciousIPCaller. أنشئ قاعدة حدث ثانية للبحث عن الحدث GuardDuty-Event-IAMUser-MaliciousIPCaller، وأرسل إشعارًا بذلك عبر البريد الإلكتروني.
# EVENT RULE RESOURCE
resource "aws_cloudwatch_event_rule" "GuardDuty-Event-IAMUser-MaliciousIPCaller" {
name = "GuardDuty-Event-IAMUser-MaliciousIPCaller"
description = "GuardDuty Event: UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom"
event_pattern = <<EOF
{
"source": ["aws.guardduty"],
"detail": {
"type": ["UnauthorizedAccess:IAMUser/MaliciousIPCaller.Custom", "Discovery:S3/MaliciousIPCaller.Custom"]
}
}
EOF
}
#EVENT TARGET RESOURCE FOR SNS NOTIFICATIONS
resource "aws_cloudwatch_event_target" "iam-sns" {
rule = aws_cloudwatch_event_rule.GuardDuty-Event-IAMUser-MaliciousIPCaller.name
target_id = "GuardDuty-Example"
arn = var.sns_topic_arn
input_transformer {
input_paths = {
gdid = "$.detail.id",
region = "$.detail.region",
userName = "$.detail.resource.accessKeyDetails.userName"
}
input_template = "\"Second GuardDuty Finding for the GuardDuty-IAC tutorial. | ID:<gdid> | AWS Region:<region>. An AWS API operation was invoked (userName: <userName>) from an IP address that is included on your threat list and should be investigated.Go to https://console.aws.amazon.com/guardduty/home?region=<region>#/findings?macros=current&fId=<gdid>\""
}
}6.5. بعد إنشاء الموارد في الوحدة النمطية، ارجع إلى ملف root/main.tf وأضف قاعدة EventBridge.
# Create the EventBridge rule
module "guardduty_eventbridge_rule" {
source = "./modules/eventbridge"
sns_topic_arn = module.guardduty_sns_topic.sns_topic_arn
}في هذا القسم، أنشأتَ قاعدة EventBridge تستخدم موضوع SNS الذي أنشأته لإرسال بريد إلكتروني عند تطابق نتائج GuardDuty. في القسم التالي، ستوسّع هذه الوظيفة باستخدام Lambda.
الخطوة 7: إنشاء وحدة Lambda Terraform
في هذا القسم، سنستخدم Terraform لإنشاء دالة Lambda تُجري عملية إصلاح لبيئتنا. هدفنا من هذا البرنامج التعليمي هو نقل مُضيفنا المُخترق إلى مجموعة أمان جديدة. وكما هو الحال مع استخدام EventBridge لشبكات التواصل الاجتماعي لإنشاء رسائل البريد الإلكتروني، سيُغلّف EventBridge دالة Lambda.
تجدر الإشارة إلى وجود العديد من الطرق الممكنة هنا. لمزيد من المعلومات، يُرجى الاطلاع على وثائق "إنشاء استجابات مخصصة لنتائج GuardDuty باستخدام أحداث Amazon CloudWatch" و"الحظر التلقائي لحركة المرور المشبوهة باستخدام جدار حماية شبكة AWS وAmazon GuardDuty".
قبل أن نبدأ، دعونا نرى ما يجب أن يحدث لتحقيق ذلك.
حاليًا، تتم مطابقة نتائج GuardDuty لدينا مع قاعدة EventBridge ذات هدف - حاليًا قاعدة SNS تُرسل بريدًا إلكترونيًا. لتحسين هذه الإمكانية، يستخدم EventBridge AWS Lambda كهدف.
بما أننا نخطط للوصول إلى موارد أخرى نيابةً عن AWS Lambda نفسها، نحتاج إلى إنشاء دور IAM لمنح الأذونات للخدمة. يُسمى هذا الدور خدمة، وسيتولى AWS Lambda هذا الدور عند تغيير مجموعة الأمان لمثيل EC2 الخاص بنا.
تُظهر الصورة أدناه كيفية تجميع كتل التعليمات البرمجية الثلاثة الأولى معًا للسماح لخدمة AWS Lambda بتولي دور يمكنه إجراء تغييرات على مجموعات الأمان المعينة لمثيلات EC2.

٧.١. ابدأ بإنشاء مستند سياسة IAM في modules/lambda/main.tf. هذه هي علاقة الثقة الخاصة بالسياسة.
data "aws_iam_policy_document" "GD-EC2MaliciousIPCaller-policy-document" {
statement {
effect = "Allow"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["lambda.amazonaws.com"]
}
}
}
7.2. بعد ذلك، قم بإنشاء سياسة مضمنة تنطبق على الدور الذي سيلعبه AWS Lambda.
resource "aws_iam_role_policy" "GD-EC2MaliciousIPCaller-inline-role-policy" {
name = "GD-EC2MaliciousIPCaller-inline-role-policy"
role = aws_iam_role.GD-Lambda-EC2MaliciousIPCaller-role.id
policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : [
"ssm:PutParameter",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateSecurityGroup",
"ec2:DescribeSecurityGroups",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:UpdateSecurityGroupRuleDescriptionsEgress",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:DescribeInstances",
"ec2:UpdateSecurityGroupRuleDescriptionsIngress",
"ec2:DescribeVpcs",
"ec2:ModifyInstanceAttribute",
"lambda:InvokeFunction",
"cloudwatch:PutMetricData",
"xray:PutTraceSegments",
"xray:PutTelemetryRecords"
],
"Resource" : "*",
"Effect" : "Allow"
},
{
"Action" : [
"logs:*"
],
"Resource" : "arn:aws:logs:*:*:*",
"Effect" : "Allow"
},
{
"Action" : [
"sns:Publish"
],
"Resource" : var.sns_topic_arn,
"Effect" : "Allow"
}
]
})
}
7.3. والآن قم بإنشاء دور IAM الذي سيتولى AWS Lambda القيام به.
resource "aws_iam_role" "GD-Lambda-EC2MaliciousIPCaller-role" {
name = "GD-Lambda-EC2MaliciousIPCaller-role1"
assume_role_policy = data.aws_iam_policy_document.GD-EC2MaliciousIPCaller-policy-document.json
}
7.4. إنشاء مصدر بيانات يشير إلى الكود.
data "archive_file" "python_lambda_package" {
type = "zip"
source_file = "${path.module}/code/index.py"
output_path = "index.zip"
}
7.5. بعد ذلك، نحتاج إلى منح EventBridge حق الوصول إلى Lambda.
resource "aws_lambda_permission" "GuardDuty-Hands-On-RemediationLambda" {
statement_id = "GuardDutyTerraformRemediationLambdaEC2InvokePermissions"
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.GuardDuty-Example-Remediation-EC2MaliciousIPCaller.function_name
principal = "events.amazonaws.com"
}
تسمح الكتلة أعلاه لـ EventBridge باستدعاء وظيفة Lambda.
٧.٦. أخيرًا، نُنشئ مصدر دالة لامدا. للقيام بذلك، نحتاج إلى إنشاء بعض المتغيرات التي تسمح لنا بتمرير المعلومات. عدّل ملف modules/lambda/variables.tf بالمتغيرات التالية:
variable "sns_topic_arn" {
}
variable "compromised_instance_id" {
}
variable "forensic_sg_id" {
}٧.٧. ثم ارجع إلى ملف modules/lambda/main.tf وأنشئ مصدر دالة لامدا. لاحظ أننا نستخدم إصدار بايثون ٣.٩ في كتلة التعليمات البرمجية التالية. نشير أيضًا إلى شيفرة بايثون التي ضغطناها في ملف index.zip. وأخيرًا، قمنا بتعيين بعض متغيرات البيئة في المصدر: INSTANCE_ID وFORENSICS_SG وTOPIC_ARN. سيتم تمرير هذه المتغيرات من المتغيرات التي أنشأناها إلى بيئة دالة لامدا.
# Create the Lambda function Resource
resource "aws_lambda_function" "GuardDuty-Example-Remediation-EC2MaliciousIPCaller" {
function_name = "GuardDuty-Example-Remediation-EC2MaliciousIPCaller"
filename = "index.zip"
source_code_hash = data.archive_file.python_lambda_package.output_base64sha256
role = aws_iam_role.GD-Lambda-EC2MaliciousIPCaller-role.arn
runtime = "python3.9"
handler = "index.handler"
timeout = 10
environment {
variables = {
INSTANCE_ID = var.compromised_instance_id
FORENSICS_SG = var.forensic_sg_id
TOPIC_ARN = var.sns_topic_arn
}
}
}7.8. في ملف root/main.tf، استدعِ وحدة Lambda، وحدِّد رقم ARN لموضوع SNS، ومعرّف المثيل المُعرَّض للخطر، ومجموعة Forensic Security. يُرجى العلم أن هذه القيم مستمدة من وحدات GuardDuty، وCompute، وVPC.
# CREATE THE LAMBDA FUNCTION
module "lambda" {
source = "./modules/lambda"
sns_topic_arn = module.guardduty_sns_topic.sns_topic_arn
compromised_instance_id = module.compute.compromised_instance_id
forensic_sg_id = module.forensic-security-group.security_group_id
}
٧.٩. لم يتم إنشاء مجموعة الأمان القانونية بعد. أضف مجموعة أمان لاستخدامها.
# CREATES THE FORENSICS_SG SECURITY GROUP
module "forensic-security-group" {
source = "terraform-aws-modules/security-group/aws"
version = "4.17.1"
name = "FORENSIC_SG"
description = "Forensic Security group "
vpc_id = module.iac_vpc.vpc_attributes.id
}٧.١٠. للوصول إلى مجموعة الأمان القانونية، نحتاج إلى إخراجها. في ملف root/outputs.tf، نُخرج مُعرّف مجموعة الأمان.
output "forensic_sg_id" {
value = module.forensic-security-group.security_group_id
description = "Output of forensic sg id created - to place the EC2 instance(s)."
}7.11. الآن، نحتاج إلى تهيئة قاعدة EventBridge لإرسال البيانات التي تم العثور عليها إلى Lambda. سنفعل ذلك في القسم التالي. ارجع إلى ملف modules/eventbridge/main.tf. أضف مصدر هدف حدث لدالة Lambda، والذي يفحص القاعدة aws_cloudwatch_event_rule.GuardDuty-Event-EC2-MaliciousIPCaller.name، واضبط مُعرّف الهدف على GuardDuty-Example-Remediation. هنا، ستحتاج إلى ARN لدالة Lambda. يُمكن إخراج هذا من وحدة Lambda.
#EVENT TARGET RESOURCE FOR LAMBDA REMEDIATION FUNCTION
resource "aws_cloudwatch_event_target" "lambda_function" {
rule = aws_cloudwatch_event_rule.GuardDuty-Event-EC2-MaliciousIPCaller.name
target_id = "GuardDuty-Example-Remediation"
arn = var.lambda_remediation_function_arn
}7.12. إذا لم تقم بذلك بالفعل، فأضف الناتج إلى وحدة Lambda (modules/lambda/outputs.tf).
output "lambda_remediation_function_arn" {
value = aws_lambda_function.GuardDuty-Example-Remediation-EC2MaliciousIPCaller.arn
}
7.13. يجب تطبيق هذا المتغير أيضًا في وحدة EventBridge (modules/eventbridge/variables.tf).
variable "lambda_remediation_function_arn" {
}٧.١٤. وأخيرًا، أضف lambda_remediation_function_arn إلى الملف root/main.tf. سيُضاف هذا إلى قاعدة EventBridge التي تم إنشاؤها سابقًا. الناتج أدناه هو كتلة التعليمات البرمجية كاملةً، وبعضها موجودٌ بالفعل. تأكد من إضافة الكود lambda_remediation_function_arn = module.lambda.lambda_remediation_function_arn فقط إلى الكتلة الموجودة.
module "guardduty_eventbridge_rule" {
source = "./modules/eventbridge"
sns_topic_arn = module.guardduty_sns_topic.sns_topic_arn
lambda_remediation_function_arn = module.lambda.lambda_remediation_function_arn
}
في هذا القسم، أنشأتَ دالة لامدا لعزل مُضيف مُعرَّض للخطر في مجموعة أمان مختلفة. يُستدعى هذا الدالة بواسطة EventBridge عندما تُطابق نتيجة GuardDuty قاعدة EventBridge. في القسم التالي، ستُطبِّق التكوين بالكامل.
الخطوة 8: تطبيق الإعدادات على حساب AWS الخاص بك
٨.١. شغّل Terraform init. سيؤدي هذا إلى تهيئة جميع الوحدات التي أضفتها في هذا البرنامج التعليمي. يجب أن يكون الناتج كما يلي.

8.2. قم بإعداد مخطط للأرضية.
٨.٣. لتطبيق التغييرات على AWS، شغّل تطبيق Terraform. بعد التطبيق، يجب أن يكون الناتج كما يلي:
في هذا القسم، طبّقتَ إعدادات Terraform على حساب AWS الخاص بك. في هذه المرحلة، لديك مثيلان EC2 يتواصلان. أحدهما ضار، وقد أُضيف عنوان IP الخاص به إلى قائمة عناوين IP المُعرّضة للتهديدات. عندما يكتشف GuardDuty أن عنوان IP هذا يتصل بالمثيل المُخترق، يُنشئ نتيجة. لدينا قاعدة EventBridge تُطابق هذه النتيجة، وتقوم بأمرين: أولًا، تُرسل إلينا بريدًا إلكترونيًا تُعلمنا بما حدث، وثانيًا، تُستدعي دالة Lambda لتغيير مجموعة الأمان للمُضيف المُخترق. في القسم التالي، سنتحقق من الإعدادات في وحدة تحكم AWS.
الخطوة 9: التحقق من الحل في وحدة التحكم الإدارية في AWS
في هذا القسم، سنراجع الحل بأكمله في وحدة التحكم AWS ونتأكد من ترحيل مجموعة الأمان عندما تظهر النتائج في GuardDuty ويقوم EventBridge بتشغيل وظيفة Lambda.
يجب أن تكون قد تلقيت أيضًا رسالة بريد إلكتروني لتأكيد اشتراكك. تذكر أنه يجب عليك الاشتراك لتلقي الإشعارات التي قمت بتكوينها.
بعد الاشتراك، انتقل إلى وحدة التحكم في إدارة AWS للتحقق من وجود مثيلين EC2 وأن كلاهما موجود في مجموعة الأمان الأساسية.
أولاً، تحقق من وجود مضيفين معرضين للخطر.
ثم تحقق من وجود مضيفين ضارين.
ثم تأكد من قيام GuardDuty بإبلاغ النتائج.

الآن تحقق مما وجدته قاعدة EventBridge.
ثم تحقق من هدف قاعدة EventBridge. يجب أن ترى هدف SNS وهدف Lambda.
تحقق من قاعدة SNS لمعرفة ما تفعله. من المفترض أن تُرسل بريدًا إلكترونيًا إلى العنوان الذي حددته.
ثم تحقق من دالة لامدا. يمكنك الوصول إليها من قاعدة EventBridge أو بالتنقل مباشرةً.
أخيرًا، تأكد من أن وظيفة Lambda قامت بنقل المضيف المخترق إلى مجموعة أمان جديدة.
اعتمادًا على المدة التي انتظرتها، إذا كان تكوينك يتطابق مع لقطات الشاشة أعلاه، فقد نجحت في إنشاء حل أمان AWS كامل باستخدام Terraform.
































