🎯 Mục Tiêu Lab
Tạo Azure SQL Server và Database tại region southeastasia
Cấu hình Microsoft Entra admin thay thế SQL authentication truyền thống
Bật SQL Auditing ghi log vào Storage Account
Xác nhận Transparent Data Encryption (TDE) đang bật mặc định
Cấu hình Dynamic Data Masking ẩn dữ liệu nhạy cảm (email, thẻ, SSN)
Tìm hiểu cơ chế Always Encrypted bảo vệ dữ liệu end-to-end
📋 Chuẩn Bị
- Azure subscription với quyền Contributor trở lên
- Azure CLI đã cài và az login thành công
- Tài khoản Entra ID (user az500-admin01 từ Lab 02)
- Azure Data Studio hoặc SSMS (tùy chọn để kiểm tra DDM)
RG="rg-az500-lab42-sql"
LOCATION="southeastasia"
SQL_SERVER="sql-az500-lab42"
SQL_DB="sqldb-az500-security"
STORAGE="staz500lab42audit"
🏗️ Kịch Bản
Công ty bạn yêu cầu bảo mật Azure SQL Database chứa dữ liệu khách hàng: xác thực phải dùng Entra ID (không dùng SQL password), mọi truy vấn phải được ghi log audit, dữ liệu phải được mã hóa khi lưu (TDE), và nhân viên không đủ quyền chỉ thấy dữ liệu bị che (Dynamic Data Masking). Đây là yêu cầu baseline bảo mật theo Microsoft Cloud Security Benchmark cho workload database.
🧪 Các Bước Thực Hiện
Tạo Resource Group, SQL Server và Database
- 1.1Portal → Resource groups → + Create → Name:
rg-az500-lab42-sql→ Region: Southeast Asia - 1.2Portal → Azure SQL → + Create → chọn SQL databases → Single database
- 1.3Server: Create new → Server name:
sql-az500-lab42→ Location: Southeast Asia → Authentication: Use only Microsoft Entra authentication - 1.4Set Microsoft Entra admin → chọn user
az500-admin01→ OK - 1.5Database name:
sqldb-az500-security→ Compute: Basic (5 DTU) → Review + Create
# Lấy Object ID của user Entra để làm admin
ADMIN_OID=$(az ad user show --id [email protected] \
--query id -o tsv)
# Tạo resource group
az group create --name $RG --location $LOCATION \
--tags owner=hoatranlab env=lab module=az500
# Tạo SQL Server với chỉ Entra authentication (không dùng SQL password)
az sql server create \
--name $SQL_SERVER \
--resource-group $RG \
--location $LOCATION \
--enable-ad-only-auth \
--external-admin-principal-type User \
--external-admin-name [email protected] \
--external-admin-sid $ADMIN_OID
# Tạo SQL Database (Basic tier, 5 DTU)
az sql db create \
--name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG \
--edition Basic \
--capacity 5
Bật SQL Auditing ghi vào Storage Account
- 2.1Portal → SQL Server sql-az500-lab42 → Security → Auditing → ON
- 2.2Chọn Storage → Configure → tạo mới Storage Account:
staz500lab42audit - 2.3Retention days: 90 → Save
- 2.4Có thể bật thêm tại Database level: SQL Database → Security → Auditing → ON → lặp lại như server level
# Tạo Storage Account cho audit log
az storage account create \
--name $STORAGE \
--resource-group $RG \
--location $LOCATION \
--sku Standard_LRS \
--allow-blob-public-access false
STORAGE_ID=$(az storage account show \
--name $STORAGE --resource-group $RG \
--query id -o tsv)
# Bật SQL Auditing ở cấp server
az sql server audit-policy update \
--name $SQL_SERVER \
--resource-group $RG \
--state Enabled \
--storage-account $STORAGE \
--retention-days 90
# Xác nhận audit policy
az sql server audit-policy show \
--name $SQL_SERVER \
--resource-group $RG \
--query "{state:state, storageEndpoint:storageEndpoint, retentionDays:retentionDays}"
Xác nhận Transparent Data Encryption (TDE)
- 3.1Portal → SQL Database sqldb-az500-security → Security → Transparent data encryption
- 3.2Xác nhận: Data encryption: ON, Key management: Service-managed key
- 3.3(Tùy chọn nâng cao) Chuyển sang Customer-managed key nếu muốn dùng Key Vault BYOK
# Kiểm tra trạng thái TDE của database
az sql db tde show \
--name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG
# Output mong đợi: "status": "Enabled"
# TDE được bật mặc định cho mọi Azure SQL Database
# Đảm bảo TDE bật (nếu vì lý do nào đó bị tắt)
az sql db tde set \
--name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG \
--status Enabled
{
"databaseName": "sqldb-az500-security",
"resourceGroup": "rg-az500-lab42-sql",
"status": "Enabled",
"type": "Microsoft.Sql/servers/databases/transparentDataEncryption"
}
Cấu hình Dynamic Data Masking (DDM)
DDM che dữ liệu nhạy cảm khi user không có đủ quyền. Dữ liệu vẫn được lưu đầy đủ trong DB, chỉ kết quả trả về bị che.
- 4.1SQL Database → Security → Dynamic Data Masking
- 4.2Click "+ Add mask" → Schema: dbo → Table: Customers → Column: Email → Masking field format: Email ([email protected])
- 4.3Thêm mask cho Column: CreditCard → format: Credit card (XXXX-XXXX-XXXX-1234)
- 4.4Save → kiểm tra "Excluded principals" (user admin không bị che)
# Tạo masking rule cho cột Email (email masking pattern)
az sql db data-masking rule create \
--name MaskEmail \
--database-name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG \
--schema-name dbo \
--table-name Customers \
--column-name Email \
--masking-function Email
# Tạo masking rule cho cột số thẻ tín dụng
az sql db data-masking rule create \
--name MaskCreditCard \
--database-name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG \
--schema-name dbo \
--table-name Customers \
--column-name CreditCard \
--masking-function CCN
# Bật DDM cho database
az sql db data-masking policy create \
--database-name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG \
--data-masking-state Enabled
# Xem danh sách masking rules
az sql db data-masking rule list \
--database-name $SQL_DB \
--server $SQL_SERVER \
--resource-group $RG \
--output table
Always Encrypted — Khái niệm và cấu hình cơ bản
Always Encrypted mã hóa dữ liệu ngay tại client — server/DBA không bao giờ thấy plaintext. Khác với TDE (mã hóa at-rest) và DDM (che kết quả truy vấn).
| Cơ chế | Bảo vệ khi nào | DBA thấy dữ liệu? |
|---|---|---|
| TDE | Data at-rest (disk) | Có (khi query) |
| DDM | Query result (hiển thị) | Có (excluded principals) |
| Always Encrypted | End-to-end (client) | Không bao giờ |
- 5.1SQL Database → Overview → click "Set up Always Encrypted columns" (hoặc dùng SSMS/Azure Data Studio)
- 5.2Chọn cột cần mã hóa → chọn loại encryption: Deterministic (có thể search) hoặc Randomized (bảo mật hơn)
- 5.3Key store: Azure Key Vault → chọn Key Vault đã tạo ở Lab 40
- 5.4Wizard tạo Column Master Key (CMK) và Column Encryption Key (CEK) trong Key Vault
-- Kiểm tra Always Encrypted keys đã tạo
SELECT name, column_master_key_id
FROM sys.column_encryption_keys;
SELECT name, key_store_provider_name, key_path
FROM sys.column_master_keys;
-- Xem cột nào đang dùng Always Encrypted
SELECT
t.name AS TableName,
c.name AS ColumnName,
c.encryption_type_desc,
c.column_encryption_key_id
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.encryption_type IS NOT NULL;
🧹 Dọn Dẹp Tài Nguyên
# Xóa resource group (xóa SQL Server, Database, Storage Account)
az group delete \
--name rg-az500-lab42-sql \
--yes --no-wait
# Xác nhận
az group list --query "[?name=='rg-az500-lab42-sql']" --output table
📊 Kết Quả Đầu Ra Lab 42
SQL Server chỉ nhận Entra ID, không có SQL password login
Log ghi vào Storage Account, retention 90 ngày
az sql db tde show → status: Enabled với service-managed key
User không quyền thấy: [email protected] thay vì email thật
❓ Câu Hỏi Ôn Tập
1. Sự khác nhau giữa TDE, DDM và Always Encrypted trong bảo mật dữ liệu Azure SQL?
Gợi ý: TDE = mã hóa file trên disk; DDM = che kết quả query với user không quyền; Always Encrypted = mã hóa tại client, server không bao giờ thấy plaintext.
2. Tại sao nên dùng "Microsoft Entra authentication only" thay vì SQL Server authentication?
Gợi ý: Entra authentication hỗ trợ MFA, Conditional Access, audit centralized; SQL password dễ bị brute-force và không có MFA.
3. Khi bật DDM, DBA có thấy dữ liệu gốc không? Làm thế nào để một user thấy dữ liệu thật?
Gợi ý: DBA có quyền UNMASK sẽ thấy dữ liệu thật. Có thể thêm user vào "Excluded principals" hoặc grant UNMASK permission.
4. Encryption type "Deterministic" và "Randomized" trong Always Encrypted khác nhau thế nào?
Gợi ý: Deterministic cho phép equality search và join; Randomized bảo mật hơn nhưng không search được. Dùng Randomized cho dữ liệu chỉ đọc/ghi không cần query.
5. SQL Auditing ở level server và level database khác nhau thế nào?
Gợi ý: Server-level áp dụng cho tất cả database; Database-level có thể cấu hình riêng cho từng DB với storage khác nhau. Nếu cả hai bật, cả hai đều ghi log.