Skip to main content

03 - Security

WAF configuration, Private Link, DDoS protection, and TLS best practices for Azure Front Door

WAF


🎯 Security Design Principles

PrincipleFront Door Implementation
Defense in depthWAF + Private Link + Origin validation
Least privilegeRBAC for management, origin IP restrictions
Encrypt everywhereEnd-to-end TLS, minimum TLS 1.2
Monitor continuouslyWAF logs, access logs, security alerts

✅ Security Checklist

#RecommendationPriorityTier
1Enable WAF in Prevention mode🔴 CriticalStandard+
2Use Private Link to origins🔴 CriticalPremium
3Enforce TLS 1.2+ minimum🔴 CriticalAll
4Block direct origin access🔴 CriticalAll
5Enable managed WAF rule sets🟡 HighPremium
6Configure rate limiting🟡 HighStandard+
7Enable bot protection🟡 HighPremium
8Use managed TLS certificates🟢 MediumAll
9Enable geo-filtering if needed🟢 MediumStandard+
10Send WAF logs to SIEM🟢 MediumAll

🛡️ Security Architecture


🔥 Web Application Firewall (WAF)

WAF Rule Sets (Premium Tier)

Rule SetDescriptionRecommendation
Default Rule Set (DRS)OWASP Top 10 protection✅ Enable
Bot ManagerGood/Bad/Unknown bot classification✅ Enable
Rate LimitingRequest throttling per IP✅ Configure
Geo-FilteringBlock/Allow by country⚠️ If needed
IP RestrictionBlock specific IPs/ranges⚠️ If needed

WAF Configuration (Bicep)

resource wafPolicy 'Microsoft.Network/FrontDoorWebApplicationFirewallPolicies@2022-05-01' = {
name: 'waf-frontdoor'
location: 'global'
sku: {
name: 'Premium_AzureFrontDoor'
}
properties: {
policySettings: {
mode: 'Prevention' // Start with Detection, then Prevention
enabledState: 'Enabled'
requestBodyCheck: 'Enabled'
}

managedRules: {
managedRuleSets: [
{
ruleSetType: 'Microsoft_DefaultRuleSet'
ruleSetVersion: '2.1'
ruleSetAction: 'Block'
}
{
ruleSetType: 'Microsoft_BotManagerRuleSet'
ruleSetVersion: '1.0'
ruleSetAction: 'Block'
}
]
}

customRules: {
rules: [
{
name: 'RateLimitRule'
priority: 100
ruleType: 'RateLimitRule'
rateLimitDurationInMinutes: 1
rateLimitThreshold: 1000
matchConditions: [
{
matchVariable: 'RemoteAddr'
operator: 'IPMatch'
matchValue: ['0.0.0.0/0'] // All IPs
}
]
action: 'Block'
}
]
}
}
}

WAF Mode Progression

Best Practice: Start in Detection mode, tune exclusions for false positives, then switch to Prevention.


Architecture: Private Origin Connectivity

resource origin 'Microsoft.Cdn/profiles/originGroups/origins@2023-05-01' = {
name: 'origin-app'
parent: originGroup
properties: {
hostName: 'app.azurewebsites.net'
originHostHeader: 'api.contoso.com'
httpPort: 80
httpsPort: 443
priority: 1
weight: 1000
enabledState: 'Enabled'
sharedPrivateLinkResource: {
privateLink: {
id: '/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Web/sites/app'
}
privateLinkLocation: 'westeurope'
requestMessage: 'Front Door Private Link'
groupId: 'sites'
}
}
}
Origin TypeGroup IDNotes
App Service / FunctionssitesMost common
Storage (Blob)blobStatic content
Internal Load BalancerVia Private Link ServiceCustom apps
Application GatewayVia Private Link ServiceRegional WAF
API ManagementgatewayAPI tier
Container AppsVia Private Link ServiceContainers

If Private Link is not available (Standard tier), secure origins with:

1. Service Tags + Header Validation

// App Service Access Restrictions
resource appService 'Microsoft.Web/sites@2022-03-01' = {
name: 'app-backend'
properties: {
siteConfig: {
ipSecurityRestrictions: [
{
ipAddress: 'AzureFrontDoor.Backend'
action: 'Allow'
tag: 'ServiceTag'
priority: 100
name: 'Allow-FrontDoor'
headers: {
'X-Azure-FDID': [ frontDoorId ] // Your Front Door ID
}
}
{
ipAddress: 'Any'
action: 'Deny'
priority: 2147483647
name: 'Deny-All'
}
]
}
}
}

2. Validate X-Azure-FDID Header (Application Code)

// ASP.NET Core Middleware
public class FrontDoorValidationMiddleware
{
private readonly string _expectedFrontDoorId;

public async Task InvokeAsync(HttpContext context, RequestDelegate next)
{
var frontDoorId = context.Request.Headers["X-Azure-FDID"].FirstOrDefault();

if (frontDoorId != _expectedFrontDoorId)
{
context.Response.StatusCode = 403;
await context.Response.WriteAsync("Direct access not allowed");
return;
}

await next(context);
}
}

🔐 TLS Best Practices

Minimum TLS Version

resource frontDoor 'Microsoft.Cdn/profiles@2023-05-01' = {
name: 'fd-api'
location: 'global'
sku: { name: 'Premium_AzureFrontDoor' }
properties: {
// TLS 1.2 is enforced by default
}
}

resource customDomain 'Microsoft.Cdn/profiles/customDomains@2023-05-01' = {
name: 'api-contoso-com'
parent: frontDoor
properties: {
hostName: 'api.contoso.com'
tlsSettings: {
certificateType: 'ManagedCertificate' // Azure manages renewal
minimumTlsVersion: 'TLS12' // Minimum TLS 1.2
}
}
}

TLS Recommendations

SettingRecommendationReason
Minimum VersionTLS 1.2TLS 1.0/1.1 have vulnerabilities
Certificate TypeManagedAutomatic renewal, less operational burden
End-to-End TLSEnableEncrypt traffic to origins
HTTPS RedirectEnableForce secure connections

🤖 Rate Limiting

Rate Limit Rule Example

{
name: 'GlobalRateLimit'
priority: 1
ruleType: 'RateLimitRule'
rateLimitDurationInMinutes: 1
rateLimitThreshold: 1000 // 1000 requests per minute per IP
matchConditions: [
{
matchVariable: 'RequestUri'
operator: 'Contains'
matchValue: ['/api/']
}
]
action: 'Block'
}

Rate Limit Recommendations

Endpoint TypeThresholdDuration
Public APIs100-1000/min1 minute
Login/Auth10-20/min1 minute
Static Content5000+/min1 minute
Admin APIs10-50/min1 minute

📊 Security Logging

Enable Diagnostic Settings

resource diagnostics 'Microsoft.Insights/diagnosticSettings@2021-05-01-preview' = {
name: 'fd-diagnostics'
scope: frontDoor
properties: {
workspaceId: logAnalyticsWorkspace.id
logs: [
{ category: 'FrontDoorAccessLog', enabled: true }
{ category: 'FrontDoorHealthProbeLog', enabled: true }
{ category: 'FrontDoorWebApplicationFirewallLog', enabled: true }
]
metrics: [
{ category: 'AllMetrics', enabled: true }
]
}
}

Key Queries for Security Monitoring

// WAF blocked requests
AzureDiagnostics
| where Category == "FrontDoorWebApplicationFirewallLog"
| where action_s == "Block"
| summarize count() by ruleName_s, clientIP_s
| order by count_ desc

// Top attacking IPs
AzureDiagnostics
| where Category == "FrontDoorWebApplicationFirewallLog"
| where action_s == "Block"
| summarize count() by clientIP_s
| order by count_ desc
| take 10

📋 Security Configuration Summary

CategoryRecommendation
WAFEnable managed rules, start Detection mode
Private LinkUse for all origins (Premium tier)
Origin SecurityService tags + X-Azure-FDID validation
TLSMinimum 1.2, managed certificates
Rate LimitingConfigure per endpoint type
LoggingWAF logs to SIEM, set up alerts

🔗 References

ResourceLink
Security BaselineAzure Front Door security baseline
WAF on Front DoorWeb Application Firewall
Private LinkSecure origin with Private Link
TLS Best PracticesTLS best practices
Secure DeploymentSecure your Azure Front Door

Previous: 02 - Reliability | Next: 04 - Cost Optimization

📖Learn