🎯 Mục Tiêu Lab
Tạo Azure SQL Server với Microsoft Entra admin (không dùng SQL auth thuần)
Tạo Private Endpoint cho SQL Server — sub-resource: sqlServer
Cấu hình Private DNS Zone privatelink.database.windows.net
Tắt public network access trên SQL Server
Kết nối SQL từ VM trong VNet bằng sqlcmd qua private IP 10.x.x.x
Xác nhận kết nối từ ngoài VNet bị từ chối (port 1433 không expose)
📋 Chuẩn Bị
- Azure subscription Active
- VNet
vnet-az500-privatetừ Lab 28/29 - Quyền Contributor trên resource group
- Azure CLI ≥ 2.50
- Azure SQL (General Purpose, 2 vCore): ~$0.18/giờ — xóa ngay sau lab!
- Private Endpoint SQL: ~$0.01/giờ
- Private DNS Zone SQL cố định:
privatelink.database.windows.net - SQL Server name phải unique globally: dùng suffix random
🏗️ Kịch Bản
Ứng dụng web backend cần kết nối Azure SQL Database. Yêu cầu bảo mật: SQL Server không expose port 1433 ra Internet. Kết nối chỉ cho phép từ trong VNet qua private IP. Microsoft Entra ID làm authentication — không lưu SQL password.
🧪 Các Bước Thực Hiện
Tạo Azure SQL Server và Database
Tạo SQL Server với Microsoft Entra admin, tắt public access ngay từ đầu. Tạo database nhỏ (Basic hoặc Serverless) để tiết kiệm chi phí lab.
1. Portal → SQL servers → + Create Basics: - Resource group: rg-az500-ch07-private - Server name: sql-az500-lab30-[random] (phải unique globally) - Region: Southeast Asia - Authentication: Use Microsoft Entra-only authentication - Set Microsoft Entra admin: chọn tài khoản của bạn Networking: - Connectivity method: No access (Private endpoint only) - Allow Azure services: No - Connection policy: Default Review + Create → Create 2. Sau khi server tạo xong → + New database - Database name: db-az500-lab30 - Compute+storage: Serverless, General Purpose, 1 vCore - Backup redundancy: Locally redundant (tiết kiệm chi phí lab) → Create
# Lấy user principal ID (để set Entra admin) USER_OID=$(az ad signed-in-user show --query id -o tsv) USER_EMAIL=$(az ad signed-in-user show --query userPrincipalName -o tsv) # Tạo SQL Server (no public access, Entra-only auth) az sql server create \ --name sql-az500-lab30-xk9m \ --resource-group rg-az500-ch07-private \ --location southeastasia \ --enable-ad-only-auth \ --external-admin-principal-type User \ --external-admin-name $USER_EMAIL \ --external-admin-sid $USER_OID # Tắt public access hoàn toàn az sql server update \ --name sql-az500-lab30-xk9m \ --resource-group rg-az500-ch07-private \ --set publicNetworkAccess=Disabled # Tạo database (Serverless, tiết kiệm chi phí) az sql db create \ --server sql-az500-lab30-xk9m \ --resource-group rg-az500-ch07-private \ --name db-az500-lab30 \ --edition GeneralPurpose \ --family Gen5 \ --capacity 1 \ --compute-model Serverless \ --backup-storage-redundancy Local
{
"fullyQualifiedDomainName": "sql-az500-lab30-xk9m.database.windows.net",
"name": "sql-az500-lab30-xk9m",
"publicNetworkAccess": "Disabled",
"state": "Ready"
}
Tạo Private Endpoint cho SQL Server
1. SQL server → Networking → Private endpoint connections → + Private endpoint Basics: - Name: pe-sql-lab30 - Resource group: rg-az500-ch07-private - Region: Southeast Asia Resource: - Resource type: Microsoft.Sql/servers - Resource: sql-az500-lab30-[random] - Target sub-resource: sqlServer ← chọn sqlServer Virtual Network: - Virtual network: vnet-az500-private - Subnet: snet-pe (subnet private endpoint) DNS: - Integrate with private DNS zone: Yes - Private DNS zone: (tự tạo) privatelink.database.windows.net 2. Review + Create → Create Đợi ~3 phút provisioning
# Lấy SQL Server ID SQL_ID=$(az sql server show \ --name sql-az500-lab30-xk9m \ --resource-group rg-az500-ch07-private \ --query id -o tsv) # Tạo Private Endpoint cho SQL Server az network private-endpoint create \ --name pe-sql-lab30 \ --resource-group rg-az500-ch07-private \ --vnet-name vnet-az500-private \ --subnet snet-pe \ --private-connection-resource-id $SQL_ID \ --group-id sqlServer \ --connection-name conn-sql-lab30 \ --location southeastasia # Tạo Private DNS Zone cho SQL az network private-dns zone create \ --resource-group rg-az500-ch07-private \ --name "privatelink.database.windows.net" # Link DNS Zone với VNet az network private-dns link vnet create \ --resource-group rg-az500-ch07-private \ --zone-name "privatelink.database.windows.net" \ --name link-vnet-sql \ --virtual-network vnet-az500-private \ --registration-enabled false # Lấy private IP của PE và tạo A record NIC_ID=$(az network private-endpoint show \ --name pe-sql-lab30 \ --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) az network private-dns record-set a add-record \ --resource-group rg-az500-ch07-private \ --zone-name "privatelink.database.windows.net" \ --record-set-name "sql-az500-lab30-xk9m" \ --ipv4-address $PRIVATE_IP echo "SQL Private IP: $PRIVATE_IP"
SQL Private IP: 10.10.3.5 # Xác nhận DNS record az network private-dns record-set a list \ --resource-group rg-az500-ch07-private \ --zone-name "privatelink.database.windows.net" \ --output table Name TTL Type Records ------------------------ --- ------ --------- sql-az500-lab30-xk9m 10 A 10.10.3.5
Tạo VM và Kiểm Tra Kết Nối SQL từ VNet
Tạo VM Ubuntu trong VNet, cài sqlcmd, kiểm tra DNS và kết nối SQL Server qua private endpoint.
# Tạo VM trong snet-app để test az vm create \ --resource-group rg-az500-ch07-private \ --name vm-sqltest \ --image Ubuntu2204 \ --size Standard_B1s \ --vnet-name vnet-az500-private \ --subnet snet-app \ --public-ip-sku Standard \ --admin-username azureuser \ --generate-ssh-keys # Lấy public IP để SSH az vm show \ --resource-group rg-az500-ch07-private \ --name vm-sqltest \ --show-details \ --query publicIps -o tsv
# SSH vào VM ssh azureuser@<public-ip-vm-sqltest> # Kiểm tra DNS resolution nslookup sql-az500-lab30-xk9m.database.windows.net # Expected: # Name: sql-az500-lab30-xk9m.privatelink.database.windows.net # Address: 10.10.3.5 ← private IP! # Cài sqlcmd (Microsoft SQL tools cho Ubuntu) curl https://packages.microsoft.com/keys/microsoft.asc | sudo apt-key add - curl https://packages.microsoft.com/config/ubuntu/22.04/prod.list | \ sudo tee /etc/apt/sources.list.d/mssql-release.list sudo apt-get update sudo ACCEPT_EULA=Y apt-get install -y mssql-tools18 unixodbc-dev export PATH="$PATH:/opt/mssql-tools18/bin" # Đăng nhập Azure CLI trên VM (để lấy token Entra) az login --use-device-code # Lấy access token cho SQL TOKEN=$(az account get-access-token \ --resource https://database.windows.net \ --query accessToken -o tsv) # Kết nối SQL qua private endpoint sqlcmd -S sql-az500-lab30-xk9m.database.windows.net \ -d db-az500-lab30 \ -G \ -P $TOKEN \ -Q "SELECT @@VERSION; SELECT DB_NAME();"
----------------------------------------------------------- Microsoft SQL Azure (RTM) - 12.0.2000.8 Southeast Asia (1 rows affected) ------------------- db-az500-lab30 (1 rows affected) # Kết nối thành công qua private IP 10.10.3.5! # Port 1433 hoàn toàn đi qua NIC private — không expose Internet
Xác Nhận Public Access Bị Từ Chối
Từ máy local (ngoài VNet), thử kết nối SQL → phải bị từ chối vì public access Disabled.
# Từ máy local — kiểm tra DNS (trả về public IP)
nslookup sql-az500-lab30-xk9m.database.windows.net
# → Address: 52.x.x.x (public IP Azure SQL Southeast Asia)
# Thử kết nối TCP 1433 (dùng telnet hoặc nc)
nc -zv sql-az500-lab30-xk9m.database.windows.net 1433
# → Connection refused / timed out
# Thử az sql query (cũng thất bại)
az sql db query \
--server sql-az500-lab30-xk9m \
--database db-az500-lab30 \
--resource-group rg-az500-ch07-private \
--query "SELECT 1"
# → ERROR: This server does not have public network access enabled.
# Xác nhận cấu hình
az sql server show \
--name sql-az500-lab30-xk9m \
--resource-group rg-az500-ch07-private \
--query "{publicNetworkAccess:publicNetworkAccess, restrictOutboundNetworkAccess:restrictOutboundNetworkAccess}"
{
"publicNetworkAccess": "Disabled",
"restrictOutboundNetworkAccess": "Disabled"
}
📊 Kết Quả Đầu Ra Lab 30
Entra-only auth, publicNetworkAccess: Disabled ngay từ đầu
pe-sql-lab30 có NIC với IP 10.10.3.5, Connection: Approved
privatelink.database.windows.net → A record 10.10.3.5, linked VNet
SELECT @@VERSION trả về thành công qua private IP
nc -zv port 1433 từ ngoài VNet → connection refused
Không có SQL admin password — bảo mật theo chuẩn Zero Trust
🧹 Dọn Dẹp Tài Nguyên
Azure SQL tốn chi phí đáng kể — xóa ngay sau khi hoàn thành lab!
# Xóa VM test az vm delete --resource-group rg-az500-ch07-private --name vm-sqltest --yes --no-wait # Xóa Private Endpoint SQL az network private-endpoint delete \ --name pe-sql-lab30 \ --resource-group rg-az500-ch07-private --yes # Xóa Private DNS Zone SQL az network private-dns zone delete \ --resource-group rg-az500-ch07-private \ --name "privatelink.database.windows.net" --yes # Xóa SQL Database trước (bắt buộc trước khi xóa server) az sql db delete \ --server sql-az500-lab30-xk9m \ --resource-group rg-az500-ch07-private \ --name db-az500-lab30 --yes # Xóa SQL Server az sql server delete \ --name sql-az500-lab30-xk9m \ --resource-group rg-az500-ch07-private --yes
❓ Câu Hỏi Ôn Tập
1. Tên Private DNS Zone cho Azure SQL là gì? Tại sao group-id là sqlServer chứ không phải sql?
Gợi ý: privatelink.database.windows.net. group-id là sqlServer vì Azure SQL có nhiều sub-resource (sqlServer cho logical server, managedInstance cho SQL MI) — mỗi loại có DNS zone khác nhau.
2. Connection policy "Default" cho Azure SQL hoạt động như thế nào với Private Endpoint?
Gợi ý: Với PE, Azure SQL luôn dùng Proxy (port 1433), không dùng Redirect (port 11000-11999). Không cần mở port ngoài 1433 khi dùng Private Endpoint.
3. Tại sao nên dùng Microsoft Entra authentication thay vì SQL admin password cho Azure SQL?
Gợi ý: Không lưu password tĩnh, hỗ trợ MFA và Conditional Access, có thể dùng Managed Identity, audit theo identity đầy đủ hơn, phù hợp chuẩn Zero Trust.
4. Azure SQL Managed Instance (SQL MI) có dùng được Private Endpoint như SQL Database không?
Gợi ý: SQL MI được deploy trực tiếp vào VNet subnet — bản thân nó đã private. Private DNS Zone khác: privatelink.<zone>.database.windows.net với zone tùy region.
5. Nếu muốn cho phép Azure Data Studio từ máy on-premises kết nối SQL Server này, cần làm gì?
Gợi ý: Cần VPN Gateway hoặc ExpressRoute kết nối on-premises với VNet. Sau đó cấu hình DNS forwarder on-premises forward *.database.windows.net về Azure DNS. Không cần bật public access.