LAB 32 AZ-500 ~45 phút Chương 08 Có phí — xóa sau lab

Azure Bastion — Truy Cập VM Không Cần Public IP

Triển khai Azure Bastion SKU Standard, kết nối RDP/SSH vào VM qua trình duyệt mà không cần expose port 3389/22 ra Internet. Loại bỏ hoàn toàn attack surface từ public endpoint.

Cảnh báo chi phí: Azure Bastion Standard SKU tốn ~$0.19/giờ + $0.10/GB data. Xóa Bastion ngay sau khi hoàn thành lab để tránh phát sinh chi phí liên tục.

🎯 Mục Tiêu Lab

Tạo VNet với subnet AzureBastionSubnet đúng prefix /26

Tạo VM không có public IP, chỉ có private IP

Triển khai Azure Bastion Standard SKU

Kết nối RDP vào VM qua Bastion từ trình duyệt

Xác nhận NSG không cần mở port 3389 từ Internet

Dọn dẹp tài nguyên để tiết kiệm chi phí

📋 Chuẩn Bị

Yêu cầu:
  • Azure subscription với quyền Contributor trở lên
  • Azure CLI phiên bản 2.50+ hoặc truy cập Azure Portal
  • Region: southeastasia (Singapore)
Naming convention:
  • RG: rg-az500-lab32
  • VNet: vnet-az500-bastion
  • VM: vm-az500-lab32
  • Bastion: bastion-az500-lab32

🏗️ Kịch Bản

Doanh nghiệp yêu cầu các VM quản trị không được có public IP. Quản trị viên phải kết nối RDP/SSH qua Azure Bastion — một dịch vụ managed PaaS hoạt động trong subnet riêng của VNet, xác thực qua Azure Portal/Entra ID, truyền tải mã hóa TLS qua port 443. Với SKU Standard, Bastion hỗ trợ native client (az network bastion tunnel), file upload/download và IP-based connection.

🧪 Các Bước Thực Hiện

1

Tạo Resource Group và VNet

Lưu ý: AzureBastionSubnet phải đặt tên chính xác và có prefix tối thiểu /26 (64 địa chỉ).
Cách 1 — Portal
  1. 1.1Portal → Resource Groups → + Create → Name: rg-az500-lab32 → Region: Southeast Asia → Review + Create
  2. 1.2Portal → Virtual Networks → + Create → Name: vnet-az500-bastion → Region: Southeast Asia → Address space: 10.10.0.0/16
  3. 1.3Tab Subnets → Xóa subnet mặc định → Add subnet: Name snet-workload, prefix 10.10.1.0/24
  4. 1.4Thêm subnet thứ hai: Name AzureBastionSubnet (tên chính xác), prefix 10.10.2.0/26 → Review + Create
Cách 2 — Azure CLI
Azure CLI— PowerShell / Bash / Cloud Shell
# Tạo resource group
az group create \
  --name rg-az500-lab32 \
  --location southeastasia \
  --tags "lab=32" "course=az500" "owner=hoatranlab"

# Tạo VNet với hai subnet
az network vnet create \
  --resource-group rg-az500-lab32 \
  --name vnet-az500-bastion \
  --address-prefix 10.10.0.0/16 \
  --subnet-name snet-workload \
  --subnet-prefix 10.10.1.0/24

# Thêm AzureBastionSubnet (tên PHẢI chính xác)
az network vnet subnet create \
  --resource-group rg-az500-lab32 \
  --vnet-name vnet-az500-bastion \
  --name AzureBastionSubnet \
  --address-prefix 10.10.2.0/26
2

Tạo VM Không Có Public IP

Cách 1 — Portal
  1. 2.1Portal → Virtual Machines → + Create → Name: vm-az500-lab32 → Region: Southeast Asia → Image: Windows Server 2022 → Size: Standard_B2s
  2. 2.2Tab Networking → VNet: vnet-az500-bastion → Subnet: snet-workloadPublic IP: None → NIC NSG: Basic
  3. 2.3Ghi nhớ username/password admin → Review + Create → Create
Cách 2 — Azure CLI
Azure CLI— Tạo VM không public IP
# Tạo VM Windows Server 2022 không có public IP
az vm create \
  --resource-group rg-az500-lab32 \
  --name vm-az500-lab32 \
  --image Win2022AzureEditionCore \
  --size Standard_B2s \
  --vnet-name vnet-az500-bastion \
  --subnet snet-workload \
  --public-ip-address "" \
  --nsg-rule NONE \
  --admin-username azureadmin \
  --admin-password "P@ssw0rd!Az500Lab32" \
  --location southeastasia

# Xác nhận VM không có public IP
az vm show \
  --resource-group rg-az500-lab32 \
  --name vm-az500-lab32 \
  --query "networkProfile.networkInterfaces[0].id" -o tsv | xargs az network nic show --ids | \
  grep -E "publicIPAddress|privateIPAddress"
3

Triển Khai Azure Bastion Standard

Cách 1 — Portal
  1. 3.1Portal → Bastions → + Create → RG: rg-az500-lab32 → Name: bastion-az500-lab32
  2. 3.2Region: Southeast Asia → Tier: Standard → VNet: vnet-az500-bastion
  3. 3.3Public IP: Create new → Name: pip-bastion-lab32 → SKU: Standard → Review + Create
  4. 3.4Đợi provisioning ~5-10 phút cho đến khi status = Succeeded
Cách 2 — Azure CLI
Azure CLI— Deploy Bastion Standard SKU
# Tạo Public IP cho Bastion (bắt buộc Standard SKU)
az network public-ip create \
  --resource-group rg-az500-lab32 \
  --name pip-bastion-lab32 \
  --sku Standard \
  --location southeastasia

# Deploy Azure Bastion Standard SKU
az network bastion create \
  --resource-group rg-az500-lab32 \
  --name bastion-az500-lab32 \
  --public-ip-address pip-bastion-lab32 \
  --vnet-name vnet-az500-bastion \
  --location southeastasia \
  --sku Standard \
  --enable-tunneling true

# Kiểm tra trạng thái (đợi provisioningState = Succeeded)
az network bastion show \
  --resource-group rg-az500-lab32 \
  --name bastion-az500-lab32 \
  --query "{name:name, sku:sku.name, state:provisioningState}" -o table
4

Kết Nối RDP Qua Bastion

Cách 1 — Portal (Bastion Browser)
  1. 4.1Portal → Virtual Machines → vm-az500-lab32Connect → Bastion
  2. 4.2Nhập username: azureadmin và password đã đặt ở bước 2
  3. 4.3Click Connect — cửa sổ RDP mở trong trình duyệt (tab mới) qua HTTPS port 443
  4. 4.4Bên trong VM: mở PowerShell → chạy ipconfig → xác nhận chỉ có private IP 10.10.1.x
Cách 2 — Azure CLI (Native Client Tunnel)
Azure CLI— Bastion tunnel cho native RDP client (yêu cầu Standard SKU)
# Lấy VM resource ID
VM_ID=$(az vm show \
  --resource-group rg-az500-lab32 \
  --name vm-az500-lab32 \
  --query id -o tsv)

# Tạo tunnel qua Bastion (chạy terminal riêng, giữ mở)
az network bastion tunnel \
  --name bastion-az500-lab32 \
  --resource-group rg-az500-lab32 \
  --target-resource-id $VM_ID \
  --resource-port 3389 \
  --port 5000

# Trong terminal khác: kết nối bằng mstsc hoặc xfreerdp
# Windows:
mstsc /v:localhost:5000
# Linux/macOS:
xfreerdp /v:localhost:5000 /u:azureadmin
Kết quả đầu ra bước 4: Màn hình RDP của VM hiển thị trong trình duyệt. Chạy ipconfig trong VM → chỉ thấy IP 10.10.1.x, không có public IP nào.
5

Xác Minh VM Không Expose Port Ra Internet

Azure CLI— Kiểm tra NSG và public IP
# Xác nhận NIC không có public IP
NIC_ID=$(az vm show -g rg-az500-lab32 -n vm-az500-lab32 \
  --query "networkProfile.networkInterfaces[0].id" -o tsv)

az network nic show --ids $NIC_ID \
  --query "ipConfigurations[0].{privateIP:privateIPAddress, publicIP:publicIPAddress}" -o table

# Kiểm tra NSG rules — không có rule mở port 3389 từ Internet
NSG_ID=$(az network nic show --ids $NIC_ID \
  --query "networkSecurityGroup.id" -o tsv)
az network nsg show --ids $NSG_ID \
  --query "securityRules[?destinationPortRange=='3389']" -o table

# Dùng Network Watcher IP Flow Verify để xác nhận block
az network watcher test-ip-flow \
  --direction Inbound \
  --protocol TCP \
  --local 10.10.1.4:3389 \
  --remote 1.2.3.4:12345 \
  --vm vm-az500-lab32 \
  --resource-group rg-az500-lab32

📊 Kết Quả Đầu Ra

VNet với AzureBastionSubnet /26

az network vnet subnet list → thấy AzureBastionSubnet với prefix 10.10.2.0/26

VM chỉ có private IP

az network nic show → publicIPAddress: null, privateIPAddress: 10.10.1.x

Bastion Standard provisioned

az network bastion show → provisioningState: Succeeded, sku: Standard

RDP qua Bastion thành công

Màn hình desktop VM hiển thị trong trình duyệt, ipconfig chỉ thấy 10.10.1.x

IP Flow Verify: Blocked

test-ip-flow trả về Access: Deny cho inbound port 3389 từ Internet

🧹 Dọn Dẹp Tài Nguyên

Azure CLI— Xóa toàn bộ tài nguyên lab
# Xóa toàn bộ resource group (bao gồm Bastion, VM, VNet, Public IP)
az group delete \
  --name rg-az500-lab32 \
  --yes \
  --no-wait

# Xác nhận đã xóa
az group show --name rg-az500-lab32 2>&1 || echo "Resource group đã được xóa thành công"

❓ Câu Hỏi Ôn Tập

1. AzureBastionSubnet yêu cầu prefix tối thiểu là gì? Tên subnet có thể tùy ý đặt không?

Gợi ý: /26 (64 địa chỉ). Tên phải là chính xác "AzureBastionSubnet" — không thể đổi tên.

2. Sự khác nhau giữa Bastion Basic và Standard SKU là gì?

Gợi ý: Standard hỗ trợ native client tunneling, file copy, IP-based connection, Kerberos auth, shareable links. Basic chỉ có browser-based RDP/SSH.

3. Bastion sử dụng port nào để truyền dữ liệu? Tại sao điều này thuận lợi hơn mở port 3389?

Gợi ý: Port 443 (HTTPS/TLS). Hầu hết corporate firewall cho phép outbound 443. Port 3389 thường bị chặn và là mục tiêu tấn công brute force.

4. Khi dùng Bastion, VM cần NSG rule inbound cho port 3389 không? Tại sao?

Gợi ý: Không cần. Bastion kết nối đến VM qua private IP nội bộ VNet. Bastion có NSG riêng yêu cầu inbound 443 từ Internet và outbound 3389/22 đến VNet.

5. Trong mô hình Zero Trust, tại sao Bastion được ưa dùng thay cho VPN + Jump Server truyền thống?

Gợi ý: Bastion tích hợp Entra ID authentication, không cần quản lý thêm VM jump server, session được audit, không cần mở port từ Internet, mỗi phiên là TLS riêng biệt.

Lab 31: App Service Access Restriction Thư viện Labs Lab 33: JIT VM Access
Zalo