🎯 Mục Tiêu Lab
Tạo VNet, subnet và VM Ubuntu tại Southeast Asia
Tạo NSG với inbound rule cho phép SSH từ IP quản trị duy nhất
Thêm rule chặn toàn bộ inbound traffic khác (DenyAll)
Gán NSG vào subnet và kiểm tra effective security rules
Dùng IP Flow Verify (Network Watcher) để xác nhận traffic allowed/denied
Dọn dẹp resource sau lab để tránh phát sinh chi phí
📋 Chuẩn Bị
- Azure subscription với quyền Contributor trở lên
- Azure CLI phiên bản 2.50+ hoặc Azure Portal
- Biết IP public của máy quản trị (
curl ifconfig.me) - Network Watcher được bật ở region southeastasia
- Resource group:
rg-az500-nsg-lab19 - VNet:
vnet-az500-lab19(10.19.0.0/16) - NSG:
nsg-az500-lab19 - VM:
vm-az500-lab19(Ubuntu 22.04)
🏗️ Kịch Bản
Bạn là Azure Security Engineer của HoaTranLab. Nhóm dev vừa triển khai VM Ubuntu để host ứng dụng nội bộ. Yêu cầu bảo mật: chỉ admin (IP cố định) được SSH vào VM; toàn bộ traffic khác phải bị chặn. Sau khi cấu hình NSG, dùng Network Watcher / IP Flow Verify để xác minh rule hoạt động đúng.
🧪 Các Bước Thực Hiện
Tạo Resource Group, VNet và Subnet
- 1.1Portal → Resource groups → + Create → Name:
rg-az500-nsg-lab19, Region: Southeast Asia → Review + Create - 1.2Portal → Virtual networks → + Create → Resource group:
rg-az500-nsg-lab19, Name:vnet-az500-lab19, Region: Southeast Asia - 1.3Tab IP Addresses → Address space:
10.19.0.0/16→ Add subnet: Namesnet-app, Range10.19.1.0/24→ Review + Create
# Tạo resource group
az group create \
--name rg-az500-nsg-lab19 \
--location southeastasia \
--tags "owner=hoatranlab" "env=lab" "module=az500-ch05"
# Tạo VNet với subnet
az network vnet create \
--resource-group rg-az500-nsg-lab19 \
--name vnet-az500-lab19 \
--address-prefix 10.19.0.0/16 \
--subnet-name snet-app \
--subnet-prefix 10.19.1.0/24 \
--location southeastasia
Tạo NSG và Cấu Hình Security Rules
- 2.1Portal → Network security groups → + Create → RG:
rg-az500-nsg-lab19, Name:nsg-az500-lab19, Region: Southeast Asia → Create - 2.2Vào NSG → Inbound security rules → + Add: Source: IP Addresses, Source IP: YOUR_ADMIN_IP/32, Port: 22, Protocol: TCP, Action: Allow, Priority: 100, Name:
Allow-SSH-Admin - 2.3Thêm rule thứ 2: Source: Any, Port: *, Protocol: Any, Action: Deny, Priority: 4000, Name:
Deny-All-Inbound - 2.4Vào NSG → Subnets → Associate → chọn
vnet-az500-lab19 / snet-app
# Lấy IP public của máy bạn
MY_IP=$(curl -s ifconfig.me)
echo "Admin IP: $MY_IP"
# Tạo NSG
az network nsg create \
--resource-group rg-az500-nsg-lab19 \
--name nsg-az500-lab19 \
--location southeastasia
# Rule 1: Cho phép SSH từ IP admin
az network nsg rule create \
--resource-group rg-az500-nsg-lab19 \
--nsg-name nsg-az500-lab19 \
--name Allow-SSH-Admin \
--priority 100 \
--direction Inbound \
--access Allow \
--protocol Tcp \
--source-address-prefixes "$MY_IP/32" \
--source-port-ranges "*" \
--destination-port-ranges 22 \
--description "Cho phep SSH tu IP quan tri"
# Rule 2: Chặn toàn bộ inbound khác
az network nsg rule create \
--resource-group rg-az500-nsg-lab19 \
--nsg-name nsg-az500-lab19 \
--name Deny-All-Inbound \
--priority 4000 \
--direction Inbound \
--access Deny \
--protocol "*" \
--source-address-prefixes "*" \
--source-port-ranges "*" \
--destination-port-ranges "*" \
--description "Chan tat ca inbound khac"
# Gán NSG vào subnet
az network vnet subnet update \
--resource-group rg-az500-nsg-lab19 \
--vnet-name vnet-az500-lab19 \
--name snet-app \
--network-security-group nsg-az500-lab19
# Kiểm tra effective rules
az network nsg show \
--resource-group rg-az500-nsg-lab19 \
--name nsg-az500-lab19 \
--query "securityRules[].{Name:name,Priority:priority,Direction:direction,Access:access,Port:destinationPortRange}" \
--output table
Tạo VM và Gán Public IP Standard SKU
- 3.1Portal → Virtual machines → + Create → RG:
rg-az500-nsg-lab19, Name:vm-az500-lab19, Region: Southeast Asia, Image: Ubuntu Server 22.04 LTS - 3.2Size: Standard_B1s → Authentication: SSH public key → Username:
azureadmin - 3.3Tab Networking → VNet:
vnet-az500-lab19, Subnet:snet-app, Public IP SKU: Standard, NIC NSG: None (đã có NSG ở subnet) - 3.4Review + Create → Create
# Tạo Public IP với SKU Standard (bắt buộc từ 2025)
az network public-ip create \
--resource-group rg-az500-nsg-lab19 \
--name pip-vm-az500-lab19 \
--sku Standard \
--allocation-method Static \
--location southeastasia
# Tạo NIC gắn vào subnet (không gán NSG ở NIC — đã có ở subnet)
az network nic create \
--resource-group rg-az500-nsg-lab19 \
--name nic-vm-az500-lab19 \
--vnet-name vnet-az500-lab19 \
--subnet snet-app \
--public-ip-address pip-vm-az500-lab19
# Tạo VM Ubuntu 22.04
az vm create \
--resource-group rg-az500-nsg-lab19 \
--name vm-az500-lab19 \
--nics nic-vm-az500-lab19 \
--image Ubuntu2204 \
--size Standard_B1s \
--admin-username azureadmin \
--generate-ssh-keys \
--location southeastasia \
--no-wait
# Lấy Public IP của VM
az network public-ip show \
--resource-group rg-az500-nsg-lab19 \
--name pip-vm-az500-lab19 \
--query ipAddress -o tsv
Kiểm Tra Bằng IP Flow Verify (Network Watcher)
- 4.1Portal → Network Watcher → IP flow verify
- 4.2VM:
vm-az500-lab19, NIC: chọn NIC của VM, Direction: Inbound - 4.3Test 1 (ALLOW): Local port: 22, Remote: YOUR_ADMIN_IP → Check → Kết quả: Access allowed, Rule:
Allow-SSH-Admin - 4.4Test 2 (DENY): Local port: 22, Remote:
1.2.3.4→ Check → Kết quả: Access denied, Rule:Deny-All-Inbound
MY_IP=$(curl -s ifconfig.me)
VM_ID=$(az vm show --resource-group rg-az500-nsg-lab19 --name vm-az500-lab19 --query id -o tsv)
NIC_ID=$(az vm show --resource-group rg-az500-nsg-lab19 --name vm-az500-lab19 --query "networkProfile.networkInterfaces[0].id" -o tsv)
# Test 1: IP admin -> port 22 (expect: Allow)
az network watcher test-ip-flow \
--resource-group rg-az500-nsg-lab19 \
--vm vm-az500-lab19 \
--direction Inbound \
--protocol TCP \
--local "10.19.1.4:22" \
--remote "$MY_IP:*"
# Test 2: IP lạ -> port 22 (expect: Deny)
az network watcher test-ip-flow \
--resource-group rg-az500-nsg-lab19 \
--vm vm-az500-lab19 \
--direction Inbound \
--protocol TCP \
--local "10.19.1.4:22" \
--remote "1.2.3.4:*"
# Test 1 (Allow):
{
"access": "Allow",
"ruleName": "Allow-SSH-Admin"
}
# Test 2 (Deny):
{
"access": "Deny",
"ruleName": "Deny-All-Inbound"
}
📊 Kết Quả Đầu Ra
2 inbound rules: Allow-SSH-Admin (priority 100) và Deny-All-Inbound (priority 4000)
snet-app của vnet-az500-lab19 có NSG được liên kết
Từ MY_IP → port 22: Access = Allow, Rule = Allow-SSH-Admin
Từ IP lạ → port 22: Access = Deny, Rule = Deny-All-Inbound
🧹 Dọn Dẹp Tài Nguyên
az group delete \
--name rg-az500-nsg-lab19 \
--yes \
--no-wait
echo "Resource group dang xoa, kiem tra trang thai:"
az group show --name rg-az500-nsg-lab19 --query properties.provisioningState -o tsv 2>/dev/null || echo "Da xoa thanh cong"
❓ Câu Hỏi Ôn Tập
1. NSG có thể gán ở hai cấp độ nào? Khi cả hai đều tồn tại, traffic cần pass cả hai không?
Gợi ý: Subnet-level và NIC-level. Traffic inbound pass subnet NSG trước → NIC NSG sau. Outbound ngược lại.
2. Priority trong NSG rules hoạt động thế nào? Số nhỏ hay lớn được ưu tiên hơn?
Gợi ý: Số nhỏ = ưu tiên cao hơn. Hợp lệ từ 100–4096. Rule trùng priority sẽ báo lỗi.
3. Service Tag trong NSG là gì? Cho ví dụ 2 service tag thường dùng và mục đích.
Gợi ý: Group IP tự quản lý bởi Microsoft. VD: AzureLoadBalancer (health probe), Internet (toàn bộ IP internet).
4. Tại sao nên dùng Public IP SKU Standard thay vì Basic từ 2025?
Gợi ý: Basic bị retire tháng 9/2025. Standard hỗ trợ zone-redundancy, bảo mật mặc định cao hơn (closed by default), bắt buộc cho Load Balancer Standard.
5. IP Flow Verify trong Network Watcher kiểm tra điều gì? Khác gì với Connection Troubleshoot?
Gợi ý: IP Flow Verify kiểm tra NSG rule xem traffic cụ thể được allow/deny bởi rule nào. Connection Troubleshoot kiểm tra kết nối end-to-end thực tế (cần agent).