شبكات AWS والهوية

الشبكات الفرعية وجداول التوجيه والبوابات

18 دقيقة الدرس 2 من 28

الشبكات الفرعية وجداول التوجيه والبوابات

الـ VPC بحد ذاته مجرد فضاء عناوين فارغ. الشبكات الفرعية وجداول التوجيه والبوابات هي الآليات الثلاث التي تقسّم هذا الفضاء إلى قطاعات شبكية وظيفية وتتحكم في كيفية تدفق حركة البيانات إلى الداخل والخارج وبين هذه القطاعات. الحصول على هذه الطوبولوجيا بشكل صحيح هو القرار المعماري الأكثر تأثيراً في حسابات AWS — الأخطاء هنا تُسبب حوادث أمنية وفواتير بيانات غير متوقعة وانقطاعات تمتد لساعات.

الشبكات الفرعية: تقسيم الـ VPC

الـ Subnet هو كتلة متجاورة من عناوين IP ضمن CIDR الخاص بـ VPC، مقيّدة بمنطقة توافر (AZ) واحدة. كل EC2 instance وRDS instance وLambda VPC attachment وECS task تعمل داخل subnet. هنا يتجسّد عزل الأخطاء على مستوى منطقة التوافر فعلياً.

يعتمد النمط الإنتاجي الراسخ على ثلاث طبقات موزّعة على منطقتَي توافر على الأقل:

  • الشبكات العامة (Public Subnets) — المضيفون الذين يجب أن يكونوا قابلين للوصول مباشرةً من الإنترنت (موازنات الحِمل، بوابات NAT، بوابات الوصول). كل subnet عام يملك خاصية auto-assign public IPv4 مفعّلة ومرتبطاً بجدول توجيه يحتوي مساراً افتراضياً نحو Internet Gateway.
  • الشبكات الخاصة (Private Subnets) — طبقة التطبيقات (ECS tasks، خوادم EC2، Lambda). لا IP عام. حركة الإنترنت الصادرة تمر عبر NAT Gateway الموجود في الـ subnet العام في نفس منطقة التوافر.
  • الشبكات المعزولة (Isolated Subnets) — RDS، ElastiCache، OpenSearch. لا مسار إلى الإنترنت بالمطلق — حتى عبر NAT. الحركة داخلية بالـ VPC فقط أو عبر VPC Endpoints.
تناظر منطق التوافر ضروري. اجعل كل طبقة من الـ subnets متطابقة في كل AZ تستخدمها. إذا وضعت NAT Gateway في us-east-1a فقط وتعرّضت هذه المنطقة لعطل جزئي، ستفقد كل الـ instances الخاصة في us-east-1b اتصالها بالإنترنت. دائماً: NAT واحد لكل AZ — تكلفة نقل البيانات الإضافية لا تُقارَن بحجم الضرر المحتمل.

قواعد حجم الـ CIDR

تحجز AWS 5 عناوين لكل subnet (الشبكة، موجّه VPC، DNS، للاستخدام المستقبلي، البث). الـ /28 يعطي 11 عنواناً فقط — مناسب لـ subnet يحتوي NAT Gateway واحداً، ضيّق لأي شيء آخر. الـ /24 يعطي 251 عنواناً. معظم الفرق تخصص كتل /20 للشبكات العامة والخاصة، و/24 للمعزولة. لا يمكن تغيير حجم الـ subnet بعد الإنشاء — خطّط لـ 3 أضعاف الذروة المتوقعة واستخدم نطاقات RFC 1918 غير متداخلة إذا كنت تخطط للـ VPC Peering أو الاتصال بالشبكات المحلية.

Internet Gateways (IGW)

Internet Gateway هو مكوّن VPC مُدار بالكامل يتوسّع أفقياً ويتيح حركة IPv4/IPv6 ثنائية الاتجاه بين VPC والإنترنت العام. يوجد IGW واحد فقط لكل VPC. إرفاقه مجاني؛ رسوم نقل البيانات تُطبَّق على الحركة الصادرة. يؤدي IGW وظيفتين:

  1. يُمثّل الهدف للمسار الافتراضي (0.0.0.0/0 → igw-xxxxxxxx) في جدول توجيه الـ subnet العام.
  2. يُجري NAT بنسبة 1:1 بين الـ IP الخاص للـ instance والـ Elastic IP (أو IP العام المعيّن تلقائياً) للـ instances التي تمتلكه.
Subnet عام ≠ Instance عام. الـ subnet يكون "عاماً" فقط لأن جدول توجيهه يشير إلى IGW. الـ instance في ذلك الـ subnet لا يُمكن الوصول إليه من الإنترنت إلا إذا امتلك IP عاماً أو Elastic IP. يمكن أن تملك instances في subnet عام بدون IP عام — تستطيع بدء اتصالات خارجية لكن لا يمكن الوصول إليها من الخارج. هذا نمط مفيد لبوابات NAT ذاتها.

NAT Gateways

كثيراً ما تحتاج الـ instances الخاصة للوصول إلى الإنترنت لتحديث الحزم، سحب صور الحاويات، أو استدعاء APIs خارجية — لكنك لا تريدها مكشوفة للاتصالات الواردة. NAT Gateway يحل هذه المعادلة. يعيش في subnet عام، يمتلك Elastic IP، ويُجري ترجمة عناوين المنافذ للاتصالات الصادرة من الـ instances الخاصة. AWS تُدير البوابة بالكامل — لا ترقيع، لا تحديد حجم، توسّع تلقائي حتى 100 Gbps.

خصائص تشغيلية حيوية:

  • بوابات NAT مقيّدة بمنطقة التوافر. وجّه كل subnet خاص نحو بوابة NAT في نفس الـ AZ لتجنب رسوم نقل البيانات العابرة للـ AZ وأعطال الاعتماد على منطقة واحدة.
  • هي أحادية الاتجاه: الـ instances الخاصة تستطيع بدء اتصالات للخارج؛ لا شيء يستطيع بدء اتصالات للداخل عبر NAT.
  • لا تدعم الاتصالات الواردة أو إعادة توجيه المنافذ.
  • نموذج التكلفة: 0.045 دولار/ساعة (us-east-1) + 0.045 دولار/جيجابايت. ثلاث بوابات NAT (واحدة لكل AZ) في بيئة مزدحمة قد تكلّف 200-400 دولار شهرياً — ضعها في الحسبان منذ البداية.
حركة البيانات بين الـ subnets الخاصة عبر AZs مختلفة قد تمر عبر NAT عند سوء الضبط. الخطأ الشائع هو توجيه جميع الـ subnets الخاصة نحو بوابة NAT واحدة. عند تعطّل تلك الـ AZ، ينقطع كل اتصال خارجي من جميع الـ subnets الخاصة. الحل: جدول توجيه منفصل لكل AZ-tier، كل منهم يشير إلى بوابة NAT الخاصة به.

جداول التوجيه

Route Table هو قائمة مرتبة من قواعد destination-prefix → target. كل subnet يجب أن يكون مرتبطاً بجدول توجيه واحد تحديداً. إذا لم تربطه صراحةً، يستخدم الـ subnet جدول التوجيه الرئيسي للـ VPC — مناسب للشبكات المعزولة، محفوف بالمخاطر لغيرها لأن أي تغيير على الجدول الرئيسي يؤثر على كل subnet مرتبط به ضمنياً.

الإعداد ذو الثلاث طبقات البسيط يحتاج كحد أدنى:

  • RT العام10.0.0.0/16 → local (مُنشأ تلقائياً) + 0.0.0.0/0 → igw-xxx
  • RT الخاص (لكل AZ)10.0.0.0/16 → local + 0.0.0.0/0 → nat-xxx في نفس الـ AZ
  • RT المعزول10.0.0.0/16 → local فقط

تُطابَق المسارات وفق أطول بادئة أولاً. مسار local (CIDR الـ VPC) موجود دائماً ضمنياً ولا يمكن حذفه — يضمن قدرة جميع الـ subnets على الوصول لبعضها بشكل افتراضي.

البنية التحتية كأكواد: مثال Terraform

في الإنتاج، كل مكوّن VPC مُعرَّف في Terraform. المقطع التالي ينشئ subnet عاماً واحداً وsubnet خاصاً وIGW وNAT Gateway وجداول التوجيه في AZ واحدة. المودييل الحقيقي يكرر هذا عبر عدة AZs.

# Internet Gateway — واحد لكل VPC resource "aws_internet_gateway" "main" { vpc_id = aws_vpc.main.id tags = { Name = "main-igw" } } # Public subnet (us-east-1a) resource "aws_subnet" "public_1a" { vpc_id = aws_vpc.main.id cidr_block = "10.0.0.0/20" availability_zone = "us-east-1a" map_public_ip_on_launch = true tags = { Name = "public-1a", Tier = "public" } } # Private subnet (us-east-1a) resource "aws_subnet" "private_1a" { vpc_id = aws_vpc.main.id cidr_block = "10.0.16.0/20" availability_zone = "us-east-1a" tags = { Name = "private-1a", Tier = "private" } } # Elastic IP for NAT Gateway resource "aws_eip" "nat_1a" { domain = "vpc" } # NAT Gateway — lives in the PUBLIC subnet resource "aws_nat_gateway" "nat_1a" { allocation_id = aws_eip.nat_1a.id subnet_id = aws_subnet.public_1a.id tags = { Name = "nat-1a" } depends_on = [aws_internet_gateway.main] } # Public route table resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.main.id } tags = { Name = "rt-public" } } resource "aws_route_table_association" "public_1a" { subnet_id = aws_subnet.public_1a.id route_table_id = aws_route_table.public.id } # Private route table — routes outbound through NAT in same AZ resource "aws_route_table" "private_1a" { vpc_id = aws_vpc.main.id route { cidr_block = "0.0.0.0/0" nat_gateway_id = aws_nat_gateway.nat_1a.id } tags = { Name = "rt-private-1a" } } resource "aws_route_table_association" "private_1a" { subnet_id = aws_subnet.private_1a.id route_table_id = aws_route_table.private_1a.id }

التحقق من البنية باستخدام AWS CLI

بعد التطبيق، تحقق من جداول التوجيه وارتباطاتها قبل نشر أي أعباء عمل:

# عرض جميع جداول التوجيه في الـ VPC aws ec2 describe-route-tables \ --filters "Name=vpc-id,Values=vpc-0abc1234" \ --query "RouteTables[*].{ID:RouteTableId,Routes:Routes[*].{Dest:DestinationCidrBlock,Target:GatewayId||NatGatewayId}}" \ --output table # التأكد من أن NAT Gateway في حالة Available aws ec2 describe-nat-gateways \ --filter "Name=vpc-id,Values=vpc-0abc1234" \ --query "NatGateways[*].{ID:NatGatewayId,State:State,AZ:SubnetId}" \ --output table # اختبار اتصال سريع من instance خاص عبر SSM Session Manager aws ssm start-session --target i-0privateinstance # بداخله: curl -s https://checkip.amazonaws.com # يجب أن يعود بـ EIP الخاص بـ NAT Gateway وليس الـ IP الخاص للـ instance

مخطط بنية الـ VPC

Three-tier VPC with public, private, and isolated subnets across two AZs VPC 10.0.0.0/16 Internet Internet Gateway AZ: us-east-1a AZ: us-east-1b Public Subnet 10.0.0.0/20 ALB / Bastion NAT GW (EIP) Public Subnet 10.0.32.0/20 ALB / Bastion NAT GW (EIP) Private Subnet 10.0.16.0/20 App Servers / ECS Private Subnet 10.0.48.0/20 App Servers / ECS Isolated Subnet 10.0.64.0/24 RDS / ElastiCache Isolated Subnet 10.0.65.0/24 RDS / ElastiCache VPC local only RT: 0/0 → IGW RT: 0/0 → NAT (same AZ) RT: local only
بنية VPC ذات ثلاث طبقات: شبكات عامة (مُوجَّهة عبر IGW)، شبكات خاصة (مُوجَّهة عبر NAT)، وشبكات معزولة (بلا مسار إنترنت)، موزّعة على منطقتَي توافر.

أنماط الفشل الإنتاجية الشائعة

غياب depends_on عند NAT Gateway. في Terraform، إذا أُنشئت بوابة NAT قبل ربط IGW بالـ VPC، تُعيد AWS خطأ لأن NAT يحتاج IGW موجوداً مسبقاً. دائماً اضبط depends_on = [aws_internet_gateway.main] على بوابة NAT.

عدم ربط جدول التوجيه. جدول توجيه منشأ حديثاً لا يملك أي ارتباطات subnet. مورد aws_route_table_association في Terraform (أو aws_subnet.route_table_id في CDK) يُنجز هذا الربط. بدونه يعود الـ subnet صامتاً إلى جدول التوجيه الرئيسي.

NAT Gateway في Subnet خاطئ. بوابات NAT يجب أن تكون في subnet عام. وضعها في subnet خاص يخلق تبعية دائرية — يشير المسار الخاص إلى NAT، وNAT نفسه ليس لديه مسار إنترنت، فتُهدر حركة البيانات الصادرة صامتةً.

ضع Tags لكل شيء بـ Tier و AZ. الموارد المُوسَمة بـ Tier=public وTier=private وTier=isolated وAZ=us-east-1a تُتيح تقسيم تكاليف Cost Explorer بالطبقة، نتائج Security Hub بالطبقة، ومراجعة يدوية سريعة. اجعل هذه Tags إلزامية في AWS Organizations SCP منذ اليوم الأول.