🎯 Mục Tiêu Lab
Tạo Private Endpoint cho Blob service — NIC riêng với private IP trong VNet
Tạo Private DNS Zone privatelink.blob.core.windows.net
Link Private DNS Zone với VNet để phân giải DNS nội bộ
Tắt hoàn toàn public network access trên Storage Account
Kiểm tra DNS resolution: nslookup trả về private IP 10.x.x.x từ trong VNet
Xác nhận truy cập blob thành công qua private IP, truy cập public bị từ chối
📋 Chuẩn Bị
- Azure subscription đang Active
- Đã có VNet
vnet-az500-privatetừ Lab 28 (hoặc tạo mới) - Quyền Contributor trên resource group
- Azure CLI ≥ 2.50
- Private Endpoint: ~$0.01/giờ (~$7.3/tháng)
- Private DNS Zone: ~$0.5/tháng/zone
- Xóa Private Endpoint ngay sau lab để tiết kiệm
- Private DNS Zone tên cố định:
privatelink.blob.core.windows.net
🏗️ Kịch Bản & Kiến Trúc
Nâng cấp từ Lab 28: thay vì Service Endpoint (traffic qua public backbone), ta tạo Private Endpoint với NIC riêng trong subnet. DNS được override bởi Private DNS Zone để staz500lab29.blob.core.windows.net phân giải về 10.10.3.4 thay vì public IP.
Public: DISABLED
Private IP: 10.10.3.4
.core.windows.net
🧪 Các Bước Thực Hiện
Tạo Storage Account và Subnet cho Private Endpoint
Tạo subnet riêng snet-pe dành cho Private Endpoint (best practice: tách subnet riêng), sau đó tạo Storage Account mới.
1. Virtual networks → vnet-az500-private → Subnets → + Subnet - Name: snet-pe - Address range: 10.10.3.0/24 - (Không cần Service Endpoint cho subnet PE) 2. Storage accounts → + Create Basics: - Name: staz500lab29[random] - Resource group: rg-az500-ch07-private - Region: Southeast Asia Advanced: - Minimum TLS version: TLS 1.2 - Allow Blob anonymous access: Disabled Networking: - Network access: "Disable public access and use private access" (Hoặc chọn "Enable from selected..." rồi tắt sau khi tạo PE) 3. Review + Create → Create
# Thêm subnet cho Private Endpoint (disable network policies — bắt buộc) az network vnet subnet create \ --name snet-pe \ --vnet-name vnet-az500-private \ --resource-group rg-az500-ch07-private \ --address-prefix 10.10.3.0/24 \ --disable-private-endpoint-network-policies true # Tạo Storage Account (public access tắt từ đầu) az storage account create \ --name staz500lab29xk9m \ --resource-group rg-az500-ch07-private \ --location southeastasia \ --sku Standard_LRS \ --min-tls-version TLS1_2 \ --allow-blob-public-access false \ --public-network-access Disabled
Tạo Private Endpoint cho Blob Service
1. Storage account → Networking → Private endpoint connections → + Private endpoint (hoặc Portal → Private endpoints → + Create) Basics: - Name: pe-storage-lab29 - Resource group: rg-az500-ch07-private - Region: Southeast Asia Resource: - Resource type: Microsoft.Storage/storageAccounts - Resource: staz500lab29[random] - Target sub-resource: blob ← chọn blob Virtual Network: - Virtual network: vnet-az500-private - Subnet: snet-pe DNS: - Integrate with private DNS zone: Yes ← QUAN TRỌNG - Private DNS zone: (tự tạo) privatelink.blob.core.windows.net 2. Review + Create → Create Đợi ~2 phút để provisioning hoàn tất
# Lấy Storage Account ID
STORAGE_ID=$(az storage account show \
--name staz500lab29xk9m \
--resource-group rg-az500-ch07-private \
--query id -o tsv)
# Tạo Private Endpoint
az network private-endpoint create \
--name pe-storage-lab29 \
--resource-group rg-az500-ch07-private \
--vnet-name vnet-az500-private \
--subnet snet-pe \
--private-connection-resource-id $STORAGE_ID \
--group-id blob \
--connection-name conn-storage-lab29 \
--location southeastasia
# Xem private IP được gán
az network private-endpoint show \
--name pe-storage-lab29 \
--resource-group rg-az500-ch07-private \
--query "customDnsConfigs[].{FQDN:fqdn, IP:ipAddresses}" \
--output table
FQDN IP ------------------------------------------------ ----------- staz500lab29xk9m.blob.core.windows.net 10.10.3.4
Tạo Private DNS Zone và Link với VNet
Nếu dùng Portal tạo PE ở bước 2 với "Integrate with private DNS zone: Yes" thì DNS Zone đã được tạo tự động. Nếu dùng CLI, tạo thủ công:
# Tạo Private DNS Zone az network private-dns zone create \ --resource-group rg-az500-ch07-private \ --name "privatelink.blob.core.windows.net" # Link DNS Zone với VNet (bắt buộc để VM trong VNet dùng DNS này) az network private-dns link vnet create \ --resource-group rg-az500-ch07-private \ --zone-name "privatelink.blob.core.windows.net" \ --name link-vnet-az500-private \ --virtual-network vnet-az500-private \ --registration-enabled false # Lấy NIC ID của Private Endpoint để tìm private IP NIC_ID=$(az network private-endpoint show \ --name pe-storage-lab29 \ --resource-group rg-az500-ch07-private \ --query "networkInterfaces[0].id" -o tsv) PRIVATE_IP=$(az network nic show --ids $NIC_ID \ --query "ipConfigurations[0].privateIPAddress" -o tsv) # Tạo A record trong DNS Zone az network private-dns record-set a add-record \ --resource-group rg-az500-ch07-private \ --zone-name "privatelink.blob.core.windows.net" \ --record-set-name staz500lab29xk9m \ --ipv4-address $PRIVATE_IP echo "Private IP: $PRIVATE_IP"
1. Portal → Private DNS zones → privatelink.blob.core.windows.net 2. Overview → xem Record sets: có A record trỏ về 10.10.3.4 3. Virtual network links → thấy vnet-az500-private với Status: Completed 4. Storage account → Networking → Private endpoint connections → pe-storage-lab29: Connection state = Approved
Tắt Public Network Access
1. Storage account → Networking → Firewalls and virtual networks 2. Public network access: "Disabled" 3. Save
# Tắt public network access hoàn toàn
az storage account update \
--name staz500lab29xk9m \
--resource-group rg-az500-ch07-private \
--public-network-access Disabled
# Xác nhận
az storage account show \
--name staz500lab29xk9m \
--resource-group rg-az500-ch07-private \
--query "{publicNetworkAccess:publicNetworkAccess, minimumTlsVersion:minimumTlsVersion}" \
--output table
PublicNetworkAccess MinimumTlsVersion --------------------- ----------------- Disabled TLS1_2
Kiểm Tra DNS Resolution và Truy Cập Blob
SSH vào VM trong VNet (tạo VM test trong snet-app hoặc snet-pe), kiểm tra DNS và truy cập blob.
# SSH vào VM trong VNet ssh azureuser@<public-ip-vm> # Kiểm tra DNS phân giải về private IP nslookup staz500lab29xk9m.blob.core.windows.net # Expected output: # Server: 168.63.129.16 (Azure DNS) # Non-authoritative answer: # Name: staz500lab29xk9m.privatelink.blob.core.windows.net # Address: 10.10.3.4 ← PRIVATE IP! # Cài azure-cli curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash az login --use-device-code # Upload file qua private endpoint echo "Lab 29 private endpoint test" > /tmp/test29.txt az storage blob upload \ --account-name staz500lab29xk9m \ --container-name lab29-container \ --name test29.txt \ --file /tmp/test29.txt \ --auth-mode login # Kết quả: Finished[#############] 100% # Kiểm tra từ ngoài VNet (máy local) — phải bị từ chối # nslookup sẽ trả về public IP → nhưng storage từ chối vì public access Disabled
staz500lab29xk9m.blob.core.windows.net — trong VNet phân giải về 10.10.3.4, ngoài VNet phân giải về public IP. Đây là split-horizon DNS hoạt động nhờ Private DNS Zone chỉ linked với VNet cụ thể.
📊 Kết Quả Đầu Ra Lab 29
pe-storage-lab29 có NIC với IP 10.10.3.4, Connection state: Approved
privatelink.blob.core.windows.net có A record → 10.10.3.4, linked với VNet
nslookup trong VM trả về 10.10.3.4 (private IP)
publicNetworkAccess: Disabled — không ai truy cập qua public được
az storage blob upload qua private endpoint trả về 100%
Chuẩn Azure 2026: minimumTlsVersion: TLS1_2, allowBlobPublicAccess: false
🧹 Dọn Dẹp Tài Nguyên
# Xóa Private Endpoint (tốn phí) az network private-endpoint delete \ --name pe-storage-lab29 \ --resource-group rg-az500-ch07-private --yes # Xóa Private DNS Zone (tốn phí nhỏ) az network private-dns zone delete \ --resource-group rg-az500-ch07-private \ --name "privatelink.blob.core.windows.net" --yes # Xóa VM nếu không cần az vm delete --resource-group rg-az500-ch07-private --name vm-app --yes --no-wait # Xóa toàn bộ nếu không làm Lab 30 # az group delete --name rg-az500-ch07-private --yes --no-wait
❓ Câu Hỏi Ôn Tập
1. Tên Private DNS Zone cho Blob Storage là gì? Tại sao tên này cố định?
Gợi ý: privatelink.blob.core.windows.net. Azure quy định mỗi service có tên zone cố định để client override DNS tự động. Danh sách đầy đủ tại docs.microsoft.com/azure/private-link/private-endpoint-dns.
2. Tại sao phải set --disable-private-endpoint-network-policies true trên subnet?
Gợi ý: Network policies (NSG, UDR) không áp dụng được cho NIC của Private Endpoint theo thiết kế. Phải disable mới tạo được PE trong subnet đó.
3. Nếu không tạo Private DNS Zone, điều gì xảy ra khi VM trong VNet nslookup storage?
Gợi ý: DNS phân giải về public IP. Nếu public access disabled → connection refused. Nếu public access còn → kết nối đi qua public, không qua Private Endpoint — mất đi mục đích bảo mật.
4. Hybrid scenario: VM on-premises kết nối qua VPN đến VNet. Có dùng được Private Endpoint Storage này không?
Gợi ý: Có, nhưng phải cấu hình DNS forwarder on-premises để forward query *.blob.core.windows.net về Azure DNS 168.63.129.16. Đây là lý do Private Endpoint vượt trội hơn Service Endpoint cho hybrid.
5. Một Storage Account có thể có bao nhiêu Private Endpoint? Có thể tạo PE cho File và Blob riêng biệt không?
Gợi ý: Có thể nhiều PE, mỗi PE cho một sub-resource (blob, file, queue, table, web, dfs). Mỗi sub-resource cần Private DNS Zone riêng: privatelink.file.core.windows.net cho File.