Menu
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Đang tải...

Bài 43 — Network Operations: VPC, Security Groups, Subnet

Operations Management for Tech Bài 43/60

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn vừa deploy một ứng dụng lên cloud. Code chạy ngon trên máy bạn, container build sạch sẽ, nhưng khi lên môi trường production thì database "không kết nối được", request từ internet "timeout", còn service A gọi service B thì báo "connection refused". Chín trên mười trường hợp như thế, thủ phạm không nằm ở code — nó nằm ở tầng mạng: VPC, subnet, route table và security group.

Network Operations là phần "hạ tầng vô hình" mà rất nhiều kỹ sư bỏ qua cho đến khi có sự cố. Nhưng với người làm Operations, đây là kiến thức nền tảng bắt buộc. Bạn không cần phải là chuyên gia network như thời "cắm cáp switch Cisco", nhưng bạn phải hiểu rõ cách một gói tin đi từ người dùng đến ứng dụng, đi qua những chốt chặn nào, và ai được phép nói chuyện với ai. Khi hiểu được điều đó, bạn debug sự cố nhanh gấp mười lần, thiết kế hệ thống an toàn hơn, và quan trọng nhất — bạn ngủ ngon hơn vì biết cửa nào đang mở, cửa nào đang khóa.

Trong bài này, chúng ta tập trung vào ba trụ cột của mạng trong môi trường cloud: VPC (mạng ảo cô lập), Subnet (cách chia nhỏ mạng theo vùng và theo mức độ công khai), và Security Group cùng các cơ chế điều khiển luồng traffic. Đây là "bộ khung xương" của mọi kiến trúc bạn sẽ vận hành.

Khái niệm cốt lõi

VPC — mạng ảo riêng của bạn

VPC (Virtual Private Cloud) là một mạng ảo được cô lập hoàn toàn dành riêng cho tài khoản của bạn bên trong hạ tầng của nhà cung cấp cloud (AWS, GCP, Azure). Hãy hình dung cloud như một tòa nhà chung cư khổng lồ, còn VPC là căn hộ riêng của bạn — có tường bao, có cửa, và hàng xóm không thể tự nhiên bước vào.

Đặc điểm quan trọng nhất của VPC là sự cô lập. Mặc định, hai VPC khác nhau (kể cả trong cùng một tài khoản) không thể nói chuyện với nhau, trừ khi bạn chủ động kết nối chúng qua VPC Peering hoặc Transit Gateway. Điều này giúp bạn tách biệt môi trường: một VPC cho production, một VPC cho staging, và chúng không thể vô tình "giẫm chân" nhau.

Khi tạo VPC, bạn phải khai báo một dải địa chỉ IP riêng gọi là CIDR block, ví dụ 10.0.0.0/16. Dải này quyết định VPC của bạn có bao nhiêu địa chỉ IP để dùng. /16 cho bạn khoảng 65.536 địa chỉ — thường là quá đủ. Một lời khuyên sớm: hãy chọn dải IP không trùng với các VPC hay mạng on-premise khác mà bạn có thể cần kết nối trong tương lai, nếu không việc peering về sau sẽ rất đau đầu.

Subnet — chia nhỏ VPC theo AZ và theo mức công khai

VPC là một dải IP lớn, nhưng bạn không đặt mọi thứ vào chung một chỗ. Bạn chia nó thành các subnet (mạng con). Mỗi subnet lấy một phần nhỏ của CIDR block VPC, ví dụ 10.0.1.0/24 (256 địa chỉ).

Subnet được chia theo hai chiều quan trọng:

Chiều thứ nhất — theo Availability Zone (AZ): Mỗi subnet nằm trọn trong một AZ (một trung tâm dữ liệu vật lý). Để hệ thống chịu lỗi tốt, bạn trải subnet ra nhiều AZ. Nếu một AZ chết, các AZ khác vẫn phục vụ. Đây là nền tảng của tính sẵn sàng cao (chúng ta sẽ đào sâu ở Bài 28).

Chiều thứ hai — public vs private:

  • Public subnet: có đường ra internet trực tiếp thông qua Internet Gateway (IGW). Đây là nơi đặt những thứ cần "mặt tiền" ra ngoài: load balancer, bastion host, NAT gateway.
  • Private subnet: không có đường vào trực tiếp từ internet. Đây là nơi đặt những thứ nhạy cảm: application server, database, cache. Chúng vẫn có thể ra internet (để tải update, gọi API bên ngoài) thông qua NAT Gateway đặt ở public subnet, nhưng internet không thể chủ động vào chúng.
Nguyên tắc vàng: database và application logic luôn nằm ở private subnet. Chỉ những gì bắt buộc phải tiếp xúc internet mới đặt ở public subnet.

Route table — bản đồ dẫn đường cho gói tin

Route table là bảng quy tắc quyết định gói tin đi đâu dựa trên địa chỉ đích. Mỗi subnet được gắn với một route table. Đây chính là yếu tố thực sự phân biệt public và private subnet — không phải tên gọi, mà là route table.

Một route table điển hình có các dòng như:

  • 10.0.0.0/16 → local: mọi traffic trong nội bộ VPC đi thẳng, không cần qua đâu cả.
  • 0.0.0.0/0 → igw-xxxx: mọi traffic đi ra internet (không khớp dòng nào ở trên) thì đẩy ra Internet Gateway. Dòng này khiến subnet trở thành public.
Nếu route table không có dòng 0.0.0.0/0 → IGW, subnet đó là private. Nếu bạn muốn private subnet ra được internet để tải update, bạn thêm 0.0.0.0/0 → nat-xxxx (trỏ tới NAT Gateway).

Security Group vs NACL — hai lớp tường lửa

Đây là phần hay gây nhầm lẫn nhất, nên hãy phân biệt rõ:

Security Group (SG) là tường lửa ở cấp instance/tài nguyên (gắn vào EC2, RDS, load balancer...). Đặc điểm:

  • Stateful: nếu bạn cho phép request đi vào, thì response tự động được phép đi ra (và ngược lại). Bạn không cần khai báo hai chiều.
  • Chỉ có luật allow (cho phép), không có luật deny. Cái gì không được cho phép rõ ràng thì mặc định bị chặn.
  • Bạn thường tham chiếu SG khác thay vì IP. Ví dụ: "SG của database chỉ cho phép traffic port 3306 đến từ SG của app server" — cực kỳ gọn và an toàn.
NACL (Network ACL) là tường lửa ở cấp subnet. Đặc điểm:
  • Stateless: bạn phải khai báo cả luật vào lẫn luật ra một cách tường minh.
  • Có cả luật allow và deny, xử lý theo số thứ tự.
  • Thường dùng như một lớp phòng thủ thô, ví dụ chặn một dải IP độc hại ở cấp subnet.
Trong thực tế, 90% công việc hằng ngày của bạn là làm việc với Security Group. NACL để mặc định (cho phép tất cả) là ổn trong đa số trường hợp, chỉ động vào khi có nhu cầu đặc biệt.

Tình huống thực tế

Tình huống 1 — Sàn TMĐT Việt Nam mở port database ra internet

Một startup thương mại điện tử ở TP.HCM, tạm gọi là ShopViet, thuê một kỹ sư junior dựng hạ tầng trên AWS trong lúc gấp rút chuẩn bị cho đợt sale 12/12. Để "cho nhanh, đỡ vướng", bạn kỹ sư đặt luôn database RDS MySQL vào public subnet và mở Security Group với luật port 3306 từ 0.0.0.0/0 — nghĩa là bất kỳ ai trên internet cũng gõ cửa được database.

Ba tuần sau, đội vận hành phát hiện bảng customers bị mã hóa và một ghi chú đòi tiền chuộc bằng Bitcoin. Log cho thấy kẻ tấn công đã brute-force mật khẩu database từ một IP ở nước ngoài. Thiệt hại: 4 ngày ngừng bán trong cao điểm, dữ liệu 80.000 khách hàng bị lộ, và một khoản phạt về bảo vệ dữ liệu cá nhân.

Bài học: Database không bao giờ được đặt ở public subnet, và Security Group của database không bao giờ mở ra 0.0.0.0/0. Cách làm đúng: đặt RDS ở private subnet, Security Group chỉ cho phép port 3306 đến từ Security Group của app server. Với cấu hình đó, kẻ tấn công đứng ngoài internet thậm chí không "thấy" được database tồn tại.

Tình huống 2 — Fintech Singapore và bài toán NAT Gateway đắt đỏ

Một công ty fintech ở Singapore, tạm gọi PayFlow, thiết kế hạ tầng rất chuẩn: mọi microservice nằm ở private subnet trải trên 3 AZ, ra internet qua NAT Gateway để gọi API của các ngân hàng đối tác. Kiến trúc an toàn, không chê được về mặt bảo mật.

Nhưng cuối tháng, hóa đơn AWS cho phần data processing của NAT Gateway lên tới hơn 9.000 USD. Điều tra ra thì thủ phạm là: các service đọc/ghi hàng terabyte dữ liệu vào Amazon S3, và toàn bộ traffic đó đi vòng qua NAT Gateway ra internet rồi mới tới S3 — mỗi GB đi qua NAT đều bị tính phí.

Giải pháp: họ tạo một VPC Endpoint (Gateway Endpoint) cho S3. Endpoint này cho phép traffic từ private subnet đến S3 đi thẳng qua mạng nội bộ AWS, không đụng đến NAT Gateway, và miễn phí với Gateway Endpoint. Hóa đơn NAT tháng sau giảm khoảng 70%.

Bài học: Network Ops không chỉ là bảo mật — nó gắn chặt với chi phí. Hãy hiểu đường đi thật sự của traffic. Traffic đến các dịch vụ cùng nhà cung cấp (S3, DynamoDB, ECR...) nên đi qua VPC Endpoint thay vì vòng ra internet.

Tình huống 3 — Hai service "không thấy nhau" vì thiếu route

Một team ở Hà Nội tách hệ thống thành hai VPC: vpc-paymentvpc-core. Họ tạo VPC Peering để hai bên nói chuyện. Nhưng sau khi peering, service bên vpc-core vẫn không gọi được service bên vpc-payment, báo timeout liên tục. Kỹ sư mất nửa ngày nghi ngờ code, nghi ngờ DNS, nghi ngờ cả nhà mạng.

Nguyên nhân thật: peering connection đã tạo, nhưng route table của hai bên chưa được cập nhật. Peering chỉ mở "con đường vật lý", còn gói tin không biết phải đi lối nào nếu route table không có dòng trỏ dải IP của VPC kia qua peering connection. Sau khi thêm route ở cả hai route table (và mở Security Group tương ứng), mọi thứ thông ngay.

Bài học: Khi hai tài nguyên "không thấy nhau" trong cloud, hãy kiểm tra theo thứ tự: (1) route table có đường đi chưa, (2) Security Group có cho phép chưa, (3) NACL có chặn không. Đừng vội đổ lỗi cho ứng dụng.

Hướng dẫn từng bước

Dưới đây là quy trình dựng một VPC production cơ bản, an toàn theo chuẩn công nghiệp. Áp dụng được trên AWS (và tương tự trên GCP/Azure với tên gọi khác).

  • Chọn CIDR block cho VPC. Ví dụ 10.20.0.0/16. Ghi lại vào tài liệu và tránh trùng với các mạng khác trong tổ chức.
  • Tạo subnet trải trên tối thiểu 2 AZ. Mỗi AZ nên có một cặp public + private:
- 10.20.1.0/24 (public, AZ-a), 10.20.2.0/24 (private, AZ-a) - 10.20.3.0/24 (public, AZ-b), 10.20.4.0/24 (private, AZ-b)

  • Gắn Internet Gateway vào VPC. Đây là cửa ra internet duy nhất.
  • Cấu hình route table cho public subnet: thêm dòng 0.0.0.0/0 → IGW. Gắn route table này cho các public subnet.
  • Tạo NAT Gateway ở public subnet (nên có một NAT mỗi AZ để chịu lỗi). Cấu hình route table cho private subnet: 0.0.0.0/0 → NAT Gateway của cùng AZ.
  • Thiết kế Security Group theo tầng, tham chiếu lẫn nhau:
- sg-alb: cho phép inbound port 80/443 từ 0.0.0.0/0. - sg-app: cho phép inbound port ứng dụng (ví dụ 8080) chỉ từ sg-alb. - sg-db: cho phép inbound port 3306 chỉ từ sg-app.

  • Đặt tài nguyên đúng chỗ: Load balancer ở public subnet, application server và database ở private subnet.
  • Tạo VPC Endpoint cho các dịch vụ nội bộ hay dùng (S3, ECR, CloudWatch) để tiết kiệm chi phí và tăng bảo mật.
  • Bật VPC Flow Logs để ghi lại toàn bộ luồng traffic — cực kỳ quý giá khi debug và điều tra sự cố bảo mật.

Lỗi thường gặp & mẹo

  • Mở Security Group ra 0.0.0.0/0 cho port quản trị (SSH 22, RDP 3389, database 3306/5432). Đây là lỗi phổ biến và nguy hiểm nhất. Luôn giới hạn theo IP văn phòng, VPN, hoặc dùng bastion/SSM.
  • Nhầm giữa Security Group stateful và NACL stateless. Nếu bạn thấy request vào được nhưng response không về, khả năng cao bạn đang vướng NACL (stateless) mà quên mở luật chiều ngược lại. Với Security Group thì không có chuyện này.
  • Chọn CIDR quá nhỏ hoặc trùng lặp. Một /28 (16 IP) nghe có vẻ đủ nhưng cloud "ăn" mất vài IP cho mục đích nội bộ, và bạn hết chỗ rất nhanh khi auto-scaling. Trùng CIDR thì không thể peering. Hãy quy hoạch dải IP ngay từ đầu.
  • Đặt mọi thứ trong một AZ duy nhất. Rẻ hơn một chút nhưng khi AZ đó gặp sự cố, toàn bộ hệ thống sập. Luôn trải tối thiểu 2 AZ cho production.
  • Quên rằng NAT Gateway tính phí theo lượng dữ liệu. Traffic lớn (đọc S3, log, backup) đi qua NAT có thể tốn hàng nghìn USD. Dùng VPC Endpoint cho traffic nội bộ.
  • Mẹo debug: Khi "không kết nối được", đi theo đường của gói tin từ ngoài vào trong theo thứ tự: DNS → route table → NACL → Security Group → ứng dụng có đang listen đúng port không. Bật VPC Flow Logs để nhìn thấy gói tin bị REJECT ở đâu.
  • Mẹo bảo mật: Tham chiếu Security Group bằng SG ID thay vì IP bất cứ khi nào có thể. Khi IP thay đổi do auto-scaling, luật vẫn đúng, không cần sửa tay.

Bài tập thực hành

  • Vẽ sơ đồ mạng. Trên giấy hoặc công cụ như draw.io, vẽ một VPC 10.0.0.0/16 gồm 2 AZ, mỗi AZ có 1 public và 1 private subnet, có IGW, 2 NAT Gateway, và các Security Group theo tầng (alb → app → db). Đánh dấu đường đi của một request từ người dùng đến database.
  • Phân loại tài nguyên. Với danh sách sau, hãy xác định mỗi thứ nên nằm ở public hay private subnet, và giải thích: Application Load Balancer, PostgreSQL RDS, Redis cache, NAT Gateway, bastion host, backend API server.
  • Thiết kế Security Group. Viết ra luật inbound cho ba Security Group (sg-alb, sg-app, sg-db) sao cho: internet chỉ vào được ALB qua 443; ALB chỉ nói chuyện với app qua 8080; app chỉ nói chuyện với db qua 5432. Chú ý dùng tham chiếu SG thay vì IP.
  • Tình huống debug (tự luận). Một app ở private subnet không tải được thư viện từ internet khi build. Hãy liệt kê 3 nguyên nhân network có thể (gợi ý: NAT, route table, NACL) và cách kiểm tra từng cái.
  • Nâng cao — nếu có tài khoản cloud: Dùng AWS Free Tier tạo thử một VPC theo quy trình 9 bước ở trên, bật Flow Logs, và quan sát log khi bạn cố SSH vào một instance ở private subnet (nó sẽ bị REJECT — hãy tìm dòng log đó).

Tóm tắt

Network Operations trong cloud xoay quanh việc kiểm soát ai được nói chuyện với ai và qua đường nào. VPC là mạng ảo cô lập với dải IP riêng (CIDR). Subnet chia VPC theo AZ (để chịu lỗi) và theo mức công khai — public subnet có đường ra internet qua Internet Gateway, còn private subnet thì không, và đó là nơi bạn đặt database cùng application. Yếu tố thực sự quyết định public hay private là route table, không phải tên gọi.

Về bảo mật, Security Group là tường lửa stateful cấp tài nguyên, chỉ có luật allow, và nên tham chiếu lẫn nhau theo tầng; NACL là tường lửa stateless cấp subnet, có cả allow lẫn deny. Ba tình huống trong bài cho thấy hậu quả thật khi làm sai: database bị hack vì mở ra internet, hóa đơn NAT phình to vì thiếu VPC Endpoint, và service "không thấy nhau" vì quên cập nhật route table.

Ghi nhớ ba nguyên tắc cốt lõi: (1) database và logic nhạy cảm luôn ở private subnet; (2) Security Group giới hạn chặt theo tầng, không bao giờ mở port quản trị ra 0.0.0.0/0; (3) khi debug kết nối, đi theo đường gói tin — route table, NACL, Security Group — trước khi đổ lỗi cho code. Nắm vững bộ khung này, bạn đã có nền tảng để vận hành mọi kiến trúc phức tạp hơn trong các bài tiếp theo.