🎯 Mục Tiêu Lab
Tạo VM trong subnet private, KHÔNG gán public IP
Cấu hình DNAT rule: Firewall Public IP:2222 → VM private IP:22 (SSH)
Giới hạn source IP chỉ cho phép IP quản trị (IP của bạn)
Kiểm tra SSH thành công qua firewall public IP:2222
Verify: IP khác không thể SSH (bị firewall chặn)
Hiểu cơ chế DNAT và use case bảo mật thực tế
📋 Chuẩn Bị
- Hoàn thành Lab 23 (hoặc có Azure Firewall đang chạy)
- Biết public IP của máy bạn:
curl ifconfig.me - SSH client (Terminal trên Mac/Linux, PowerShell/PuTTY trên Windows)
- NAT (Network Address Translation) cơ bản
- SSH port forwarding concept
- Azure Firewall từ Lab 23
🏗️ Kịch Bản
VM quản trị trong môi trường production không được phép có public IP trực tiếp (giảm attack surface). Admin chỉ SSH vào VM thông qua Azure Firewall bằng DNAT rule, và chỉ IP quản trị mới được phép.
Admin Machine (My IP)
│ SSH to FW_PUBLIC_IP:2222
▼
[Azure Firewall] Public IP: x.x.x.x
│ DNAT: x.x.x.x:2222 → 10.0.2.4:22
▼
[VM private] 10.0.2.4 (NO public IP)
│ snet-app subnet
└─ SSH port 22 open
🧪 Các Bước Thực Hiện
Chuẩn Bị Môi Trường (Tái Dùng hoặc Tạo Mới)
Nếu đã có Lab 23 đang chạy, bỏ qua bước này. Nếu không, chạy script nhanh dưới đây.
# Tạo resource group và VNet (bỏ qua nếu có từ Lab 23)
RG="rg-lab24-dnat"
LOCATION="southeastasia"
az group create --name $RG --location $LOCATION
az network vnet create \
--resource-group $RG --name vnet-lab24 \
--address-prefix 10.0.0.0/16 \
--subnet-name AzureFirewallSubnet --subnet-prefix 10.0.1.0/26
az network vnet subnet create \
--resource-group $RG --vnet-name vnet-lab24 \
--name snet-app --address-prefix 10.0.2.0/24
az network public-ip create \
--resource-group $RG --name pip-fw-lab24 \
--sku Standard --allocation-method Static
az network firewall create \
--resource-group $RG --name fw-lab24 \
--location $LOCATION --sku-tier Standard
az network firewall ip-config create \
--firewall-name fw-lab24 --resource-group $RG \
--name fw-ipconfig \
--public-ip-address pip-fw-lab24 --vnet-name vnet-lab24
Tạo VM Private (Không Có Public IP)
VM chỉ có private IP. SSH port 22 mở trong NSG nhưng không thể reach trực tiếp từ Internet.
- 2.1Virtual Machines → + Create → Ubuntu Server 22.04 LTS → Size: Standard_B1s
- 2.2Admin:
azureuser→ Authentication: SSH public key → Generate new key pair - 2.3Tab Networking → VNet: vnet-lab24 → Subnet: snet-app → Public IP: None
- 2.4NIC NSG: Basic → Inbound ports: SSH (22) → Review + Create
- 2.5Download private key → lưu tại
~/.ssh/vm-lab24.pem
RG="rg-lab24-dnat"
# Tạo VM trong snet-app, KHÔNG gán public IP
az vm create \
--resource-group $RG \
--name vm-private-lab24 \
--image Ubuntu2204 \
--vnet-name vnet-lab24 \
--subnet snet-app \
--public-ip-address "" \
--admin-username azureuser \
--generate-ssh-keys \
--size Standard_B1s
# Lấy private IP của VM
VM_PRIVATE_IP=$(az vm show \
--resource-group $RG \
--name vm-private-lab24 \
--show-details \
--query privateIps \
--output tsv)
echo "VM Private IP: $VM_PRIVATE_IP"
# Mở port 22 trong NSG (nếu chưa có)
az vm open-port \
--resource-group $RG \
--name vm-private-lab24 \
--port 22
Tạo Network Rule Collection — Cho Phép SSH Traffic
Trước khi tạo DNAT rule, cần có Network rule cho phép traffic SSH (port 22) từ IP quản trị qua firewall.
- 3.1fw-lab24 → Rules (classic) → Network rule collection → + Add
- 3.2Name:
nrc-allow-ssh-admin→ Priority: 100 → Action: Allow - 3.3Rule: Name: allow-admin-ssh → Protocol: TCP → Source:
YOUR_PUBLIC_IP/32 - 3.4Destination:
VM_PRIVATE_IP/32→ Ports:22→ Add
RG="rg-lab24-dnat"
# Lấy public IP của máy bạn
MY_IP=$(curl -s ifconfig.me)
echo "My public IP: $MY_IP"
# Lấy VM private IP
VM_PRIVATE_IP=$(az vm show \
--resource-group $RG --name vm-private-lab24 \
--show-details --query privateIps --output tsv)
# Tạo Network Rule Collection cho phép SSH từ IP admin
az network firewall network-rule collection add \
--resource-group $RG \
--firewall-name fw-lab24 \
--collection-name nrc-allow-ssh-admin \
--priority 100 \
--action Allow
az network firewall network-rule add \
--resource-group $RG \
--firewall-name fw-lab24 \
--collection-name nrc-allow-ssh-admin \
--name allow-admin-ssh \
--protocols TCP \
--source-addresses "${MY_IP}/32" \
--destination-addresses "$VM_PRIVATE_IP" \
--destination-ports 22
Tạo DNAT Rule Collection
DNAT rule chuyển đổi: traffic đến Firewall Public IP port 2222 → VM private IP port 22. Port 2222 thay vì 22 để phân biệt nhiều VM sau này.
- 4.1fw-lab24 → Rules (classic) → NAT rule collection → + Add NAT rule collection
- 4.2Name:
dnat-ssh-vm→ Priority: 100 - 4.3Rule name:
dnat-to-vm-ssh→ Protocol: TCP - 4.4Source:
YOUR_PUBLIC_IP/32→ Destination: Firewall Public IP → Dest Ports:2222 - 4.5Translated address:
VM_PRIVATE_IP→ Translated port:22→ Add
RG="rg-lab24-dnat"
# Lấy Public IP của Firewall
FW_PUBLIC_IP=$(az network public-ip show \
--resource-group $RG --name pip-fw-lab24 \
--query ipAddress --output tsv)
VM_PRIVATE_IP=$(az vm show \
--resource-group $RG --name vm-private-lab24 \
--show-details --query privateIps --output tsv)
MY_IP=$(curl -s ifconfig.me)
echo "FW Public IP: $FW_PUBLIC_IP"
echo "VM Private IP: $VM_PRIVATE_IP"
echo "My IP: $MY_IP"
# Tạo DNAT rule collection
az network firewall nat-rule collection add \
--resource-group $RG \
--firewall-name fw-lab24 \
--collection-name dnat-ssh-vm \
--priority 100
# Thêm DNAT rule: FW_PUBLIC_IP:2222 → VM_PRIVATE_IP:22
az network firewall nat-rule add \
--resource-group $RG \
--firewall-name fw-lab24 \
--collection-name dnat-ssh-vm \
--name dnat-to-vm-ssh \
--protocols TCP \
--source-addresses "${MY_IP}/32" \
--destination-addresses "$FW_PUBLIC_IP" \
--destination-ports 2222 \
--translated-address "$VM_PRIVATE_IP" \
--translated-port 22
Kiểm Tra SSH Qua DNAT
SSH tới Firewall Public IP port 2222. Firewall sẽ DNAT forward sang VM private port 22.
# Lấy FW public IP (chạy từ Azure CLI)
FW_PUBLIC_IP=$(az network public-ip show \
--resource-group rg-lab24-dnat --name pip-fw-lab24 \
--query ipAddress --output tsv)
echo "SSH to: $FW_PUBLIC_IP:2222"
# SSH qua DNAT (port 2222 → VM port 22)
ssh -i ~/.ssh/id_rsa \
-p 2222 \
azureuser@$FW_PUBLIC_IP
# Sau khi vào VM, kiểm tra IP nội bộ
hostname -I
# Kết quả: 10.0.2.x → xác nhận đang ở VM private
hostname -I trả về IP 10.0.2.x (private). Nếu SSH từ IP khác (VPN, hotspot) → Connection timeout.
📊 Kết Quả Đầu Ra Lab 24
az vm show → privateIps có giá trị, publicIps rỗng
SSH tới FW_IP:2222 → kết nối thành công tới VM private
Chỉ MY_IP/32 được phép, IP khác bị firewall drop
Xác nhận đang kết nối vào VM trong subnet 10.0.2.0/24
🧹 Dọn Dẹp Tài Nguyên
az group delete --name rg-lab24-dnat --yes --no-wait
❓ Câu Hỏi Ôn Tập
1. DNAT (Destination NAT) hoạt động như thế nào? Khác gì SNAT?
Gợi ý: DNAT đổi destination IP/port trên inbound traffic. SNAT đổi source IP trên outbound traffic. Azure Firewall tự động SNAT egress traffic.
2. Tại sao không dùng trực tiếp port 22 trên firewall mà dùng port 2222?
Gợi ý: Dùng port khác 22 giảm bot scanning, còn có thể map nhiều VM khác nhau (VM2 → 2223:22, VM3 → 2224:22)
3. Tại sao cần tạo cả Network Rule và DNAT Rule? Chỉ DNAT có đủ không?
Gợi ý: DNAT rule xử lý destination translation. Network rule kiểm soát xem traffic có được phép đi tiếp sau DNAT không. Cần cả hai.
4. So sánh bảo mật giữa DNAT qua Firewall và Azure Bastion. Khi nào dùng cái nào?
Gợi ý: Bastion không cần port nào mở, dùng HTTPS/443, không cần SSH key quản lý. DNAT linh hoạt hơn nhưng phức tạp hơn. Production → Bastion. Lab/dev → DNAT hoặc Bastion.