Tags: azure, ingress, application gateway, front door, web application firewall
Overview
Azure Web Application Firewall (WAF) provides centralized protection of your web applications from common exploits and vulnerabilities. Web applications are increasingly targeted by malicious attacks that exploit commonly known vulnerabilities. SQL injection and cross-site scripting are among the most common attacks.
WAF can be deployed with Azure Application Gateway and Azure Front Door service from Microsoft. WAF has features that are customized for each specific service.
Kublr provides full customization for integration Azure Front Door with WAF and Kuberntes NGNIX Ingress controller service.
Prerequisites
Ingress controller DNS record and SSL certificate
You will need to create DNS record for Ingress controller and provide a valid SSL certificate for this record. Please refer to Kublr documentation (https://docs.kublr.com/articles/tls-setup/) or Support portal article (https://support.kublr.com/support/solutions/articles/33000257554-let-s-enrypt-dns-solver-with-aws-route53-service)
To determine the health of ingress service for a given Front Door environment, each Front Door environment periodically sends a synthetic HTTP/HTTPS request to Kubernetes ingress controller. If you use HTTPS, your ingress
health probe host must have valid SSL Certificate (https://ccadb-public.secure.force.com/microsoft/IncludedCACertificateReportForMSFT).
You cannot use self-signed certificates when you are forwarding the traffic as HTTPS or HTTPS health probes or filling the cache for from origin for routing rules!
Certificate CN: For HTTPS connections, Front Door expects that your backend presents certificate from a valid CA with subject name(s) matching the backend hostname. You can disabling certificate subject name check for your Front Door.
Certificate CA: Only certificates from valid Certificate Authorities can be used at the backend with Front Door. Certificates from internal CAs or self-signed certificates aren't allowed. The certificate must have a complete certificate chain with leaf and intermediate certificates, and root CA must be part of the Microsoft Trusted CA List.
Ingress Controller LB DNS record: You will need to create A record in DNS for Kubernetes NGINX Ingress controller public LB IP address.
Workloads services DNS records: For each ingress hostname you will need to create CNAME records linked to Azure Front Door public DNS name (e.g. my-ingress-front-door.azurefd.net).
Azure WAF policy: You will need to create Web Application Firewall policy for FrontDoor in Azure console (https://docs.microsoft.com/en-us/azure/frontdoor/front-door-waf).
Kublr Cluster ARM Template extras
Azure FrontDoor Name: kublr-frontdoor
FrontDoor DNS: kublr-frontdoor-my-ingress-fqdn.azurefd.net
Kubernetes ingress public LB FQDN: ingress.kubernetes-ingress-domain.com
spec:
locations:
- name: azure1
azure:
armTemplateResourcesExtra:
- apiVersion: '2020-07-01'
location: Global
name: kublr-frontdoor
type: Microsoft.Network/frontdoors
properties:
cName: {kublr-frontdoor-my-ingress-fqdn}.azurefd.net
backendPoolsSettings:
enforceCertificateNameCheck: Disabled
backendPools:
- name: ingress
type: Microsoft.Network/Frontdoors/BackendPools
properties:
backends:
- address: ingress.{kubernetes-ingress-domain.com}
backendHostHeader: ''
httpPort: 80
httpsPort: 443
priority: 1
weight: 50
healthProbeSettings:
id: '[concat(''/subscriptions/'', subscription().subscriptionId, ''/resourceGroups/'', resourceGroup().name, ''/providers/Microsoft.Network/Frontdoors/kublr-frontdoor/HealthProbeSettings/ingress'')]'
loadBalancingSettings:
id: '[concat(''/subscriptions/'', subscription().subscriptionId, ''/resourceGroups/'', resourceGroup().name, ''/providers/Microsoft.Network/Frontdoors/kublr-frontdoor/LoadBalancingSettings/ingress-lb-0'')]'
frontendEndpoints:
- name: azurefd-net
type: Microsoft.Network/Frontdoors/FrontendEndpoints
properties:
hostName: {kublr-frontdoor-my-ingress-fqdn}.azurefd.net
sessionAffinityEnabledState: Enabled
sessionAffinityTtlSeconds: 0
healthProbeSettings:
- name: ingress
type: Microsoft.Network/Frontdoors/HealthProbeSettings
properties:
healthProbeMethod: HEAD
intervalInSeconds: 60
path: /healthz
protocol: Https
loadBalancingSettings:
- name: ingress-lb-0
type: Microsoft.Network/Frontdoors/LoadBalancingSettings
properties:
additionalLatencyMilliseconds: 0
sampleSize: 4
successfulSamplesRequired: 2
routingRules:
- name: ingress
properties:
acceptedProtocols:
- Https
- Http
enabledState: Enabled
frontendEndpoints:
- id: '[concat(''/subscriptions/'', subscription().subscriptionId, ''/resourceGroups/'', resourceGroup().name, ''/providers/Microsoft.Network/Frontdoors/kublr-frontdoor/FrontendEndpoints/azurefd-net'')]'
patternsToMatch:
- /*
routeConfiguration:
'@odata.type': '#Microsoft.Azure.FrontDoor.Models.FrontdoorForwardingConfiguration'
backendPool:
id: '[concat(''/subscriptions/'', subscription().subscriptionId, ''/resourceGroups/'', resourceGroup().name, ''/providers/Microsoft.Network/Frontdoors/kublr-frontdoor/backendPools/ingress'')]'
forwardingProtocol: HttpsOnly
type: Microsoft.Network/Frontdoors/RoutingRules
tags:
KubernetesCluster: Kublr-Cluster-NameWorkload service with WAF policy
Azure FrontDoor Name: kublr-frontdoor
Azure WAF policy for FrontDoor: MyWAFPolicy in waf-policy resource group
FrontDoor DNS: kublr-frontdoor-my-ingress-fqdn.azurefd.net
Workload FQDN: service.kubernetes-ingress-domain.com
You will need to create CNAME DNS record:
service.kubernetes-ingress-domain.com CNAME kublr-frontdoor-my-ingress-fqdn.azurefd.net
spec:
locations:
- name: azure1
azure:
armTemplateResourcesExtra:
- apiVersion: '2020-07-01'
location: Global
name: kublr-frontdoor
type: Microsoft.Network/frontdoors
properties:
...
frontendEndpoints:
...
- name: service
type: Microsoft.Network/Frontdoors/FrontendEndpoints
properties:
hostName: service.kuberntes-ingress-domain.com
sessionAffinityEnabledState: Enabled
sessionAffinityTtlSeconds: 0
webApplicationFirewallPolicyLink:
id: '[concat(''/subscriptions/'', subscription().subscriptionId, ''/resourceGroups/'', ''waf-policy'', ''/providers/Microsoft.Network/frontdoorwebapplicationfirewallpolicies/MyWAFPolicy'')]'
...
routingRules:
- name: ingress
properties:
acceptedProtocols:
- Https
enabledState: Enabled
frontendEndpoints:
...
- id: '[concat(''/subscriptions/'', subscription().subscriptionId, ''/resourceGroups/'', resourceGroup().name, ''/providers/Microsoft.Network/Frontdoors/kublr-frontdoor/FrontendEndpoints/service'')]'Workload enable SSL termination on FrontDoor
Azure FrontDoor Name: kublr-frontdoor
Workload FQDN: service.kubernetes-ingress-domain.com
spec:
locations:
- name: azure1
azure:
armTemplateResourcesExtra:
- apiVersion: '2020-07-01'
type: Microsoft.Network/frontdoors/frontendEndpoints/customHttpsConfiguration
name: kublr-frontdoor/{service}/default
dependsOn:
- '[resourceId(''Microsoft.Network/frontdoors'', ''kublr-frontdoor'')]'
properties:
certificateSource: FrontDoor
frontDoorCertificateSourceParameters:
certificateType: Dedicated
minimumTlsVersion: 1.2
protocolType: ServerNameIndication
tags:
KubernetesCluster: My-Kubernetes-ClusterNameCustomize Ingress service firewall rules
This can be done via chart parameters controller.service.annotations etc as shown below in Kublr cluster specification snippet:
spec:
features:
ingress:
values:
nginx-ingress:
controller:
service:
annotations:
service.beta.kubernetes.io/azure-allowed-service-tags: 'AzureFrontDoor.Backend'
enableHttp: false