Application Gateway and WAF Patterns
Application Gateway and WAF Patterns
Introduction
In today's cloud-native landscape, securing web applications is paramount. As organizations migrate and develop applications in Azure, ensuring these applications are resilient, scalable, and protected against common web vulnerabilities becomes a core concern. Azure Application Gateway, a web traffic load balancer that enables you to manage traffic to your web applications, offers a powerful solution. When combined with its Web Application Firewall (WAF) capabilities, it provides robust, centralized protection.
This article delves into common architectural patterns leveraging Azure Application Gateway and its integrated WAF. We will explore how these patterns can be implemented to enhance security, improve performance, and optimize costs for your web applications hosted on Azure. This guide is intended for cloud architects, network engineers, security professionals, and DevOps specialists responsible for designing, deploying, and managing secure web application infrastructure in Azure.
Why this matters
The judicious implementation of Application Gateway with WAF offers significant business and technical advantages. From a compliance perspective, WAF helps organizations meet regulatory requirements like PCI DSS, GDPR, and HIPAA by mitigating common web threats, which often feature prominently in audit checklists. Technically, WAF provides an essential layer of defense against OWASP Top 10 vulnerabilities, such as SQL Injection and Cross-Site Scripting, significantly reducing the risk of data breaches and service interruptions. This proactive security posture bolsters customer trust and protects brand reputation.
Economically, centralizing WAF functionalities at the network edge with Application Gateway can lead to cost efficiencies. Rather than deploying and managing individual WAF solutions for each application, a single Application Gateway instance can secure multiple backend services, reducing operational overhead and licensing costs. Furthermore, Application Gateway's capabilities like SSL/TLS offloading and session stickiness improve application performance and user experience, contributing indirectly to business productivity by ensuring consistent, fast access to critical applications.
Key concepts
- Azure Application Gateway: A Layer 7 load balancer that manages traffic to web applications. It provides features like SSL/TLS termination, cookie-based session affinity, URL-based routing, and multi-site hosting.
- Web Application Firewall (WAF): Integrated directly into Application Gateway, WAF provides centralized protection for your web applications from common exploits and vulnerabilities like SQL injection, cross-site scripting, and other OWASP Top 10 threats.
- WAF tiers (Standard_v2 and WAF_v2): Application Gateway offers two tiers: Standard_v2 and WAF_v2. The WAF_v2 SKU is specifically designed to provide WAF capabilities, offering enhanced performance, scalability, and features.
- WAF Policies: Centralized resources that define the WAF settings, rules, and exclusions for an Application Gateway. These can be managed independently and associated with one or multiple Application Gateway instances.
- Managed Rule Sets: Pre-configured collections of rules provided by Microsoft that offer protection against common web vulnerabilities. These are regularly updated by Azure to address new threats.
- Custom Rules: User-defined rules that allow for fine-grained control over WAF behavior, enabling specific request blocking or allowing based on various match conditions.
- Detection Mode vs. Prevention Mode: WAF can operate in two modes. Detection mode logs all detected threats without blocking them, useful for initial deployment and tuning. Prevention mode blocks detected threats and logs them, providing active protection.
- Backend Pools: A collection of backend targets (e.g., VMs, VM Scale Sets, App Services, internal IP addresses) to which the Application Gateway routes traffic.
Step-by-step implementation
Here’s a simplified step-by-step process for deploying an Application Gateway with WAF using Azure CLI, focusing on creating the core resources. This assumes you have an existing VNet and Subnet.
- Define Variables:
``bash resourceGroupName="myAppGwResourceGroup" location="EastUS" vnetName="myVNet" subnetName="myAppGwSubnet" publicIpName="myAppGwPublicIp" appGwName="myAppGateway" wafPolicyName="myAppGwWafPolicy" ``
- Create a Resource Group:
``bash az group create --name $resourceGroupName --location $location ``
- Create a Public IP Address for the Application Gateway:
``bash az network public-ip create \ --resource-group $resourceGroupName \ --name $publicIpName \ --allocation-method Static \ --sku Standard ``
- Create the WAF Policy (in prevention mode):
``bash az network application-gateway waf-policy create \ --resource-group $resourceGroupName \ --name $wafPolicyName \ --location $location \ --mode Prevention \ --disabled-rule-groups "SQLInjection" # Example: Disable a specific rule group if needed, consider carefully. `` Note: Disabling rule groups should be done with extreme caution and only after thorough testing and understanding of the implications.
- Create the Application Gateway v2 with WAF Policy Association:
``bash az network application-gateway create \ --resource-group $resourceGroupName \ --name $appGwName \ --location $location \ --sku WAF_v2 \ --capacity 2 \ --vnet-name $vnetName \ --subnet $subnetName \ --public-ip-address $publicIpName \ --http-settings-cookie-based-affinity Enabled \ --http-settings-port 80 \ --http-settings-protocol Http \ --frontend-port 80 \ --waf-policy $wafPolicyName \ --priority 100 \ --routing-rule-name "rule1" \ --routing-rule-type Basic \ --backend-pool-name "appBackendPool" \ --frontend-port-name "httpPort" \ --listener-name "httpListener" \ --http-settings-name "appGwHttpSettings" ` This command creates a WAF_v2 SKU Application Gateway, associates it with the previously created WAF policy, and sets up a basic HTTP listener, routing rule, and backend pool. You would then add your actual backend servers to the appBackendPool`.
Example configuration
Here's a Bicep snippet demonstrating a more comprehensive Application Gateway with WAF configuration, including SSL/TLS enabled, multiple backend pools, and a custom WAF rule.
resource appGateway 'Microsoft.Network/applicationGateways@2023-05-01' = {
name: appGatewayName
location: location
properties: {
sku: {
name: 'WAF_v2'
tier: 'WAF_v2'
capacity: 2
}
gatewayIPConfigurations: [
{
name: 'appGatewayIpConfig'
properties: {
subnet: {
id: subnetId
}
}
}
]
frontendIPConfigurations: [
{
name: 'appGwFrontendPublicIp'
properties: {
publicIPAddress: {
id: publicIpId
}
}
}
]
frontendPorts: [
{
name: 'httpsPort'
properties: {
port: 443
}
}
]
backendAddressPools: [
{
name: 'webBackendPool'
properties: {
backendAddresses: [
{
ipAddress: '10.0.1.4'
}
{
ipAddress: '10.0.1.5'
}
]
}
}
{
name: 'apiBackendPool'
properties: {
backendAddresses: [
{
fqdn: 'api-service.contoso.com' // Example for Azure App Service
}
]
}
}
]
backendHttpSettingsCollection: [
{
name: 'httpsBackendSettings'
properties: {
port: 443
protocol: 'Https'
cookieBasedAffinity: 'Enabled'
requestTimeout: 30
probe: {
id: resourceId('Microsoft.Network/applicationGateways/probes', appGatewayName, 'healthProbe')
}
}
}
]
httpListeners: [
{
name: 'httpsListener'
properties: {
frontendIPConfiguration: {
id: resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', appGatewayName, 'appGwFrontendPublicIp')
}
frontendPort: {
id: resourceId('Microsoft.Network/applicationGateways/frontendPorts', appGatewayName, 'httpsPort')
}
protocol: 'Https'
sslCertificate: {
id: resourceId('Microsoft.Network/applicationGateways/sslCertificates', appGatewayName, 'appGwSslCert')
}
hostNames: [
'www.contoso.com'
]
}
}
]
routingRules: [
{
name: 'pathBasedRule'
properties: {
ruleType: 'PathBasedRouting'
httpListener: {
id: resourceId('Microsoft.Network/applicationGateways/httpListeners', appGatewayName, 'httpsListener')
}
backendHttpSettings: {
id: resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', appGatewayName, 'httpsBackendSettings')
}
urlPathMap: {
id: resourceId('Microsoft.Network/applicationGateways/urlPathMaps', appGatewayName, 'urlPathMap')
}
}
}
]
urlPathMaps: [
{
name: 'urlPathMap'
properties: {
defaultBackendAddressPool: {
id: resourceId('Microsoft.Network/applicationGateways/backendAddressPools', appGatewayName, 'webBackendPool')
}
defaultBackendHttpSettings: {
id: resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', appGatewayName, 'httpsBackendSettings')
}
pathRules: [
{
name: 'apiPathRule'
properties: {
paths: [
'/api/*'
]
backendAddressPool: {
id: resourceId('Microsoft.Network/applicationGateways/backendAddressPools', appGatewayName, 'apiBackendPool')
}
backendHttpSettings: {
id: resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', appGatewayName, 'httpsBackendSettings')
}
}
}
]
}
}
]
sslCertificates: [
{
name: 'appGwSslCert'
properties: {
data: base64(certData) // Base64 encoded PFX certificate
password: certPassword
}
}
]
probes: [
{
name: 'healthProbe'
properties: {
protocol: 'Https'
path: '/health'
interval: 30
timeout: 30
unhealthyThreshold: 3
}
}
]
webApplicationFirewallConfiguration: {
enabled: true
firewallMode: 'Prevention'
wafPolicy: {
id: resourceId('Microsoft.Network/ApplicationGatewayWafPolicies', wafPolicyName)
}
}
}
}
resource wafPolicy 'Microsoft.Network/ApplicationGatewayWafPolicies@2023-05-01' = {
name: wafPolicyName
location: location
properties: {
customRules: [
{
name: 'RateLimitRule'
priority: 100
ruleType: 'RateLimitRule'
action: 'Block'
matchConditions: [
{
matchVariables: [
{
variableName: 'RemoteAddr'
}
]
operator: 'IPMatch'
negationConditon: false
matchValues: [
'0.0.0.0/0' // Apply to all IPs
]
}
]
rateLimitThreshold: 1000 // Requests per 5 minutes
rateLimitDurationInMinutes: 5
}
]
managedRules: {
managedRuleSets: [
{
ruleSetType: 'OWASP'
ruleSetVersion: '3.2'
ruleGroupOverrides: [
{
ruleGroupName: 'SQLInjection'
rules: [
{
ruleId: 942100
state: 'Disabled' // Temporarily disable a specific rule within a group for testing
}
]
}
]
}
]
}
}
}Common pitfalls
- Misconfiguring WAF Mode: Deploying WAF directly in "Prevention" mode without initial testing in "Detection" mode can lead to legitimate traffic being blocked, causing application outages. Always start in Detection mode to identify false positives.
- Ignoring WAF Logs: Not actively monitoring Application Gateway WAF logs (via Azure Monitor, Log Analytics) means missing critical security insights and the opportunity to fine-tune WAF rules, leading to either insufficient protection or excessive false positives.
- Incorrect Subnet Sizing: Application Gateway requires a dedicated subnet with sufficient IP addresses. Under-sizing the subnet can lead to deployment failures or an inability to scale the Application Gateway. Consult Microsoft Learn on Application Gateway subnet sizing.
- SSL Certificate Management: Forgetting to renew SSL certificates on the Application Gateway or using incorrect certificate formats can cause service disruptions and security warnings for users.
- Overly Aggressive WAF Rules: Implementing custom WAF rules or overriding managed rules without thorough understanding and testing can block legitimate application functions, leading to poor user experience or critical business process failures.
- Not Updating Managed Rule Sets: Relying solely on the initially configured managed rule set without considering new versions or updates means falling behind the evolving threat landscape. Microsoft regularly releases new OWASP Core Rule Set (CRS) versions.
Best practices
- Start with Detection Mode, Transition to Prevention: Following the Well-Architected Framework's Security pillar, deploy WAF in Detection mode first. Monitor logs extensively to identify legitimate traffic patterns and false positives. Only transition to Prevention mode once you are confident that real threats are blocked and legitimate traffic flows unimpeded.
- Integrate with Azure Monitor and Sentinel: Forward Application Gateway and WAF logs to Azure Monitor Log Analytics for centralized logging, analytics, and alerting. Integrate with Azure Sentinel for advanced threat detection, incident response, and correlation with other security signals, aligning with the Zero Trust principle.
- Leverage WAF Policies for Centralized Management: Use WAF Policies to define and manage security rules centrally. This approach, advocated by the Cloud Adoption Framework for management, allows for consistent WAF configurations across multiple Application Gateways, simplifying governance and reducing configuration drift.
- Regularly Review and Tune WAF Rules: Conduct periodic reviews of WAF rules and logs. If false positives occur, create specific exclusions or custom rules to allow legitimate traffic. Stay informed about new OWASP CRS versions and consider upgrading to benefit from enhanced protection.
- Implement End-to-End SSL/TLS: While Application Gateway can terminate SSL, it's a best practice to re-encrypt traffic to backend servers (end-to-end SSL) to protect data in transit within your VNet, aligning with the "assume breach" mentality of Zero Trust.
- Enable Diagnostics and Health Probes: Configure detailed diagnostic logging for Application Gateway. Utilize health probes with specific paths or headers to accurately assess the health of backend instances and ensure traffic is only routed to healthy endpoints, crucial for resilience as per the Well-Architected Framework's Reliability pillar.
- Automate Deployment with Infrastructure as Code (IaC): Use Bicep or Azure Resource Manager (ARM) templates to define and deploy your Application Gateway and WAF configurations. This ensures consistency, repeatability, and version control, supporting efficient operations within the Cloud Adoption Framework's DevOps guidance.
Further reading
Related articles
Designing an Azure Landing Zone
Apply Microsoft Cloud Adoption Framework to design an enterprise landing zone.
Hub-and-Spoke vs Virtual WAN: Which to Pick
Compare topology options and choose what fits your scale and complexity.
ExpressRoute vs Site-to-Site VPN
Performance, cost, and resiliency trade-offs for hybrid connectivity.