# How to front a Quake AI workload with a web application firewall

Source: https://docs.quake.ai/docs/network/how-to/front-with-waf
Markdown: https://docs.quake.ai/docs/network/how-to/front-with-waf.md

---

# How to front a Quake AI workload with a web application firewall

Put a web application firewall (WAF) in front of an HTTP workload so attack traffic (SQL injection, cross-site scripting, and other OWASP Top 10 patterns) is filtered before it reaches your instances, then lock the origin down so it accepts traffic only from the WAF.



Run a WAF on Quake AI by putting a CDN-layer WAF in front of your origin or by running a self-managed WAF engine on an instance.



<PrerequisiteBlock methods={["console", "cli"]}>

- A running HTTP or HTTPS workload on one or more instances
- The [security group](/docs/network/how-to/create-security-group) that controls inbound traffic to the workload
- A registered domain you can point at the WAF, with access to its DNS records
- For the CDN-layer option, an account with a CDN provider that offers a WAF (for example, Cloudflare or Fastly)

</PrerequisiteBlock>

## Pick a WAF layer

Two patterns put a WAF in front of a Quake AI workload. Pick one before you start.

| Decision factor | CDN-layer WAF (default) | Self-managed WAF on an instance |
|---|---|---|
| Where filtering runs | The CDN provider's edge network | An instance you operate on Quake AI |
| Who maintains the rules | The provider ships and updates managed rule sets | You install and update the engine and rule set |
| TLS termination | The CDN terminates TLS at the edge | The WAF instance terminates TLS |
| Added latency | An edge hop close to the client | One reverse-proxy hop inside the region |
| Public floating IPs | One, on the origin instance | One, on the WAF instance; backend instances stay private |
| Best for | Most public web workloads that want DDoS absorption and managed rules without running software | Teams with a specific engine, custom rule set, or data-residency requirement |

The CDN-layer WAF is the default recommendation: the provider runs and patches the filtering layer, absorbs volumetric traffic at the edge, and ships managed rule sets you enable per site. Choose the self-managed WAF when you need a specific engine such as ModSecurity or Coraza, a custom rule set, or filtering that stays inside the Quake AI region.

Both patterns share the same final step: lock the origin security group so it accepts web traffic only from the WAF. An origin reachable directly from the internet lets an attacker bypass the WAF, so this restriction is what makes either pattern effective.



Replace AWS WAF, ALB WAF integration, or GCP Cloud Armor with a CDN-layer WAF or a self-managed engine on Quake AI (see Pick a WAF layer above). Quake AI does not ship a first-party managed WAF product.



## Option A: Front the workload with a CDN-layer WAF

In this pattern the CDN provider terminates TLS at its edge, applies its WAF rules, and forwards clean requests to your origin instance or reverse proxy, reachable on one public floating IP.

### Configure the WAF at the CDN provider

The exact field names differ per provider. The shape is the same: add your site, set the origin to your Quake AI public address, then enable the WAF rule set.




1. Add your domain as a zone and move its authoritative DNS to the provider, or proxy the existing record.
2. Create a DNS record routed through the provider (the orange-cloud record) for the hostname, with the address set to your Quake AI origin floating IP.
3. Set the SSL/TLS mode to **Full (strict)** so the edge validates the origin certificate.
4. Under **Security** > **WAF**, enable the managed rule set and set the action for the OWASP Core Rule Set to **Managed Challenge** or **Block**.




1. Create a service and set the host to your Quake AI origin floating IP, with TLS to the origin enabled.
2. Attach a TLS certificate for your domain to the service so the edge terminates client TLS.
3. Enable the Next-Gen WAF (or the OWASP-based ruleset) on the service and set it to blocking mode.
4. Point your domain's DNS record at the provider's anycast addresses for the service.




After the provider reports the configuration as active, send a test request to your domain and confirm it resolves to the CDN edge, not directly to your origin.

### Point your domain at the WAF

Create the public DNS record for your hostname at your DNS provider so visitors resolve to the CDN edge:

- For a CDN that proxies through its own addresses, create a `CNAME` record pointing the hostname at the provider's edge hostname.
- For a CDN that fronts a fixed origin floating IP, create an `A` record per the provider's instructions.

Confirm propagation with `dig +short YOUR_HOSTNAME` before you lock the origin down, so you do not cut off your own testing path. For registrar-side steps, see [How to point a domain at a Quake AI resource](/docs/network/how-to/point-domain-to-quake-ai).

## Option B: Run a self-managed WAF on an instance

In this pattern you run a reverse proxy with an embedded WAF engine on a Quake AI instance. The proxy holds the single public floating IP, terminates TLS, filters requests, and forwards clean traffic to your backend instances on the private subnet. The backend instances keep no floating IP of their own.

For a [validated OpenTofu template](/docs/platform/validation#how-infrastructure-templates-are-checked) that provisions Caddy with automatic TLS and a private backend (without a WAF engine), see the [edge reverse proxy template](/resources/iac-templates/edge-reverse-proxy). Add ModSecurity, Coraza, or a dedicated WAF appliance on top of that front door, or follow the manual install steps below.

A common stack is Nginx with the ModSecurity connector and the OWASP Core Rule Set. Coraza is a drop-in alternative engine for Caddy or Envoy when you prefer a Go-based rule engine.

1. Launch an instance for the WAF on the same private subnet as your backends, and allocate one floating IP to it. See [How to allocate floating IPs](/docs/network/how-to/allocate-floating-ips).
2. Install the reverse proxy, the WAF connector, and the OWASP Core Rule Set, then set the engine to blocking mode (`SecRuleEngine On` for ModSecurity).
3. Configure the proxy to terminate TLS with your domain certificate and forward to the backend pool or instance address on the private subnet.
4. Point your domain's DNS `A` record at the WAF instance floating IP.



A WAF inspects decrypted requests, so TLS terminates at the WAF layer: the CDN edge in Option A or the proxy instance in Option B.



## Lock down the origin

This step is what makes the WAF effective. Restrict the workload's security group so it accepts web traffic (ports 80 and 443) only from the WAF, and remove any rule that allows those ports from `0.0.0.0/0`. The source depends on the pattern you chose:

- **CDN-layer WAF:** allow only the provider's published egress IP ranges. Add one rule per CIDR the provider lists for its WAF egress, and refresh them when the provider updates the list.
- **Self-managed WAF:** allow only the WAF instance, by referencing the WAF instance's security group as the source rather than a CIDR.

<MethodTabs>
<Method label="Console">

1. Go to **Network** > **Security Groups**, click the origin security group's ID or name link to open its detail page, then open the **Rules** tab.
2. On the **Rules** tab, delete any ingress rule that allows port 80 or 443 from source `0.0.0.0/0`.
3. Select **Create Rule** and add an HTTPS rule:
   - **Protocol**: **Custom TCP Rule**
   - **Port**: `443`
   - **Direction**: **Ingress**
   - **Source**: the WAF source. For a CDN, enter one provider egress CIDR. For a self-managed WAF, select **Security Group**; a second **Security** selector appears where you pick the WAF instance's security group.
4. Select **OK**. Repeat for port `80` if the WAF forwards plain HTTP, and repeat for each additional CDN egress CIDR.

For the field-by-field walkthrough of the Create Rule dialog, see [How to create security group rules](/docs/network/how-to/create-security-group-rules).

</Method>
<Method label="CLI">

Remove the open web rules, then allow only the WAF source. For a CDN-layer WAF, repeat the allow command once per published egress CIDR:

```bash
# Remove any ingress rule that opens 80/443 to the internet.
openstack security group rule list ORIGIN_SECURITY_GROUP -f value -c ID -c "Port Range" -c "IP Range"
openstack security group rule delete OPEN_HTTP_RULE_ID OPEN_HTTPS_RULE_ID

# CDN-layer WAF: allow only the provider's egress CIDR (repeat per range).
openstack security group rule create \
  --protocol tcp \
  --dst-port 443 \
  --remote-ip CDN_EGRESS_CIDR \
  ORIGIN_SECURITY_GROUP
```

For a self-managed WAF, allow the WAF instance's security group as the source instead of a CIDR:

```bash
openstack security group rule create \
  --protocol tcp \
  --dst-port 443 \
  --remote-group WAF_SECURITY_GROUP \
  ORIGIN_SECURITY_GROUP
```

Confirm the result lists only WAF sources on ports 80 and 443:

```bash
openstack security group rule list ORIGIN_SECURITY_GROUP
```

</Method>
</MethodTabs>

## Managed rules compared with custom rules

A WAF rule set decides which requests to block. Most deployments run a managed rule set and add a few custom rules on top.

- **Managed rule sets** ship from the CDN provider or the OWASP Core Rule Set project and cover broad attack classes (injection, cross-site scripting, protocol violations). The maintainer updates them as new patterns appear, so you inherit coverage without writing signatures. Start in a count or log-only mode, review what would have blocked legitimate traffic, then switch to blocking.
- **Custom rules** target your application: rate limits on a login path, an allowlist for an admin route, or a block for a request shape specific to your stack. Keep the custom set small and test each rule against real traffic, because an over-broad custom rule blocks legitimate users.

Run managed rules in blocking mode as the baseline and layer custom rules for application-specific cases. Tune false positives by adjusting rule severity or adding narrow exclusions rather than disabling a whole managed category.

## Verify the result

Confirm that traffic reaches the workload only through the WAF, and that the WAF blocks attack patterns:

1. **Clean traffic passes.** Request your site through the domain and confirm a normal response. The request flows client to WAF to origin.
2. **The WAF blocks attacks.** Send a request that matches a managed rule, for example a query string containing a known injection probe, and confirm the WAF returns a block response (typically `403`) instead of the application response.
3. **The origin rejects direct traffic.** From a host outside the WAF egress range, request the origin floating IP directly on port 443. The connection should time out or be refused, because the security group now allows only the WAF source. If the origin still answers, recheck the origin rules.

## See also

- [Edge reverse proxy template](/resources/iac-templates/edge-reverse-proxy)
- [How to put a CDN in front of a Quake AI workload](/docs/network/how-to/front-with-cdn)
- [How to create a security group](/docs/network/how-to/create-security-group)
- [How to create security group rules](/docs/network/how-to/create-security-group-rules)
- [How to allocate floating IPs](/docs/network/how-to/allocate-floating-ips)
- [Security group concepts](/docs/network/concepts/security-groups)
- [Network FAQ](/docs/network/faq)
