Lý Thuyết Cốt Lõi
1. Tổng Quan Application Gateway — Layer 7 Load Balancer
Azure Application Gateway là managed load balancer hoạt động ở Layer 7 (HTTP/HTTPS/HTTP2). Khác với Azure Load Balancer (Layer 4 — chỉ xem IP/port), Application Gateway đọc và phân tích nội dung HTTP request để routing thông minh hơn.
| Tiêu chí | Load Balancer (L4) | Application Gateway (L7) |
|---|---|---|
| OSI Layer | Layer 4 — TCP/UDP | Layer 7 — HTTP/HTTPS/WebSocket |
| Routing dựa theo | IP address + Port | URL path, hostname, HTTP headers, cookies |
| SSL/TLS | Pass-through (không decrypt) | SSL termination hoặc end-to-end SSL |
| WAF | Không có | Có (WAF v2 tích hợp) |
| Session affinity | Dựa trên IP hash | Cookie-based (ApplicationGatewayAffinity) |
| Giao thức | TCP, UDP | HTTP, HTTPS, HTTP/2, WebSocket |
| SKU | Basic, Standard | Standard_v2, WAF_v2 |
2. Các Thành Phần Cấu Trúc Application Gateway
Request flow: Client → Frontend IP → Listener → Rule → Backend Pool → Backend HTTP Setting → Backend Server. Mỗi thành phần đóng một vai trò cụ thể trong pipeline xử lý request.
- • Frontend IP: Public IP và/hoặc Private IP nhận request từ client
- • Basic listener: lắng nghe port + protocol, nhận mọi request
- • Multi-site listener: lắng nghe theo hostname (SNI) — phân biệt app1.vn vs app2.vn trên cùng IP
- • Một App Gateway có thể có nhiều listener trên nhiều port/hostname
- • Tập hợp backend targets nhận request đã được route
- • Hỗ trợ: VM, VMSS, App Service, IP address, FQDN
- • Có thể trỏ đến App Service trực tiếp (không cần IP)
- • Empty backend pool → App Gateway trả 502 Bad Gateway
- • Mỗi listener/rule có thể route đến backend pool khác nhau
- • Định nghĩa cách App Gateway kết nối đến backend
- • Protocol: HTTP hoặc HTTPS (end-to-end SSL)
- • Port backend (thường 80 hoặc 443)
- • Cookie-based affinity: bật/tắt sticky session
- • Connection draining: đợi request cũ xong trước khi remove backend
- • Custom health probe: hoặc dùng default probe
- • Basic rule: Listener → Backend Pool + HTTP Settings (1-to-1)
- • Path-based rule: Listener → URL Path Map → nhiều backend theo path
- • Redirect rule: chuyển hướng HTTP → HTTPS hoặc sang URL khác
- • Rewrite rule (v2): sửa HTTP headers request/response
- • Priority: rule có priority thấp hơn được đánh giá trước
Default probe: App Gateway tự gửi GET đến backend IP + port từ Backend HTTP Settings. Custom probe: tùy chỉnh hostname, path, interval, timeout, unhealthy threshold, và match condition (status code 200-399 hoặc custom range). Custom probe bắt buộc khi backend là App Service có custom domain.
3. Path-Based Routing & Multi-Site Routing
- • Một listener xử lý nhiều backend tùy URL path
- • Default path map: bắt tất cả request không khớp rule nào
- • Wildcard: /images/* khớp /images/a, /images/b/c, v.v.
- • Path matching: case-sensitive, không normalize %2F
- • SNI (Server Name Indication) phân biệt hostname trong TLS
- • Mỗi listener có certificate SSL riêng
- • Tối đa 100 sites trên 1 App Gateway v2
- • Multi-site listener có priority cao hơn Basic listener
4. WAF — Web Application Firewall
WAF_v2 SKU tích hợp Web Application Firewall bảo vệ chống lại các tấn công phổ biến theo chuẩn OWASP. WAF chạy trước khi request được forward đến backend.
Ghi log các request vi phạm rule nhưng KHÔNG chặn. Dùng để monitor và tuning rule trước khi bật Prevention.
Chặn và log request vi phạm. Trả về 403 Forbidden. Đây là chế độ production khi đã xác nhận không có false positive.
Rule tự định nghĩa: match IP range, geo-location, URI, request headers. Ưu tiên cao hơn OWASP managed rules.
- • CRS 3.2 (mặc định) và CRS 3.1 — OWASP Top 10
- • Bảo vệ: SQL injection, XSS, Remote File Inclusion, Command injection, Protocol violations
- • DRS (Default Rule Set) 2.1 — Microsoft managed rules
- • Bot protection rules (optional): chặn known malicious bots
- • WAF Policy object: tách rời khỏi App Gateway, có thể share nhiều gateway
- • Exclusion list: bỏ qua rule cụ thể cho field cụ thể (VD: cho phép special char trong cookie)
- • Per-site policy (v2): mỗi listener có WAF policy riêng
- • Log phân tích: Azure Monitor → Diagnostic Logs → ApplicationGatewayFirewallLog
Bài Tập Thực Hành (Lab)
Tạo Resource Group, VNet (gồm subnet cho App Gateway và backend) và 2 backend VM
# Tạo Resource Group
az group create \
--name rg-az104-m15 \
--location southeastasia
# Tạo VNet — App Gateway cần subnet riêng (không share với backend)
az network vnet create \
--resource-group rg-az104-m15 \
--name vnet-m15 \
--address-prefix 10.15.0.0/16
# Subnet dành riêng cho Application Gateway (bắt buộc)
az network vnet subnet create \
--resource-group rg-az104-m15 \
--vnet-name vnet-m15 \
--name snet-appgw \
--address-prefix 10.15.0.0/24
# Subnet cho backend servers
az network vnet subnet create \
--resource-group rg-az104-m15 \
--vnet-name vnet-m15 \
--name snet-backend \
--address-prefix 10.15.1.0/24
# NSG cho backend subnet — cho phép HTTP từ App Gateway subnet
az network nsg create \
--resource-group rg-az104-m15 \
--name nsg-m15-backend
az network nsg rule create \
--resource-group rg-az104-m15 \
--nsg-name nsg-m15-backend \
--name Allow-HTTP-from-AppGW \
--priority 100 \
--source-address-prefixes 10.15.0.0/24 \
--protocol Tcp \
--destination-port-range 80 \
--access Allow
az network vnet subnet update \
--resource-group rg-az104-m15 \
--vnet-name vnet-m15 \
--name snet-backend \
--network-security-group nsg-m15-backend
# Tạo VM web cho backend-pool-web (phục vụ trang chủ)
az vm create \
--resource-group rg-az104-m15 \
--name vm-m15-web \
--image Ubuntu2204 \
--size Standard_B1s \
--vnet-name vnet-m15 \
--subnet snet-backend \
--nsg "" \
--public-ip-address "" \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data '#!/bin/bash
apt-get update -y && apt-get install -y nginx
echo "<h1>WEB Server - Trang chu</h1>" > /var/www/html/index.html
systemctl enable nginx && systemctl start nginx'
# Tạo VM api cho backend-pool-api (phục vụ /api/*)
az vm create \
--resource-group rg-az104-m15 \
--name vm-m15-api \
--image Ubuntu2204 \
--size Standard_B1s \
--vnet-name vnet-m15 \
--subnet snet-backend \
--nsg "" \
--public-ip-address "" \
--admin-username azureuser \
--generate-ssh-keys \
--custom-data '#!/bin/bash
apt-get update -y && apt-get install -y nginx
mkdir -p /var/www/html/api
echo "<h1>API Server - /api endpoint</h1>" > /var/www/html/api/index.html
sed -i "s|root /var/www/html;|root /var/www/html;|" /etc/nginx/sites-available/default
systemctl enable nginx && systemctl start nginx'
# Lấy private IP của từng VM để cấu hình backend pool
VM_WEB_IP=$(az vm show -d \
--resource-group rg-az104-m15 \
--name vm-m15-web \
--query privateIps -o tsv)
VM_API_IP=$(az vm show -d \
--resource-group rg-az104-m15 \
--name vm-m15-api \
--query privateIps -o tsv)
echo "VM Web IP: $VM_WEB_IP"
echo "VM API IP: $VM_API_IP"
Tạo Application Gateway Standard_v2 với Public IP
# Tạo Standard Public IP cho App Gateway (phải là Standard SKU)
az network public-ip create \
--resource-group rg-az104-m15 \
--name pip-m15-appgw \
--sku Standard \
--allocation-method Static
# Tạo Application Gateway Standard_v2
# Lệnh này tạo App Gateway kèm: 1 frontend IP, 1 backend pool, 1 HTTP setting,
# 1 basic listener (port 80), 1 basic rule
az network application-gateway create \
--resource-group rg-az104-m15 \
--name appgw-m15 \
--location southeastasia \
--sku Standard_v2 \
--capacity 1 \
--vnet-name vnet-m15 \
--subnet snet-appgw \
--public-ip-address pip-m15-appgw \
--frontend-port 80 \
--http-settings-port 80 \
--http-settings-protocol Http \
--servers $VM_WEB_IP \
--priority 100
# Kiểm tra trạng thái (Provisioning State phải là Succeeded — có thể mất 5-10 phút)
az network application-gateway show \
--resource-group rg-az104-m15 \
--name appgw-m15 \
--query "{name:name, provisioningState:provisioningState, sku:sku.name}" \
-o table
# Lấy Public IP của App Gateway
APPGW_IP=$(az network public-ip show \
--resource-group rg-az104-m15 \
--name pip-m15-appgw \
--query ipAddress -o tsv)
echo "App Gateway IP: $APPGW_IP"
Cấu hình Path-Based Routing — /api/* đến backend VM API
# Thêm backend pool thứ 2 cho API servers
az network application-gateway address-pool create \
--resource-group rg-az104-m15 \
--gateway-name appgw-m15 \
--name pool-api \
--servers $VM_API_IP
# Tạo HTTP settings riêng cho API backend
az network application-gateway http-settings create \
--resource-group rg-az104-m15 \
--gateway-name appgw-m15 \
--name httpsettings-api \
--port 80 \
--protocol Http \
--cookie-based-affinity Disabled \
--timeout 30
# Tạo URL path map: /api/* → pool-api, mọi thứ khác → pool web mặc định
az network application-gateway url-path-map create \
--resource-group rg-az104-m15 \
--gateway-name appgw-m15 \
--name pathmap-m15 \
--paths /api/* \
--address-pool pool-api \
--http-settings httpsettings-api \
--default-address-pool appGatewayBackendPool \
--default-http-settings appGatewayBackendHttpSettings
# Tạo path-based rule mới thay thế basic rule
# Trước tiên xóa basic rule mặc định
az network application-gateway rule delete \
--resource-group rg-az104-m15 \
--gateway-name appgw-m15 \
--name rule1
# Tạo path-based rule với URL path map
az network application-gateway rule create \
--resource-group rg-az104-m15 \
--gateway-name appgw-m15 \
--name rule-pathbased \
--rule-type PathBasedRouting \
--http-listener appGatewayHttpListener \
--address-pool appGatewayBackendPool \
--http-settings appGatewayBackendHttpSettings \
--url-path-map pathmap-m15 \
--priority 100
echo "Path-based routing configured."
echo "Test: curl http://$APPGW_IP/ -> Web Server"
echo "Test: curl http://$APPGW_IP/api/ -> API Server"
curl http://[APPGW_IP]/api/ phải trả về "API Server"; curl http://[APPGW_IP]/ trả về "WEB Server".
Tạo WAF Policy và gán vào Application Gateway
# Tạo WAF Policy với OWASP CRS 3.2, chế độ Detection (an toàn để bắt đầu)
az network application-gateway waf-policy create \
--resource-group rg-az104-m15 \
--name wafpolicy-m15 \
--location southeastasia
# Cấu hình WAF policy: OWASP CRS 3.2, Detection mode
az network application-gateway waf-policy policy-setting update \
--resource-group rg-az104-m15 \
--policy-name wafpolicy-m15 \
--mode Detection \
--state Enabled \
--request-body-check true \
--max-request-body-size-kb 128 \
--file-upload-limit-mb 100
# Thêm managed rule set OWASP CRS 3.2
az network application-gateway waf-policy managed-rule rule-set add \
--resource-group rg-az104-m15 \
--policy-name wafpolicy-m15 \
--type OWASP \
--version 3.2
# Thêm custom rule: chặn request từ IP range cụ thể (ví dụ block IP test)
az network application-gateway waf-policy custom-rule create \
--resource-group rg-az104-m15 \
--policy-name wafpolicy-m15 \
--name BlockSuspiciousUA \
--priority 10 \
--rule-type MatchRule \
--action Block
az network application-gateway waf-policy custom-rule match-condition add \
--resource-group rg-az104-m15 \
--policy-name wafpolicy-m15 \
--name BlockSuspiciousUA \
--match-variables RequestHeaders.User-Agent \
--operator Contains \
--values "sqlmap" "nikto" "nmap" \
--negate false
# Gán WAF Policy vào Application Gateway
# (Upgrade App Gateway từ Standard_v2 sang WAF_v2 trước)
az network application-gateway update \
--resource-group rg-az104-m15 \
--name appgw-m15 \
--sku WAF_v2 \
--waf-policy wafpolicy-m15
echo "WAF Policy gán vào appgw-m15 thành công."
echo "Kiểm tra WAF logs: Portal -> appgw-m15 -> Diagnostic settings -> ApplicationGatewayFirewallLog"
curl "http://[APPGW_IP]/?q=<script>alert(1)</script>" — trong Detection mode request vẫn qua nhưng ghi log. Bật Prevention mode rồi test lại → phải nhận 403.
Cleanup — Dọn dẹp tài nguyên tránh phát sinh chi phí
# Xóa WAF Policy (tách khỏi App Gateway trước)
az network application-gateway update \
--resource-group rg-az104-m15 \
--name appgw-m15 \
--sku Standard_v2 \
--remove wafConfiguration 2>/dev/null || true
# Xóa toàn bộ Resource Group — xóa App Gateway, VMs, VNet, Public IP
az group delete --name rg-az104-m15 --yes --no-wait
# Xóa WAF Policy (standalone resource, không nằm trong RG xóa trên nếu đã detach)
az network application-gateway waf-policy delete \
--resource-group rg-az104-m15 \
--name wafpolicy-m15 2>/dev/null || true
echo "Resource group rg-az104-m15 đang được xóa."
echo "Lưu ý: Application Gateway WAF_v2 tính phí ~0.36 USD/giờ — cleanup ngay sau lab!"
az group list -o table | grep m15 — không được còn RG nào.
Kết Quả Đầu Ra
Hiểu rõ Layer 4 vs Layer 7, chọn đúng giải pháp theo yêu cầu routing và bảo mật
Tạo App Gateway với subnet riêng, cấu hình frontend IP, backend pool và listener cơ bản
Cấu hình URL Path Map để route /api/* đến backend API pool, verify bằng curl
Hiểu cách nhiều hostname chia sẻ cùng 1 IP qua multi-site listener và Server Name Indication
Tạo WAF Policy với OWASP CRS 3.2, custom rules, chuyển Detection → Prevention mode và verify chặn XSS/SQLi
Mô tả được flow: Listener → Rule → URL Path Map → Backend Pool → HTTP Settings → Backend VM
Ứng Dụng Thực Tế
Tình huống 1: Công ty fintech — Microservices routing qua 1 IP duy nhất
Startup fintech Việt Nam có 5 microservice (auth, payment, notification, reporting, admin), cần expose qua 1 domain duy nhất api.fintech.vn với WAF bảo vệ.
Application Gateway WAF_v2 với 1 HTTPS listener (api.fintech.vn:443). Path-based routing: /auth/* → pool-auth, /payment/* → pool-payment, /notify/* → pool-notify, /report/* → pool-report, /admin/* → pool-admin (riêng biệt). SSL termination tại App Gateway — backend chạy HTTP.
WAF Prevention mode + OWASP CRS 3.2. Custom rule chặn /admin/* từ ngoài (chỉ cho phép IP office VN). HTTP redirect rule: HTTP:80 → HTTPS:443. Cookie-based affinity bật cho /payment/* (stateful checkout flow). Health probe custom cho từng microservice (/health endpoint).
1 Public IP thay vì 5. SSL quản lý tập trung (không cần cert trên từng backend). WAF chặn SQLi/XSS cho toàn bộ API. Microservice scale độc lập. Giảm 60% chi phí so với dùng 5 API Management instance.
Tình huống 2: Tập đoàn truyền thông — Multi-site cho 10 báo điện tử
Tập đoàn sở hữu 10 tờ báo điện tử (vnexpress.vn, tuoitre.vn style), mỗi báo chạy trên stack riêng nhưng muốn chia sẻ 1 IP và WAF chung.
1 Application Gateway WAF_v2 với 10 Multi-site listener, mỗi listener 1 hostname + SSL certificate riêng. Mỗi listener basic rule trỏ đến backend pool chứa 2-4 web server của báo đó. Cookie affinity bật — reader được giữ trên cùng 1 server trong session.
WAF Policy level per-site: báo tin tức thường dùng CRS 3.2 standard; báo kinh tế tài chính dùng CRS 3.2 + DRS 2.1 nghiêm ngặt hơn. Auto-renew SSL cert qua Azure Key Vault integration. Autoscale capacity unit theo giờ cao điểm (7-9AM và 5-8PM).
10 tên miền trên 1 IP — tiết kiệm chi phí. SSL cert tập trung. WAF log tập trung phân tích tấn công toàn tập đoàn. Capacity autoscale từ 2 → 10 unit trong flash news event (bầu cử, World Cup). Downtime 0 khi update WAF rule.
Tình huống 3: Bệnh viện — SSL End-to-End và WAF bảo vệ hồ sơ bệnh nhân
Bệnh viện tư triển khai portal bệnh nhân online, yêu cầu mã hóa end-to-end và bảo vệ dữ liệu PHI theo tiêu chuẩn y tế.
App Gateway WAF_v2 với end-to-end SSL: HTTPS từ client đến App Gateway (cert public), HTTPS từ App Gateway đến backend (cert nội bộ). WAF Prevention + CRS 3.2 + Bot protection. Custom rule chặn tất cả quốc gia ngoại trừ Vietnam (Geo-filter).
Backend HTTP Settings: HTTPS port 443, trusted root cert của backend CA. Path-based: /api/patient/* → App Service (hồ sơ bệnh nhân), /api/appointment/* → AKS cluster (đặt lịch), / → static web (thông tin bệnh viện). Connection draining 300s cho /api/* (không mất request giữa chừng khi update).
Dữ liệu PHI được mã hóa toàn bộ path. WAF ngăn chặn OWASP Top 10 trước khi chạm backend. Geo-filter giảm 95% bot traffic nước ngoài. Compliance với HIPAA (tương đương tiêu chuẩn y tế VN). Log tập trung cho audit trail.