Public Subnet vs Private Subnet trong AWS VPC: Cách Giấu Database Khỏi Internet
Danh Mục Bài Viết
- 1. Public Subnet và Private Subnet là gì? Giải thích bình dân
- 2. Khi nào dùng Public Subnet, khi nào dùng Private Subnet?
- 3. Hướng dẫn cấu hình từng bước: Tạo Public và Private Subnet
- 4. Kinh nghiệm thực chiến và "Ổ gà" cần tránh
- 5. FAQ — Câu hỏi thường gặp
- 6. Bảo mật không phải là thứ thêm vào sau — nó phải là kiến trúc
Hồi mới học AWS, mình đã từng deploy một ứng dụng Node.js với RDS MySQL. Tất cả chạy ngon lành, khách hàng dùng được, mình vui lắm. Cho đến một ngày, mình chạy thử một port scanner thì... database port 3306 của mình mở toác ra ngoài Internet. Bất kỳ ai cũng có thể thử brute-force vào đó. Lạnh cả người. Đó là lúc mình bắt đầu học nghiêm túc về VPC Subnets.
Public Subnet và Private Subnet là gì? Giải thích bình dân
Hãy tưởng tượng VPC (Virtual Private Cloud) của bạn là một tòa nhà văn phòng. Trong tòa nhà đó, bạn có hai khu vực:
Public Subnet giống như tầng trệt có lễ tân — ai từ ngoài đường cũng có thể bước vào, gặp nhân viên lễ tân, gửi thư, nhận hàng. Đây là nơi bạn đặt những thứ cần giao tiếp trực tiếp với Internet: web server, load balancer, bastion host.
Private Subnet giống như các tầng văn phòng bên trên — khách bên ngoài không thể tự lên đó được. Chỉ nhân viên nội bộ (hoặc người được lễ tân dẫn lên) mới vào được. Đây là nơi bạn đặt database, backend service, bất kỳ thứ gì không cần expose ra Internet.
Sự khác biệt kỹ thuật cốt lõi nằm ở Route Table: Public Subnet có route 0.0.0.0/0 trỏ tới Internet Gateway (IGW), còn Private Subnet thì không. Đơn giản vậy thôi, nhưng ý nghĩa bảo mật khổng lồ.
Khi nào dùng Public Subnet, khi nào dùng Private Subnet?
Hiểu lý thuyết rồi, nhưng áp dụng vào thực tế thế nào? Đây là các use case điển hình:
- Web Application (3-tier architecture): Application Load Balancer nằm ở Public Subnet nhận traffic từ Internet; EC2 chạy Node.js/PHP đặt ở Private Subnet; RDS MySQL/PostgreSQL đặt sâu hơn trong Private Subnet (thậm chí một Private Subnet riêng biệt). Người dùng chỉ tiếp cận được Load Balancer, không bao giờ chạm được tới EC2 hay database.
- Microservices với API Gateway: API Gateway hoặc NLB đặt ở Public Subnet; các service container (ECS/EKS) chạy trong Private Subnet; service giao tiếp với nhau qua internal VPC DNS, không cần ra Internet. Kết quả: giảm attack surface xuống còn 1 điểm vào duy nhất.
- Data Pipeline: Lambda function xử lý data đặt trong Private Subnet; kết nối RDS, ElastiCache, S3 (qua VPC Endpoint) mà không cần public IP. Chi phí NAT Gateway thấp hơn nhiều so với việc để mọi thứ ở public. Một công ty fintech mình biết tiết kiệm ~40% chi phí network sau khi refactor theo pattern này.
Hướng dẫn cấu hình từng bước: Tạo Public và Private Subnet
Mình sẽ hướng dẫn bạn tạo một VPC chuẩn với 2 loại subnet trong cùng một Availability Zone. Trong production, bạn nên nhân đôi cho ít nhất 2 AZ để high availability.
Bước 1: Tạo VPC
Vào AWS Console → VPC → Create VPC. Điền:
- Name:
my-app-vpc - IPv4 CIDR:
10.0.0.0/16(cho phép tới 65,536 địa chỉ IP)
Bước 2: Tạo Public Subnet
VPC → Subnets → Create Subnet:
- VPC: chọn
my-app-vpc - Name:
public-subnet-1a - AZ:
ap-southeast-1a - CIDR:
10.0.1.0/24(256 địa chỉ)
Sau khi tạo xong, chọn subnet → Actions → Edit subnet settings → tick Enable auto-assign public IPv4 address. Bước này quan trọng — instance trong public subnet mới tự nhận public IP.
Bước 3: Tạo Private Subnet
- Name:
private-subnet-1a - AZ:
ap-southeast-1a - CIDR:
10.0.2.0/24
Không enable auto-assign public IP cho private subnet.
Bước 4: Tạo và gắn Internet Gateway
VPC → Internet Gateways → Create IGW → đặt tên my-app-igw → Attach to VPC → chọn my-app-vpc.
Bước 5: Cấu hình Route Table cho Public Subnet
VPC → Route Tables → Create route table:
- Name:
public-rt - VPC:
my-app-vpc
Chọn public-rt → tab Routes → Edit routes → Add route:
- Destination:
0.0.0.0/0 - Target: Internet Gateway → chọn
my-app-igw
Sau đó → tab Subnet associations → Edit → chọn public-subnet-1a.
Bước 6: NAT Gateway cho Private Subnet (nếu cần)
Private Subnet không có đường ra Internet, nhưng đôi khi instance bên trong cần download package, gọi API bên ngoài. Lúc đó dùng NAT Gateway:
VPC → NAT Gateways → Create NAT Gateway:
- Subnet: chọn public subnet (NAT Gateway phải nằm trong public subnet!)
- Elastic IP: Allocate Elastic IP
Tạo Route Table riêng cho private subnet (private-rt), thêm route 0.0.0.0/0 → NAT Gateway, rồi associate với private-subnet-1a.
Mẹo xương máu: NAT Gateway tính phí theo giờ (~$0.045/giờ ở Singapore region) cộng thêm phí data transfer. Nếu bạn chỉ cần private instance download package lúc setup, hãy tạo NAT Gateway tạm, xong việc thì xóa đi. Quên xóa là mất ~$32/tháng cho một NAT Gateway chạy không.
Kinh nghiệm thực chiến và "Ổ gà" cần tránh
Sau vài năm làm việc với VPC, đây là những lỗi mình thấy nhiều nhất:
Lỗi 1: Đặt database trong Public Subnet. Nhiều người làm vậy cho "tiện debug", rồi quên mất. Database không bao giờ cần public IP. Nếu cần kết nối từ máy local để debug, dùng SSH tunnel qua bastion host hoặc AWS Systems Manager Session Manager — không cần mở port 3306/5432 ra Internet.
Lỗi 2: Security Group quá rộng trên Private Subnet. Để subnet là private chưa đủ. Bạn còn cần Security Group của RDS chỉ chấp nhận kết nối từ Security Group của EC2 application, không phải từ 0.0.0.0/0. Hai lớp bảo vệ tốt hơn một.
Lỗi 3: Dùng chung một Route Table cho cả public và private subnet. Mình thấy người mới hay nhầm điều này. Main route table của VPC thường không có route IGW — tốt. Nhưng nếu bạn "tiện tay" gắn cả hai subnet vào public-rt thì private subnet của bạn thực ra đã public rồi đấy.
FAQ — Câu hỏi thường gặp
Q: Instance trong Private Subnet có thể gọi AWS services như S3, DynamoDB không?A: Có, nhưng có 2 cách. Cách 1: qua NAT Gateway (traffic ra Internet rồi vào lại AWS — tốn phí data transfer). Cách 2 tốt hơn: dùng VPC Endpoint — kết nối thẳng từ VPC tới service AWS mà không qua Internet, rẻ hơn và nhanh hơn. Với S3 và DynamoDB, dùng Gateway Endpoint miễn phí. Với các service khác dùng Interface Endpoint (có phí nhỏ).
Q: Tôi có thể có bao nhiêu subnet trong một VPC?A: Mặc định AWS cho tối đa 200 subnet/VPC. Trong thực tế kiến trúc chuẩn thường dùng: 1 public + 1 private/AZ, nhân với số AZ. Ví dụ Singapore region có 3 AZ → 6 subnet tối thiểu. Nên tạo sẵn đủ AZ từ đầu vì resize CIDR sau này rất phức tạp.
Q: NAT Gateway vs NAT Instance: cái nào tốt hơn?A: NAT Gateway của AWS managed hoàn toàn, tự scale, không cần patch. NAT Instance là EC2 tự cài, rẻ hơn (t3.nano ~$3/tháng vs NAT Gateway ~$32/tháng) nhưng bạn phải tự quản lý, tự scale, có single point of failure. Cho production workload quan trọng: NAT Gateway. Cho môi trường dev/test tiết kiệm chi phí: NAT Instance hoặc xóa đi khi không dùng.
Bảo mật không phải là thứ thêm vào sau — nó phải là kiến trúc
Public Subnet và Private Subnet không chỉ là khái niệm lý thuyết trong AWS exam. Đây là nền tảng của mọi kiến trúc cloud production nghiêm túc. Mình đã từng thấy startups bị pentest xong phát hiện database expose ra Internet từ ngày đầu launch — chi phí để fix không chỉ là kỹ thuật, mà còn là niềm tin của khách hàng.
Khi bạn đã nắm vững subnet, bước tiếp theo là đi sâu vào Security Groups và Network ACLs — hai lớp tường lửa bổ sung cho nhau trong VPC. Mình sẽ viết chi tiết về chủ đề đó trong bài tới của series AWS này.
