AZ-500 · LAB 28 ~45 phút Chương 07 Private Access Security Trung bình

Cấu Hình Service Endpoint cho Storage Account

Bật Service Endpoint Microsoft.Storage trên subnet, cấu hình Storage Account firewall chỉ cho phép subnet được chỉ định. Hiểu rõ sự khác biệt giữa Service Endpoint và Private Endpoint — hai cơ chế bảo vệ PaaS quan trọng trong AZ-500.

🎯 Mục Tiêu Lab

Tạo VNet với subnet và bật Service Endpoint Microsoft.Storage

Tạo Storage Account với TLS 1.2 và cấu hình firewall chỉ cho phép subnet

Kiểm tra truy cập từ VM trong subnet được phép và VM ngoài subnet bị từ chối

Hiểu traffic vẫn đi qua public IP của Storage — backbone Microsoft

Phân biệt Service Endpoint vs Private Endpoint: use case, chi phí, DNS

Áp dụng chuẩn 2026: tắt anonymous access, bật minimum TLS 1.2

📋 Chuẩn Bị

Yêu cầu:
  • Azure subscription đang Active
  • Quyền Contributor hoặc Owner trên resource group
  • Azure CLI đã cài đặt (az version ≥ 2.50)
  • Đã hoàn thành Lab 22 (NSG Flow Logs) hoặc nắm cơ bản VNet/NSG
Lưu ý:
  • Service Endpoint KHÔNG tạo private IP — traffic vẫn đi qua public endpoint
  • Service Endpoint Policy (SEP) để giới hạn đến storage account cụ thể
  • Region: southeastasia
  • Xóa resource sau lab để tránh phát sinh chi phí VM

🏗️ Kịch Bản

Doanh nghiệp có subnet ứng dụng (snet-app) chứa VM backend. Yêu cầu bảo mật: Storage Account chỉ truy cập được từ subnet này, không cho phép truy cập từ Internet hoặc các subnet khác. Dùng Service Endpoint vì chi phí thấp và triển khai nhanh — đủ dùng khi không cần private IP hoàn toàn.

Resource Group
rg-az500-ch07-private
VNet
vnet-az500-private
10.10.0.0/16
Subnet App
snet-app
10.10.1.0/24
Storage
staz500lab28<random>
TLS 1.2, no public

So Sánh: Service Endpoint vs Private Endpoint

Tiêu chí Service Endpoint Private Endpoint
IP endpoint Public IP (vẫn là *.blob.core.windows.net) Private IP trong VNet (NIC riêng)
DNS thay đổi Không — DNS giữ nguyên public Có — cần Private DNS Zone
Chi phí Miễn phí Có phí (~$7.3/tháng + data)
On-premises Không hỗ trợ Hỗ trợ qua VPN/ExpressRoute
Tắt public access Không bắt buộc (firewall restrict) Nên tắt hoàn toàn
Khi nào dùng Đơn giản, nhanh, VNet cùng region Bảo mật cao, hybrid, cross-region

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

1

Tạo Resource Group, VNet và Subnet

Tạo hạ tầng mạng cơ bản: VNet 10.10.0.0/16, subnet ứng dụng 10.10.1.0/24, subnet test 10.10.2.0/24 (để kiểm tra truy cập bị từ chối).

Cách 1 — Azure Portal
1. Portal → Resource groups → + Create
   - Name: rg-az500-ch07-private
   - Region: Southeast Asia
   - Tags: course=az500, chapter=ch07

2. Portal → Virtual networks → + Create
   - Name: vnet-az500-private
   - Resource group: rg-az500-ch07-private
   - Region: Southeast Asia
   - IPv4 address space: 10.10.0.0/16

3. Tab "Subnets" → Add subnet:
   Subnet 1:
   - Name: snet-app
   - Address range: 10.10.1.0/24
   - Services (Service Endpoint): Microsoft.Storage ← BẬT TẠI ĐÂY
   Subnet 2:
   - Name: snet-test
   - Address range: 10.10.2.0/24
   - Services: (để trống — không có Service Endpoint)

4. Review + Create → Create
Cách 2 — Azure CLI
# Tạo resource group
az group create \
  --name rg-az500-ch07-private \
  --location southeastasia \
  --tags "course=az500" "chapter=ch07" "owner=hoatranlab"

# Tạo VNet
az network vnet create \
  --name vnet-az500-private \
  --resource-group rg-az500-ch07-private \
  --location southeastasia \
  --address-prefix 10.10.0.0/16

# Tạo snet-app với Service Endpoint Microsoft.Storage
az network vnet subnet create \
  --name snet-app \
  --vnet-name vnet-az500-private \
  --resource-group rg-az500-ch07-private \
  --address-prefix 10.10.1.0/24 \
  --service-endpoints Microsoft.Storage

# Tạo snet-test không có Service Endpoint
az network vnet subnet create \
  --name snet-test \
  --vnet-name vnet-az500-private \
  --resource-group rg-az500-ch07-private \
  --address-prefix 10.10.2.0/24

# Xác nhận subnet và service endpoint
az network vnet subnet show \
  --name snet-app \
  --vnet-name vnet-az500-private \
  --resource-group rg-az500-ch07-private \
  --query "serviceEndpoints"
Kết quả (Output)
[
  {
    "locations": ["southeastasia"],
    "provisioningState": "Succeeded",
    "service": "Microsoft.Storage"
  }
]
2

Tạo Storage Account với TLS 1.2 và Cấu Hình Firewall

Tạo Storage Account theo chuẩn 2026: tắt anonymous access, bật TLS 1.2 tối thiểu, cấu hình network firewall chỉ cho phép snet-app.

Cách 1 — Azure Portal
1. Portal → Storage accounts → + Create
   Basics:
   - Resource group: rg-az500-ch07-private
   - Storage account name: staz500lab28[4-ký-tự-random] (ví dụ: staz500lab28xk9m)
   - Region: Southeast Asia
   - Performance: Standard
   - Redundancy: LRS

   Advanced:
   - Minimum TLS version: TLS 1.2 ← BẮT BUỘC
   - Allow Blob anonymous access: DISABLED ← BẮT BUỘC

   Networking:
   - Network access: "Enable from selected virtual networks and IP addresses"
   - Virtual networks → + Add existing virtual network:
     VNet: vnet-az500-private
     Subnet: snet-app ← CHỈ subnet này

2. Review + Create → Create
Cách 2 — Azure CLI
# Lấy subnet ID
SUBNET_ID=$(az network vnet subnet show \
  --name snet-app \
  --vnet-name vnet-az500-private \
  --resource-group rg-az500-ch07-private \
  --query id -o tsv)

# Tạo Storage Account với network rule
az storage account create \
  --name staz500lab28xk9m \
  --resource-group rg-az500-ch07-private \
  --location southeastasia \
  --sku Standard_LRS \
  --min-tls-version TLS1_2 \
  --allow-blob-public-access false \
  --default-action Deny \
  --bypass AzureServices

# Thêm subnet rule cho snet-app
az storage account network-rule add \
  --account-name staz500lab28xk9m \
  --resource-group rg-az500-ch07-private \
  --subnet $SUBNET_ID

# Xác nhận network rules
az storage account show \
  --name staz500lab28xk9m \
  --resource-group rg-az500-ch07-private \
  --query "networkRuleSet" \
  --output json
Kết quả (Output)
{
  "bypass": "AzureServices",
  "defaultAction": "Deny",
  "ipRules": [],
  "virtualNetworkRules": [
    {
      "action": "Allow",
      "state": "Succeeded",
      "virtualNetworkResourceId": "/subscriptions/.../snet-app"
    }
  ]
}
3

Tạo VM Kiểm Tra trong Cả Hai Subnet

Tạo 2 VM: vm-app trong snet-app (được phép) và vm-test trong snet-test (bị từ chối).

Cách 2 — Azure CLI
# VM trong snet-app (có Service Endpoint — được phép truy cập storage)
az vm create \
  --resource-group rg-az500-ch07-private \
  --name vm-app \
  --image Ubuntu2204 \
  --size Standard_B1s \
  --vnet-name vnet-az500-private \
  --subnet snet-app \
  --public-ip-sku Standard \
  --admin-username azureuser \
  --generate-ssh-keys \
  --no-wait

# VM trong snet-test (KHÔNG có Service Endpoint — bị từ chối)
az vm create \
  --resource-group rg-az500-ch07-private \
  --name vm-test \
  --image Ubuntu2204 \
  --size Standard_B1s \
  --vnet-name vnet-az500-private \
  --subnet snet-test \
  --public-ip-sku Standard \
  --admin-username azureuser \
  --generate-ssh-keys
4

Tạo Blob Container và Upload File Test

Cách 1 — Azure Portal
1. Storage account → Containers → + Container
   - Name: lab28-container
   - Public access: Private

2. Vào container → Upload → chọn file bất kỳ (vd: test.txt)

3. Ghi lại URL: https://staz500lab28xk9m.blob.core.windows.net/lab28-container/test.txt
Cách 2 — Azure CLI
# Lấy connection string (chạy từ máy local hoặc Cloud Shell)
CONN=$(az storage account show-connection-string \
  --name staz500lab28xk9m \
  --resource-group rg-az500-ch07-private \
  --query connectionString -o tsv)

# Tạo container
az storage container create \
  --name lab28-container \
  --connection-string "$CONN" \
  --public-access off

# Upload file test
echo "Hello from AZ-500 Lab 28" > /tmp/test.txt
az storage blob upload \
  --container-name lab28-container \
  --name test.txt \
  --file /tmp/test.txt \
  --connection-string "$CONN"
5

Kiểm Tra Truy Cập Từ Hai VM

Kiểm tra: vm-app (snet-app có Service Endpoint) được phép; vm-test (snet-test không có Service Endpoint) bị từ chối 403.

Kiểm tra từ vm-app (được phép)
# SSH vào vm-app
ssh azureuser@<public-ip-vm-app>

# Cài azure-cli trên Ubuntu
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash

# Đăng nhập (dùng device code)
az login --use-device-code

# List blob từ snet-app — KẾT QUẢ: thành công
az storage blob list \
  --account-name staz500lab28xk9m \
  --container-name lab28-container \
  --output table \
  --auth-mode login
Kiểm tra từ vm-test (bị từ chối)
# SSH vào vm-test
ssh azureuser@<public-ip-vm-test>

# Thử truy cập blob — KẾT QUẢ: 403 AuthorizationFailure
curl -I https://staz500lab28xk9m.blob.core.windows.net/lab28-container/test.txt
# HTTP/1.1 403 This request is not authorized to perform this operation.

# Nguyên nhân: snet-test không có Service Endpoint,
# request đi qua public internet → bị Deny theo default-action
Giải thích kỹ thuật: Service Endpoint cho phép traffic từ snet-app đi thẳng lên backbone Microsoft và được nhận diện bởi Storage firewall. vm-test không có Service Endpoint — traffic xuất ra Internet public rồi gặp firewall Deny.

📊 Kết Quả Đầu Ra Lab 28

Service Endpoint bật thành công

snet-app có service endpoint Microsoft.Storage → state: Succeeded

Storage firewall cấu hình đúng

defaultAction: Deny, chỉ snet-app trong virtualNetworkRules

vm-app truy cập được blob

az storage blob list từ snet-app trả về danh sách thành công

vm-test bị từ chối 403

curl từ snet-test → HTTP 403 AuthorizationFailure

TLS 1.2 bắt buộc

minimumTlsVersion: TLS1_2 — chuẩn Azure 2026

Anonymous access tắt

allowBlobPublicAccess: false — không ai đọc public được

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

Giữ lại VNet và subnet nếu tiếp tục Lab 29. Xóa VM để tránh chi phí.

Azure CLI
# Xóa VM để tránh chi phí (giữ VNet và Storage cho Lab 29)
az vm delete --resource-group rg-az500-ch07-private --name vm-app --yes --no-wait
az vm delete --resource-group rg-az500-ch07-private --name vm-test --yes --no-wait

# Xóa public IPs và NICs liên quan
az network public-ip list \
  --resource-group rg-az500-ch07-private \
  --query "[].name" -o tsv | \
  xargs -I {} az network public-ip delete \
    --resource-group rg-az500-ch07-private --name {}

# Xóa toàn bộ nếu không cần tiếp tục
# az group delete --name rg-az500-ch07-private --yes --no-wait

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

1. Service Endpoint cho Storage tạo ra private IP trong VNet không? Traffic đi qua đâu?

Gợi ý: Không có private IP. Traffic vẫn dùng public IP của Storage nhưng đi qua backbone Microsoft (không ra internet public). Storage firewall nhận diện nguồn là subnet được trust.

2. Tại sao VM trong snet-test nhận 403 dù đã đăng nhập đúng Azure credential?

Gợi ý: 403 từ Storage firewall network rule, không phải lỗi authentication. snet-test không có Service Endpoint → request đến từ public internet → defaultAction: Deny.

3. Service Endpoint Policy (SEP) là gì? Khi nào cần dùng thêm SEP?

Gợi ý: SEP giới hạn traffic qua Service Endpoint chỉ đến storage account cụ thể (không phải toàn bộ Microsoft.Storage). Dùng khi muốn ngăn exfiltration sang storage account khác.

4. Cần thêm điều kiện gì để VM on-premises truy cập được Storage Account này?

Gợi ý: Service Endpoint không hỗ trợ on-premises. Phải dùng Private Endpoint (Lab 29) kết hợp với VPN/ExpressRoute, hoặc thêm IP rule trong Storage firewall.

5. Tham số --bypass AzureServices có ý nghĩa gì trong network rule Storage?

Gợi ý: Cho phép một số dịch vụ Azure trusted (như Azure Backup, Azure Monitor) truy cập storage dù defaultAction là Deny. Không ảnh hưởng đến traffic từ VNet.

Lab 27: WAF Policy Thư viện Labs Lab 29: Private Endpoint Storage
Zalo