<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic URI Rewrite - Complete Implementation Reference in WAF</title>
    <link>https://community.checkpoint.com/t5/WAF/URI-Rewrite-Complete-Implementation-Reference/m-p/275721#M398</link>
    <description>&lt;H2 id="what-is-uri-rewriting-and-why-does-it-matter" class="code-line" dir="auto" data-line="7"&gt;What is URI Rewriting and Why Does it Matter?&lt;/H2&gt;
&lt;P class="code-line" data-line="9"&gt;A&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;URI rewrite&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is the act of changing the request path — silently, server-side — before it reaches the upstream application. The client sends one URL; the backend receives a different one. No redirect is issued; the client is unaware.&lt;/P&gt;
&lt;H3 id="why-it-is-needed" class="code-line" dir="auto" data-line="11"&gt;Why it is needed&lt;/H3&gt;
&lt;P class="code-line" data-line="13"&gt;Real-world deployments rarely have a clean 1:1 mapping between the public URL structure and the backend's internal URL structure. URI rewriting bridges that gap without requiring changes to either the client or the backend.&lt;/P&gt;
&lt;H3 id="common-use-cases" class="code-line" dir="auto" data-line="15"&gt;Common use cases&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="17"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="17"&gt;
&lt;TR class="code-line" dir="auto" data-line="17"&gt;
&lt;TH&gt;Use case&lt;/TH&gt;
&lt;TH&gt;Example&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="19"&gt;
&lt;TR class="code-line" dir="auto" data-line="19"&gt;
&lt;TD&gt;&lt;STRONG&gt;Expose a sub-path publicly, serve from root&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Public:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→ Backend:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/*&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="20"&gt;
&lt;TD&gt;&lt;STRONG&gt;Version translation&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Public:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api/v1/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→ Backend:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/v1/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(strip the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;prefix a gateway added)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="21"&gt;
&lt;TD&gt;&lt;STRONG&gt;Legacy URL migration&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Old:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/old-endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→ New:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/new-endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(keep old clients working)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="22"&gt;
&lt;TD&gt;&lt;STRONG&gt;Path normalization&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Add a prefix the backend expects:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/public/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/static/public/*&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="23"&gt;
&lt;TD&gt;&lt;STRONG&gt;Segment reordering&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;REST to internal:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/users/42/profile&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/profile/42&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="24"&gt;
&lt;TD&gt;&lt;STRONG&gt;Multi-service routing&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;One WAF asset routes&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/payments/*&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/orders/*&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/catalog/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to separate upstreams by rewriting paths&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="25"&gt;
&lt;TD&gt;&lt;STRONG&gt;WAF in front of a legacy app&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;The app was built with a hard-coded path structure that can't be changed; the WAF adapts incoming paths to match it&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="uri-rewrite-vs-redirect--key-distinction" class="code-line" dir="auto" data-line="27"&gt;URI rewrite vs redirect — key distinction&lt;/H3&gt;
&lt;P class="code-line" data-line="29"&gt;A&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;rewrite&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is invisible to the client (internal, server-side). A&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;redirect&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;tells the client to issue a new request to a different URL (HTTP 301/302, client-visible). For reverse proxy scenarios, you almost always want a rewrite — the client should not know or care about the backend's internal path structure.&lt;/P&gt;
&lt;HR data-line="31" /&gt;
&lt;H2 id="table-of-contents" class="code-line" dir="auto" data-line="33"&gt;Table of Contents&lt;/H2&gt;
&lt;OL class="code-line" dir="auto" data-line="35"&gt;
&lt;LI class="code-line" dir="auto" data-line="35"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#1-architecture-overview" target="_blank" rel="noopener" data-href="#1-architecture-overview"&gt;Architecture Overview&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="36"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#2-how-cloudguard-waf-manages-nginx" target="_blank" rel="noopener" data-href="#2-how-cloudguard-waf-manages-nginx"&gt;How CloudGuard WAF Manages NGINX&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="37"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#3-the-two-injection-points" target="_blank" rel="noopener" data-href="#3-the-two-injection-points"&gt;The Two Injection Points&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="38"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#4-what-uri-rewrite-means-in-this-context" target="_blank" rel="noopener" data-href="#4-what-uri-rewrite-means-in-this-context"&gt;What URI Rewrite Means in This Context&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="39"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#5-critical-limitation-request_uri-vs-uri" target="_blank" rel="noopener" data-href="#5-critical-limitation-request_uri-vs-uri"&gt;Critical Limitation: $request_uri vs $uri&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="40"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#6-the-workaround-per-path-location-blocks-with-literal-proxy_pass" target="_blank" rel="noopener" data-href="#6-the-workaround-per-path-location-blocks-with-literal-proxy_pass"&gt;The Workaround: Per-Path Location Blocks with Literal proxy_pass&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="41"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#7-location-block-file-reference" target="_blank" rel="noopener" data-href="#7-location-block-file-reference"&gt;Location Block File Reference&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="42"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#8-the-rewrite-directive-in-depth" target="_blank" rel="noopener" data-href="#8-the-rewrite-directive-in-depth"&gt;The rewrite Directive In Depth&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="43"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#9-nginx-variables-available-inside-the-location-block" target="_blank" rel="noopener" data-href="#9-nginx-variables-available-inside-the-location-block"&gt;NGINX Variables Available Inside the Location Block&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="44"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#10-setting-the-host-header" target="_blank" rel="noopener" data-href="#10-setting-the-host-header"&gt;Setting the Host Header&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="45"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#11-rewrite-pattern-catalogue" target="_blank" rel="noopener" data-href="#11-rewrite-pattern-catalogue"&gt;Rewrite Pattern Catalogue&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="46"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#12-generated-nginx-artifacts" target="_blank" rel="noopener" data-href="#12-generated-nginx-artifacts"&gt;Generated NGINX Artifacts&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="47"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#13-deployment-procedure-infinity-portal" target="_blank" rel="noopener" data-href="#13-deployment-procedure-infinity-portal"&gt;Deployment Procedure (Infinity Portal)&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="48"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#14-validation-and-testing" target="_blank" rel="noopener" data-href="#14-validation-and-testing"&gt;Validation and Testing&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="49"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#15-logging-implications" target="_blank" rel="noopener" data-href="#15-logging-implications"&gt;Logging Implications&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="50"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#16-troubleshooting-guide" target="_blank" rel="noopener" data-href="#16-troubleshooting-guide"&gt;Troubleshooting Guide&lt;/A&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;HR data-line="52" /&gt;
&lt;H2 id="1-architecture-overview" class="code-line" dir="auto" data-line="54"&gt;1. Architecture Overview&lt;/H2&gt;
&lt;P class="code-line" data-line="56"&gt;CloudGuard WAF operates as an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;L7 reverse proxy&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in front of upstream application servers. All client traffic is routed through the WAF; the WAF inspects, optionally transforms, and forwards requests to the upstream.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="58"&gt;  Client (browser / curl / API)
          │
          │  HTTP/HTTPS  (public DNS, e.g. jwt.cpwaf.net)
          ▼
  ┌───────────────────────────────────────────────────────┐
  │           CloudGuard WAF — AppSec Gateway             │
  │                                                       │
  │  nginx (WAF-managed)                                  │
  │  ┌─────────────────────────────────────────────────┐  │
  │  │  server block: jwt.cpwaf.net:80/443           │  │
  │  │  location / {                                   │  │
  │  │    [Additional Location Block injected here]    │  │
  │  │    proxy_pass $upstream_endpoint$request_uri;   │  │ ← generated
  │  │  }                                              │  │
  │  └─────────────────────────────────────────────────┘  │
  └───────────────────────────────────────────────────────┘
          │
          │  HTTP  (internal / private network)
          │  Host: &amp;lt;as configured&amp;gt;
          ▼
  ┌─────────────────────────────┐
  │  Upstream Backend           │
  │  e.g. 51.4.115.60:8080         │
  └─────────────────────────────┘
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="85"&gt;&lt;STRONG&gt;Key facts:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="86"&gt;
&lt;LI class="code-line" dir="auto" data-line="86"&gt;The WAF terminates the client connection and opens a new connection to the upstream.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="87"&gt;URI rewriting happens&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inside the WAF&lt;/STRONG&gt;, before the upstream sees the request.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="88"&gt;The client never observes the rewrite (no HTTP redirect is issued).&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="89"&gt;The upstream receives the rewritten URI, not the original client URI.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR data-line="91" /&gt;
&lt;H2 id="2-how-cloudguard-waf-manages-nginx" class="code-line" dir="auto" data-line="93"&gt;2. How CloudGuard WAF Manages NGINX&lt;/H2&gt;
&lt;P class="code-line" data-line="95"&gt;CloudGuard WAF runs&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;nginx&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;as its proxy engine. Unlike self-managed nginx deployments, the admin&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;cannot directly edit&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;nginx.conf&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or any generated server block file. The WAF management plane (Infinity Portal) owns these files and regenerates them on every policy enforce.&lt;/P&gt;
&lt;H3 id="what-is-auto-generated-and-what-is-user-controlled" class="code-line" dir="auto" data-line="97"&gt;What is auto-generated and what is user-controlled&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="99"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="99"&gt;
&lt;TR class="code-line" dir="auto" data-line="99"&gt;
&lt;TH&gt;File / Component&lt;/TH&gt;
&lt;TH&gt;Who controls it&lt;/TH&gt;
&lt;TH&gt;Editable by admin?&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="101"&gt;
&lt;TR class="code-line" dir="auto" data-line="101"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/nginx.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="102"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No — overwritten on enforce&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="103"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;User&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(via Portal upload)&lt;/TD&gt;
&lt;TD&gt;Yes — this is the injection point&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="104"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/nginx/modules/*.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="105"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/error-pages/&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;BLOCKQUOTE class="code-line" dir="auto" data-line="107"&gt;
&lt;P class="code-line" data-line="107"&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Even if you manually edit a generated server conf on the gateway host, those changes are&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;overwritten&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the next time you enforce a policy from the Infinity Portal. The only durable injection point is the Additional Location Block / Additional Server Block upload.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="generated-server-block-structure" class="code-line" dir="auto" data-line="109"&gt;Generated server block structure&lt;/H3&gt;
&lt;P class="code-line" data-line="111"&gt;For a WAF asset listening on port 80 for&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;jwt.cpwaf.net&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;proxying to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;51.4.115.60:8080&lt;/CODE&gt;, CloudGuard generates a file at:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="113"&gt;/etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="117"&gt;The relevant excerpt looks like this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="119"&gt;&lt;SPAN class="hljs-section"&gt;server&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;listen&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;80&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;server_name&lt;/SPAN&gt; jwt.cpwaf.net;

    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_headers&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_body&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;

    &lt;SPAN class="hljs-comment"&gt;# ONLY present because "Host: cpfakedomain.com" was added under&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# Advanced Proxy Settings -&amp;gt; Custom Headers in the Portal.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# Without that setting this line does NOT appear in the generated config.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;

    &lt;SPAN class="hljs-attribute"&gt;resolver&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;168.63.129.16&lt;/SPAN&gt; ipv6=&lt;SPAN class="hljs-literal"&gt;off&lt;/SPAN&gt;;

    &lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; / {
        &lt;SPAN class="hljs-attribute"&gt;include&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_5_additional_location_config.conf;

        &lt;SPAN class="hljs-attribute"&gt;set&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt; http://51.4.115.60:8080;
        &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$request_uri&lt;/SPAN&gt;;   &lt;SPAN class="hljs-comment"&gt;# ← see Section 5&lt;/SPAN&gt;

        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; X-Forwarded-For &lt;SPAN class="hljs-variable"&gt;$proxy_add_x_forwarded_for&lt;/SPAN&gt;;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Upgrade &lt;SPAN class="hljs-variable"&gt;$http_upgrade&lt;/SPAN&gt;;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Connection &lt;SPAN class="hljs-string"&gt;"Upgrade"&lt;/SPAN&gt;;
    }
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="147"&gt;The include file (&lt;CODE&gt;waf_N_additional_location_config.conf&lt;/CODE&gt;) is where your uploaded Additional Location Block content lands. The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is an internal counter assigned by the WAF management plane — it is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;not predictable&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in advance and may change across policy enforces.&lt;/P&gt;
&lt;P class="code-line" data-line="149"&gt;To find which include file belongs to your asset at any point in time:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="151"&gt;sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="155" /&gt;
&lt;H2 id="3-the-two-injection-points" class="code-line" dir="auto" data-line="157"&gt;3. The Two Injection Points&lt;/H2&gt;
&lt;P class="code-line" data-line="159"&gt;Navigate to:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Infinity Portal → Policy → [Your Asset] → Advanced Proxy Settings&lt;/STRONG&gt;&lt;/P&gt;
&lt;H3 id="31-additional-location-block-instructions" class="code-line" dir="auto" data-line="161"&gt;3.1 Additional Location Block Instructions&lt;/H3&gt;
&lt;P class="code-line" data-line="163"&gt;Content is injected&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inside the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block&lt;/STRONG&gt;, before the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directive.&lt;/P&gt;
&lt;P class="code-line" data-line="165"&gt;&lt;STRONG&gt;Allowed directives:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="166"&gt;
&lt;LI class="code-line" dir="auto" data-line="166"&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="167"&gt;&lt;CODE&gt;set&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="168"&gt;&lt;CODE&gt;add_header&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="169"&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="170"&gt;&lt;CODE&gt;sub-&lt;/CODE&gt;location blocks (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location ~ ^/path { ... }&lt;/CODE&gt;) —&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;with caveats, see Section 6&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="171"&gt;Most per-request nginx directives&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="code-line" data-line="173"&gt;&lt;STRONG&gt;NOT allowed (will cause nginx config test failure):&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="174"&gt;
&lt;LI class="code-line" dir="auto" data-line="174"&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— server-level block; belongs in Server Block&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="175"&gt;&lt;CODE&gt;http { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— global block; not injectable&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="176"&gt;&lt;CODE&gt;upstream { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— not injectable; use the Portal's Reverse Proxy settings&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="177"&gt;Bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;without a specific&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;wrapper —&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;partially allowed but ineffective; see Section 5&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="32-additional-server-block-instructions" class="code-line" dir="auto" data-line="179"&gt;3.2 Additional Server Block Instructions&lt;/H3&gt;
&lt;P class="code-line" data-line="181"&gt;Content is injected&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inside the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block&lt;/STRONG&gt;, outside of any&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;.&lt;/P&gt;
&lt;P class="code-line" data-line="183"&gt;Use this for:&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="184"&gt;
&lt;LI class="code-line" dir="auto" data-line="184"&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives you want to apply to all locations&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="185"&gt;&lt;CODE&gt;map&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks (though&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;map&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is technically an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http&lt;/CODE&gt;-level directive in standard nginx — behavior may vary)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="186"&gt;Custom error pages&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="187"&gt;Access log configuration&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="33-custom-headers-proxy-settings" class="code-line" dir="auto" data-line="189"&gt;3.3 Custom Headers (Proxy Settings)&lt;/H3&gt;
&lt;P class="code-line" data-line="191"&gt;The Portal also provides a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Custom Headers&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;table (under Advanced Proxy Settings → Add custom headers). Headers added here are rendered as&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives at the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;server block level&lt;/STRONG&gt;, so they apply to every proxied request for that asset.&lt;/P&gt;
&lt;P class="code-line" data-line="193"&gt;&lt;STRONG&gt;This is the recommended way to set the upstream&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(see Section 10). Using Custom Headers is officially supported; manually writing&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inside the Additional Location Block is a workaround.&lt;/P&gt;
&lt;HR data-line="195" /&gt;
&lt;H2 id="4-what-uri-rewrite-means-in-this-context" class="code-line" dir="auto" data-line="197"&gt;4. What URI Rewrite Means in This Context&lt;/H2&gt;
&lt;P class="code-line" data-line="199"&gt;There are four distinct operations that are often conflated. Understanding the difference is essential before writing any rewrite rule.&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="201"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="201"&gt;
&lt;TR class="code-line" dir="auto" data-line="201"&gt;
&lt;TH&gt;Operation&lt;/TH&gt;
&lt;TH&gt;What happens&lt;/TH&gt;
&lt;TH&gt;Client sees redirect?&lt;/TH&gt;
&lt;TH&gt;Upstream sees rewritten path?&lt;/TH&gt;
&lt;TH&gt;Where to configure&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="203"&gt;
&lt;TR class="code-line" dir="auto" data-line="203"&gt;
&lt;TD&gt;&lt;STRONG&gt;Internal URI rewrite&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;WAF changes&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;before forwarding&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;TD&gt;Yes&lt;/TD&gt;
&lt;TD&gt;Additional Location Block (&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="204"&gt;
&lt;TD&gt;&lt;STRONG&gt;Client redirect&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;WAF sends HTTP 301/302 to client&lt;/TD&gt;
&lt;TD&gt;Yes&lt;/TD&gt;
&lt;TD&gt;No (client re-requests)&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;rewrite ... redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;return 301&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="205"&gt;
&lt;TD&gt;&lt;STRONG&gt;Upstream path via proxy_pass URL&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;proxy_pass appends a fixed path prefix&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;TD&gt;Yes (prefix substitution only)&lt;/TD&gt;
&lt;TD&gt;Portal Reverse Proxy URL field&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="206"&gt;
&lt;TD&gt;&lt;STRONG&gt;Server block routing&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Different location blocks handle different paths&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;TD&gt;Depends on location&lt;/TD&gt;
&lt;TD&gt;Additional Location Block (nested&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="code-line" data-line="208"&gt;For CloudGuard WAF reverse proxy URI rewriting, you almost always want&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;internal URI rewrite&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— the client sends&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/old-path&lt;/CODE&gt;, the WAF forwards&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/new-path&lt;/CODE&gt;, the client is unaware.&lt;/P&gt;
&lt;HR data-line="210" /&gt;
&lt;H2 id="5-critical-limitation-request_uri-vs-uri" class="code-line" dir="auto" data-line="212"&gt;5. Critical Limitation:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;vs&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/H2&gt;
&lt;P class="code-line" data-line="214"&gt;This is the most important technical detail when implementing rewrites in CloudGuard WAF, and the source of the most common failure mode.&lt;/P&gt;
&lt;H3 id="how-nginx-handles-uri-variables" class="code-line" dir="auto" data-line="216"&gt;How nginx handles URI variables&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="218"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="218"&gt;
&lt;TR class="code-line" dir="auto" data-line="218"&gt;
&lt;TH&gt;Variable&lt;/TH&gt;
&lt;TH&gt;What it contains&lt;/TH&gt;
&lt;TH&gt;Modified by&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;?&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="220"&gt;
&lt;TR class="code-line" dir="auto" data-line="220"&gt;
&lt;TD&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Current normalized URI (path only, no query string)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Yes&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— updated each time a rewrite fires&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="221"&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Original URI as sent by client (path + query string)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;No&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— read-only, never changes&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="222"&gt;
&lt;TD&gt;&lt;CODE&gt;$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Query string (without&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;)&lt;/TD&gt;
&lt;TD&gt;No — but preserved by&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flag&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="223"&gt;
&lt;TD&gt;&lt;CODE&gt;$is_args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;if query string exists, empty otherwise&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="the-problem-with-cloudguards-generated-proxy_pass" class="code-line" dir="auto" data-line="225"&gt;The problem with CloudGuard's generated proxy_pass&lt;/H3&gt;
&lt;P class="code-line" data-line="227"&gt;CloudGuard WAF generates the following inside the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="229"&gt;&lt;SPAN class="hljs-attribute"&gt;set&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt; http://51.4.115.60:8080;
&lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$request_uri&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="234"&gt;Because&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;uses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;, it always forwards the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;original&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;client URI — regardless of any&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directive that fires before it.&lt;/P&gt;
&lt;P class="code-line" data-line="236"&gt;&lt;STRONG&gt;Example:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="238"&gt;Client request:   GET /chatbot/items HTTP/1.1

rewrite fires:    $uri         = /items   ← updated ✓
                  $request_uri = /chatbot/items  ← unchanged ✗

proxy_pass sends: GET /chatbot/items   ← rewrite had zero effect
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="247"&gt;&lt;STRONG&gt;This means: bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives placed in the Additional Location Block have no effect on what the upstream receives when proxy_pass uses a variable like&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$upstream_endpoint$request_uri&lt;/CODE&gt;.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="code-line" data-line="249"&gt;This is not a bug in nginx — it is the documented behavior when&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;references&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;explicitly. It becomes a limitation in CloudGuard WAF because the admin cannot change the generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;line.&lt;/P&gt;
&lt;H3 id="why-uriis_argsargs-would-fix-it" class="code-line" dir="auto" data-line="251"&gt;Why&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri$is_args$args&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;would fix it&lt;/H3&gt;
&lt;P class="code-line" data-line="253"&gt;If CloudGuard generated:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="254"&gt;&lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$uri&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$is_args&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$args&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="257"&gt;Then bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;rules in the Additional Location Block would work as expected, because&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is rewrite-aware. This is the correct approach for a rewrite-capable reverse proxy, but it is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;not what CloudGuard currently generates&lt;/STRONG&gt;.&lt;/P&gt;
&lt;HR data-line="259" /&gt;
&lt;H2 id="6-the-workaround-per-path-location-blocks-with-literal-proxy_pass" class="code-line" dir="auto" data-line="261"&gt;6. The Workaround: Per-Path Location Blocks with Literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;/H2&gt;
&lt;P class="code-line" data-line="263"&gt;Because bare rewrite rules are ineffective (see Section 5), the working approach is to define&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;sub-location blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inside the Additional Location Block file. Each sub-location block:&lt;/P&gt;
&lt;OL class="code-line" dir="auto" data-line="265"&gt;
&lt;LI class="code-line" dir="auto" data-line="265"&gt;Matches a specific path pattern&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="266"&gt;Applies the rewrite&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="267"&gt;Uses a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;literal&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;URL (not a variable) pointing directly to the upstream&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="code-line" data-line="269"&gt;When&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is specified as a literal URL (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;) and a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fires in the same location, nginx uses the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;rewritten&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— not&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— as the upstream path. This is documented nginx behavior for literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;+&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite break&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="271"&gt;&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;    &lt;SPAN class="hljs-comment"&gt;# literal URL → respects $uri after rewrite&lt;/SPAN&gt;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="how-it-works" class="code-line" dir="auto" data-line="278"&gt;How it works&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="280"&gt;Client request:   GET /chatbot/items HTTP/1.1

nginx matches:    location ~ ^/chatbot  ✓
rewrite fires:    $uri = /items
proxy_pass:       literal URL → nginx appends $uri
upstream receives: GET /items HTTP/1.1  ✓
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="why-this-works-but-proxy_pass-varrequest_uri-does-not" class="code-line" dir="auto" data-line="289"&gt;Why this works but&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass $var$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;does not&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="291"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="291"&gt;
&lt;TR class="code-line" dir="auto" data-line="291"&gt;
&lt;TH&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;form&lt;/TH&gt;
&lt;TH&gt;URI appended to upstream&lt;/TH&gt;
&lt;TH&gt;Rewrite-aware?&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="293"&gt;
&lt;TR class="code-line" dir="auto" data-line="293"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://backend" target="_blank" rel="noopener"&gt;http://backend&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(literal, no path)&lt;/TD&gt;
&lt;TD&gt;Rewritten&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;+&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$is_args$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Yes&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="294"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://backend/" target="_blank" rel="noopener"&gt;http://backend/&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(literal, with trailing slash)&lt;/TD&gt;
&lt;TD&gt;Replaces location prefix&lt;/TD&gt;
&lt;TD&gt;Yes (but path manipulation is prefix-based)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="295"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass $variable;&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(original, unmodified)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;No&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="296"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass $variable$request_uri;&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;No&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;BLOCKQUOTE class="code-line" dir="auto" data-line="298"&gt;
&lt;P class="code-line" data-line="298"&gt;&lt;STRONG&gt;Status:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This is an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inferred workaround&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;based on nginx's documented behavior and confirmed through testing on a live CloudGuard WAF deployment. It is not explicitly documented in Check Point's official CloudGuard WAF documentation as of the writing of this guide.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="constraint-the-upstream-ip-must-be-hardcoded" class="code-line" dir="auto" data-line="300"&gt;Constraint: the upstream IP must be hardcoded&lt;/H3&gt;
&lt;P class="code-line" data-line="302"&gt;The sub-location&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;must reference the upstream directly (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;). You cannot reference the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$upstream_endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;variable that CloudGuard defines, because using a variable in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reintroduces the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;problem.&lt;/P&gt;
&lt;P class="code-line" data-line="304"&gt;If your upstream IP changes, you must update the Additional Location Block file and re-enforce.&lt;/P&gt;
&lt;HR data-line="306" /&gt;
&lt;H2 id="7-location-block-file-reference" class="code-line" dir="auto" data-line="308"&gt;7. Location Block File Reference&lt;/H2&gt;
&lt;H3 id="file-format" class="code-line" dir="auto" data-line="310"&gt;File format&lt;/H3&gt;
&lt;P class="code-line" data-line="312"&gt;The Additional Location Block file is a plain text file containing nginx directives. There is no wrapping&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block in the file itself — the content is injected directly inside the generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;.&lt;/P&gt;
&lt;P class="code-line" data-line="314"&gt;However, when using the sub-location workaround, you&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;do&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;include&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks in the file. These become nested locations inside&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;.&lt;/P&gt;
&lt;H3 id="what-to-put-in-the-file" class="code-line" dir="auto" data-line="316"&gt;What to put in the file&lt;/H3&gt;
&lt;P class="code-line" data-line="318"&gt;&lt;STRONG&gt;Pattern A — Bare rewrite (only effective if you can modify proxy_pass, or for redirect use cases):&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="320"&gt;&lt;SPAN class="hljs-comment"&gt;# This is INEFFECTIVE for upstream path rewriting in CloudGuard WAF&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# because proxy_pass uses $request_uri&lt;/SPAN&gt;
&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-path$&lt;/SPAN&gt; /new-path &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="326"&gt;&lt;STRONG&gt;Pattern B — Sub-location with literal proxy_pass (the working workaround):&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="328"&gt;&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/old-path&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-path/?(.*)$&lt;/SPAN&gt; /new-path/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="file-constraints" class="code-line" dir="auto" data-line="335"&gt;File constraints&lt;/H3&gt;
&lt;UL class="code-line" dir="auto" data-line="337"&gt;
&lt;LI class="code-line" dir="auto" data-line="337"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— nginx rejects these inside a location context&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="338"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— same reason&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="339"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;upstream { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— these are http-level; use the Portal's Reverse Proxy settings&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="340"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;include&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— the file is already an include; recursive includes are not supported by the Portal upload mechanism&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="341"&gt;&lt;STRONG&gt;Avoid unicode characters in comments&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— some CloudGuard nginx builds reject non-ASCII characters in config files, causing nginx config test failure and HTTP 500 on all requests. Use only ASCII in comments.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="342"&gt;&lt;STRONG&gt;Always use ASCII&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;-&amp;gt;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;not&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;→&lt;/CODE&gt;&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in comments for the same reason.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="verifying-the-file-was-applied" class="code-line" dir="auto" data-line="344"&gt;Verifying the file was applied&lt;/H3&gt;
&lt;P class="code-line" data-line="346"&gt;SSH to the gateway and run:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="348"&gt;&lt;SPAN class="hljs-comment"&gt;# Find which include file belongs to your asset&lt;/SPAN&gt;
sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf

&lt;SPAN class="hljs-comment"&gt;# Read the file&lt;/SPAN&gt;
sudo &lt;SPAN class="hljs-built_in"&gt;cat&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf

&lt;SPAN class="hljs-comment"&gt;# Test nginx config validity&lt;/SPAN&gt;
sudo nginx -t
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="359"&gt;If&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;nginx -t&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fails, the enforce in the Portal will have produced a 500 error on all requests to that asset.&lt;/P&gt;
&lt;HR data-line="361" /&gt;
&lt;H2 id="8-the-rewrite-directive-in-depth" class="code-line" dir="auto" data-line="363"&gt;8. The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Directive In Depth&lt;/H2&gt;
&lt;H3 id="full-syntax" class="code-line" dir="auto" data-line="365"&gt;Full syntax&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="367"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt; regex replacement [flag];
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;TABLE class="code-line" dir="auto" data-line="371"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="371"&gt;
&lt;TR class="code-line" dir="auto" data-line="371"&gt;
&lt;TH&gt;Part&lt;/TH&gt;
&lt;TH&gt;Description&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="373"&gt;
&lt;TR class="code-line" dir="auto" data-line="373"&gt;
&lt;TD&gt;&lt;CODE&gt;regex&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;PCRE regular expression matched against&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(path only, no query string)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="374"&gt;
&lt;TD&gt;&lt;CODE&gt;replacement&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;The new URI. Can reference capture groups via&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$1&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$2&lt;/CODE&gt;, etc.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="375"&gt;
&lt;TD&gt;&lt;CODE&gt;flag&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Controls what happens after the rewrite. See flags below.&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="flags" class="code-line" dir="auto" data-line="377"&gt;Flags&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="379"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="379"&gt;
&lt;TR class="code-line" dir="auto" data-line="379"&gt;
&lt;TH&gt;Flag&lt;/TH&gt;
&lt;TH&gt;Behavior&lt;/TH&gt;
&lt;TH&gt;Use in CloudGuard WAF&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="381"&gt;
&lt;TR class="code-line" dir="auto" data-line="381"&gt;
&lt;TD&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Stop processing rewrite rules. Proceed with the current location using the new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;. When combined with a literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;, forwards the rewritten&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to upstream.&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Use this for upstream path rewriting.&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="382"&gt;
&lt;TD&gt;&lt;CODE&gt;last&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Stop processing rewrite rules. Re-initiate location matching with the new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;. Can match a different location block.&lt;/TD&gt;
&lt;TD&gt;Use with caution — can cause loops. Not recommended for proxy rewrites.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="383"&gt;
&lt;TD&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Issue HTTP 302 to the client with the replacement as the Location header.&lt;/TD&gt;
&lt;TD&gt;Use when you want the client to follow a new URL.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="384"&gt;
&lt;TD&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Issue HTTP 301 to the client.&lt;/TD&gt;
&lt;TD&gt;Use for permanent client-visible redirects.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="385"&gt;
&lt;TD&gt;&lt;EM&gt;(none)&lt;/EM&gt;&lt;/TD&gt;
&lt;TD&gt;Continue processing subsequent rewrite rules. The last matching rule applies.&lt;/TD&gt;
&lt;TD&gt;Useful for chaining, but the final&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;will still use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="regex-syntax-pcre" class="code-line" dir="auto" data-line="387"&gt;Regex syntax (PCRE)&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="389"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="389"&gt;
&lt;TR class="code-line" dir="auto" data-line="389"&gt;
&lt;TH&gt;Construct&lt;/TH&gt;
&lt;TH&gt;Meaning&lt;/TH&gt;
&lt;TH&gt;Example&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="391"&gt;
&lt;TR class="code-line" dir="auto" data-line="391"&gt;
&lt;TD&gt;&lt;CODE&gt;^&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Anchor: start of string&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/api&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches URIs starting with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="392"&gt;
&lt;TD&gt;&lt;CODE&gt;$&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Anchor: end of string&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;/endpoint$&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches URIs ending with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/endpoint&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="393"&gt;
&lt;TD&gt;&lt;CODE&gt;(.*)&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Capture group: zero or more of any character&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/chatbot/(.*)$&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;captures everything after&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot/&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="394"&gt;
&lt;TD&gt;&lt;CODE&gt;([^/]+)&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Capture group: one or more non-slash characters&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/users/([^/]+)/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;captures a path segment&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="395"&gt;
&lt;TD&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Makes the preceding character optional&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;/?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches optional trailing slash&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="396"&gt;
&lt;TD&gt;&lt;CODE&gt;$1&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$2&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Backreference to 1st, 2nd capture group&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;/$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inserts first captured group&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="397"&gt;
&lt;TD&gt;&lt;CODE&gt;\.&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Escaped dot (literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.&lt;/CODE&gt;)&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;\.json$&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches URIs ending in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.json&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="398"&gt;
&lt;TD&gt;&lt;CODE&gt;(foo|bar)&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Alternation&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/(foo|bar)/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/foo/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/bar/&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="query-string-behavior" class="code-line" dir="auto" data-line="400"&gt;Query string behavior&lt;/H3&gt;
&lt;P class="code-line" data-line="402"&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directive operates on&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;—&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;the path only, without the query string&lt;/STRONG&gt;. The query string (&lt;CODE&gt;$args&lt;/CODE&gt;) is handled separately:&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="404"&gt;
&lt;LI class="code-line" dir="auto" data-line="404"&gt;With&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;last&lt;/CODE&gt;: the original query string is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;automatically appended&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the rewritten URI when forwarded.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;GET /chatbot/search?foo=bar&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;rewritten to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/search&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;arrives at the upstream as&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/search?foo=bar&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="405"&gt;With&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;/&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;: the query string is appended to the redirect Location header.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="406"&gt;To&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;drop&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the query string in a rewrite: end the replacement with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ^/old$ /new? break;&lt;/CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="rewrite-evaluation-order" class="code-line" dir="auto" data-line="408"&gt;Rewrite evaluation order&lt;/H3&gt;
&lt;P class="code-line" data-line="410"&gt;When multiple&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives exist in the same context, nginx evaluates them&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;in order&lt;/STRONG&gt;. The first matching rule with a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or redirect flag stops processing. Without a flag, all rules are tested and the last match wins before proxy_pass.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="412"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api/v1/(.*)$&lt;/SPAN&gt; /v1/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;   &lt;SPAN class="hljs-comment"&gt;# matches /api/v1/* → stops here&lt;/SPAN&gt;
&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api/(.*)$&lt;/SPAN&gt; /legacy/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;   &lt;SPAN class="hljs-comment"&gt;# never reached for /api/v1/* paths&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="417" /&gt;
&lt;H2 id="9-nginx-variables-available-inside-the-location-block" class="code-line" dir="auto" data-line="419"&gt;9. NGINX Variables Available Inside the Location Block&lt;/H2&gt;
&lt;P class="code-line" data-line="421"&gt;These variables are available inside the Additional Location Block and behave as in standard nginx.&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="423"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="423"&gt;
&lt;TR class="code-line" dir="auto" data-line="423"&gt;
&lt;TH&gt;Variable&lt;/TH&gt;
&lt;TH&gt;Contains&lt;/TH&gt;
&lt;TH&gt;Notes&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="425"&gt;
&lt;TR class="code-line" dir="auto" data-line="425"&gt;
&lt;TD&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Current request URI (path only, no&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or query string)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Updated by&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;/STRONG&gt;. Use this, not&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;, if you need the post-rewrite path.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="426"&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Original URI as sent by client, including query string&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Read-only. Never modified.&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This is what CloudGuard's generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;uses.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="427"&gt;
&lt;TD&gt;&lt;CODE&gt;$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Query string without the leading&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;foo=bar&amp;amp;x=1&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="428"&gt;
&lt;TD&gt;&lt;CODE&gt;$is_args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;if&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$args&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is non-empty, otherwise empty string&lt;/TD&gt;
&lt;TD&gt;Useful for constructing URIs:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri$is_args$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="429"&gt;
&lt;TD&gt;&lt;CODE&gt;$host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;request header (or server name if absent)&lt;/TD&gt;
&lt;TD&gt;Value the client sent&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="430"&gt;
&lt;TD&gt;&lt;CODE&gt;$http_host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Raw&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header including port&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;jwt.cpwaf.net:8080&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="431"&gt;
&lt;TD&gt;&lt;CODE&gt;$remote_addr&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Client IP address&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="432"&gt;
&lt;TD&gt;&lt;CODE&gt;$scheme&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Request scheme:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;https&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="433"&gt;
&lt;TD&gt;&lt;CODE&gt;$server_name&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;nginx&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server_name&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;value for this virtual host&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="434"&gt;
&lt;TD&gt;&lt;CODE&gt;$http_&amp;lt;name&amp;gt;&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Any request header, lowercased, hyphens replaced with underscores&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$http_x_forwarded_for&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$http_authorization&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="435"&gt;
&lt;TD&gt;&lt;CODE&gt;$upstream_endpoint&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Set by CloudGuard to the configured upstream URL&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;&lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— available but problematic in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(see Section 5)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;HR data-line="437" /&gt;
&lt;H2 id="10-setting-the-host-header" class="code-line" dir="auto" data-line="439"&gt;10. Setting the Host Header&lt;/H2&gt;
&lt;P class="code-line" data-line="441"&gt;The upstream backend may enforce a specific&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header and reject requests with the wrong value (HTTP 403 or 421). CloudGuard WAF by default forwards the original client&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header to the upstream, which is almost never the correct backend hostname.&lt;/P&gt;
&lt;H3 id="recommended-method-custom-headers-in-the-portal" class="code-line" dir="auto" data-line="443"&gt;Recommended method: Custom Headers in the Portal&lt;/H3&gt;
&lt;P class="code-line" data-line="445"&gt;&lt;STRONG&gt;Infinity Portal → Policy → Asset → Advanced Proxy Settings → Add custom headers&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="447"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="447"&gt;
&lt;TR class="code-line" dir="auto" data-line="447"&gt;
&lt;TH&gt;Name&lt;/TH&gt;
&lt;TH&gt;Value&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="449"&gt;
&lt;TR class="code-line" dir="auto" data-line="449"&gt;
&lt;TD&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;cpfakedomain.com&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="code-line" data-line="451"&gt;This renders as&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header Host cpfakedomain.com;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;at the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;server block level&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in the generated nginx config, applying to all requests for this asset. This is the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;officially supported method&lt;/STRONG&gt;.&lt;/P&gt;
&lt;BLOCKQUOTE class="code-line" dir="auto" data-line="453"&gt;
&lt;P class="code-line" data-line="453"&gt;The Portal UI displays:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;"You don't need to add the proxy_set_header header, as it will be automatically included in the configuration."&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This note refers to standard forwarded headers (X-Forwarded-For, etc.) — it is not saying you cannot add Host. Adding Host via Custom Headers is intentional and works correctly.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="alternative-proxy_set_header-inside-the-additional-location-block" class="code-line" dir="auto" data-line="455"&gt;Alternative: proxy_set_header inside the Additional Location Block&lt;/H3&gt;
&lt;P class="code-line" data-line="457"&gt;If for any reason you need the Host header set only for specific sub-location blocks:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="459"&gt;&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/api&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
    &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="467"&gt;When using sub-location blocks (the workaround), server-level&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;are inherited&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;by sub-locations that do not override them. So if you set&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;via the Custom Headers UI, it applies inside your sub-location blocks as well — you do not need to repeat it.&lt;/P&gt;
&lt;H3 id="why-this-matters-for-the-demotest-setup" class="code-line" dir="auto" data-line="469"&gt;Why this matters for the demo/test setup&lt;/H3&gt;
&lt;P class="code-line" data-line="471"&gt;If the upstream enforces Host validation and you forget to set it:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="473"&gt;Client → WAF → Upstream
                ← 403 Forbidden (wrong Host: jwt.cpwaf.net, expected: cpfakedomain.com)
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="478"&gt;Without&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header Host&lt;/CODE&gt;, the upstream receives whatever the client sent — typically the WAF's public DNS name. Every request through the WAF will return 403, and it will look like a WAF problem when it is actually a Host header problem. Always verify the Host header first when debugging 403 errors on a new asset.&lt;/P&gt;
&lt;HR data-line="480" /&gt;
&lt;H2 id="11-rewrite-pattern-catalogue" class="code-line" dir="auto" data-line="482"&gt;11. Rewrite Pattern Catalogue&lt;/H2&gt;
&lt;P class="code-line" data-line="484"&gt;All patterns below are for the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Additional Location Block&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file using the sub-location workaround. Replace&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;51.4.115.60:8080&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;with your upstream address.&lt;/P&gt;
&lt;H3 id="pattern-1--simple-prefix-strip" class="code-line" dir="auto" data-line="486"&gt;Pattern 1 — Simple prefix strip&lt;/H3&gt;
&lt;P class="code-line" data-line="488"&gt;Remove a path prefix before forwarding. Classic use case: a WAF asset is exposed at&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;but the upstream serves everything from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="490"&gt;&lt;SPAN class="hljs-comment"&gt;# /chatbot          -&amp;gt; /&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /chatbot/foo/bar  -&amp;gt; /foo/bar&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="499"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="500"&gt;
&lt;LI class="code-line" dir="auto" data-line="500"&gt;&lt;CODE&gt;^/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— URI starts with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="501"&gt;&lt;CODE&gt;/?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— optional trailing slash after&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;chatbot&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="502"&gt;&lt;CODE&gt;(.*)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture everything after (may be empty)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="503"&gt;&lt;CODE&gt;/$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— prepend&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the captured group (handles the bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;case)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-2--prefix-replacement" class="code-line" dir="auto" data-line="505"&gt;Pattern 2 — Prefix replacement&lt;/H3&gt;
&lt;P class="code-line" data-line="507"&gt;Replace one path prefix with another. The client uses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api/v1/...&lt;/CODE&gt;, the upstream expects&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/v1/...&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="509"&gt;&lt;SPAN class="hljs-comment"&gt;# /api/v1/items  -&amp;gt; /v1/items&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /api/v1/users  -&amp;gt; /v1/users&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/api/v1&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api(/v1/.*)$&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="518"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="519"&gt;
&lt;LI class="code-line" dir="auto" data-line="519"&gt;&lt;CODE&gt;^/api&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— match starts at&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="520"&gt;&lt;CODE&gt;(/v1/.*)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/v1/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and everything after it&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="521"&gt;&lt;CODE&gt;$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— the replacement IS the capture group (no extra prefix)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-3--path-injection-add-a-prefix" class="code-line" dir="auto" data-line="523"&gt;Pattern 3 — Path injection (add a prefix)&lt;/H3&gt;
&lt;P class="code-line" data-line="525"&gt;The client accesses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/public/...&lt;/CODE&gt;, the upstream serves static assets from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/static/public/...&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="527"&gt;&lt;SPAN class="hljs-comment"&gt;# /public/logo.png       -&amp;gt; /static/public/logo.png&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /public/css/main.css   -&amp;gt; /static/public/css/main.css&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/public&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^(/public/.*)$&lt;/SPAN&gt; /static&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="536"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="537"&gt;
&lt;LI class="code-line" dir="auto" data-line="537"&gt;&lt;CODE&gt;^(/public/.*)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture the entire path starting from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/public/&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="538"&gt;&lt;CODE&gt;/static$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— prepend&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/static&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the full captured path&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-4--full-path-swap" class="code-line" dir="auto" data-line="540"&gt;Pattern 4 — Full path swap&lt;/H3&gt;
&lt;P class="code-line" data-line="542"&gt;An exact-match rewrite. No wildcards; the entire path is replaced.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="544"&gt;&lt;SPAN class="hljs-comment"&gt;# /old-endpoint  -&amp;gt; /new-endpoint  (exact match only)&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; = /old-endpoint {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-endpoint$&lt;/SPAN&gt; /new-endpoint &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="552"&gt;Using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location = /old-endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(exact match) is more efficient than regex for single-path swaps.&lt;/P&gt;
&lt;H3 id="pattern-5--regex-capture-with-segment-reordering" class="code-line" dir="auto" data-line="554"&gt;Pattern 5 — Regex capture with segment reordering&lt;/H3&gt;
&lt;P class="code-line" data-line="556"&gt;Reorder path segments. The client sends&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/users/&amp;lt;id&amp;gt;/profile&lt;/CODE&gt;, the upstream expects&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/profile/&amp;lt;id&amp;gt;&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="558"&gt;&lt;SPAN class="hljs-comment"&gt;# /users/42/profile    -&amp;gt; /profile/42&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /users/alice/profile -&amp;gt; /profile/alice&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/users/[^/]+/profile$&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/users/([^/]+)/profile$&lt;/SPAN&gt; /profile/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="567"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="568"&gt;
&lt;LI class="code-line" dir="auto" data-line="568"&gt;&lt;CODE&gt;([^/]+)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture one or more non-slash characters (the user ID)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="569"&gt;&lt;CODE&gt;/profile/$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— place the captured ID after&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/profile/&lt;/CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-6--query-string-preservation" class="code-line" dir="auto" data-line="571"&gt;Pattern 6 — Query string preservation&lt;/H3&gt;
&lt;P class="code-line" data-line="573"&gt;Query strings are preserved automatically with the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flag. No special handling is needed.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="575"&gt;&lt;SPAN class="hljs-comment"&gt;# /chatbot/search?foo=bar&amp;amp;x=1  -&amp;gt; /search?foo=bar&amp;amp;x=1&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="583"&gt;To&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;drop&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the query string intentionally, append&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the replacement:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="585"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt;? &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="pattern-7--multi-pattern-combined-file" class="code-line" dir="auto" data-line="589"&gt;Pattern 7 — Multi-pattern combined file&lt;/H3&gt;
&lt;P class="code-line" data-line="591"&gt;A complete Additional Location Block file covering all the above cases:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="593"&gt;&lt;SPAN class="hljs-comment"&gt;# Pattern 1 - Simple prefix strip: /chatbot/* -&amp;gt; /*&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 2 - Prefix replacement: /api/v1/* -&amp;gt; /v1/*&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/api/v1&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api(/v1/.*)$&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 3 - Path injection: /public/* -&amp;gt; /static/public/*&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/public&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^(/public/.*)$&lt;/SPAN&gt; /static&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 4 - Full path swap: /old-endpoint -&amp;gt; /new-endpoint&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; = /old-endpoint {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-endpoint$&lt;/SPAN&gt; /new-endpoint &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 5 - Regex reorder: /users/&amp;lt;id&amp;gt;/profile -&amp;gt; /profile/&amp;lt;id&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/users/[^/]+/profile$&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/users/([^/]+)/profile$&lt;/SPAN&gt; /profile/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="625" /&gt;
&lt;H2 id="12-generated-nginx-artifacts" class="code-line" dir="auto" data-line="627"&gt;12. Generated NGINX Artifacts&lt;/H2&gt;
&lt;H3 id="file-locations-on-the-gateway-host" class="code-line" dir="auto" data-line="629"&gt;File locations on the gateway host&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="631"&gt;/etc/cp/conf/rpmanager/
├── nginx.conf                          # Main nginx config (auto-generated, do not edit)
├── servers/
│   ├── 00_nginx_conf_include.conf      # Global includes (auto-generated)
│   ├── 80_jwt.cpwaf.net.conf         # Per-asset server block (auto-generated)
│   └── 127.0.0.1_5555.conf            # Internal health check (auto-generated)
└── include/
    ├── waf_0_additional_location_config.conf   # Injection point for asset 0
    ├── waf_1_additional_location_config.conf   # Injection point for asset 1
    ...
    └── waf_N_additional_location_config.conf   # Your file lands here
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="how-cloudguard-assigns-waf_n-files-to-assets" class="code-line" dir="auto" data-line="645"&gt;How CloudGuard assigns waf_N files to assets&lt;/H3&gt;
&lt;P class="code-line" data-line="647"&gt;CloudGuard assigns a sequential index&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(0–9, then a–f in hex) to each WAF asset. The mapping between asset and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is managed internally by the management plane and is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;not guaranteed to be stable&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;across portal re-enforcements or gateway restarts. Always verify the current mapping with:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="649"&gt;sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="what-a-full-generated-server-block-looks-like-annotated" class="code-line" dir="auto" data-line="653"&gt;What a full generated server block looks like (annotated)&lt;/H3&gt;
&lt;P class="code-line" data-line="655"&gt;Verified output from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;sudo cat /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;on a live CloudGuard WAF gateway:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="657"&gt;&lt;SPAN class="hljs-comment"&gt;# Auto-generated by CloudGuard WAF management. DO NOT EDIT MANUALLY.&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# Changes are overwritten on next policy enforce.&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Used internally for rate-limit logging decisions&lt;/SPAN&gt;
&lt;SPAN class="hljs-attribute"&gt;map&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$status&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$RateLimitLoggable&lt;/SPAN&gt; {
    429 1;
    &lt;SPAN class="hljs-attribute"&gt;default&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;0&lt;/SPAN&gt;;
}

&lt;SPAN class="hljs-section"&gt;server&lt;/SPAN&gt;
{
    &lt;SPAN class="hljs-attribute"&gt;listen&lt;/SPAN&gt;  &lt;SPAN class="hljs-number"&gt;80&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;server_name&lt;/SPAN&gt; jwt.cpwaf.net;

    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_headers&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_body&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;

    &lt;SPAN class="hljs-comment"&gt;# Generated ONLY because "Host: cpfakedomain.com" was added in&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# Portal -&amp;gt; Advanced Proxy Settings -&amp;gt; Custom Headers.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# This line is absent by default if no custom Host header is configured.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;

    &lt;SPAN class="hljs-attribute"&gt;access_log&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;off&lt;/SPAN&gt;;                                      &lt;SPAN class="hljs-comment"&gt;# access logging disabled by default&lt;/SPAN&gt;
    &lt;SPAN class="hljs-attribute"&gt;error_log&lt;/SPAN&gt; /var/log/nginx/&lt;SPAN class="hljs-literal"&gt;error&lt;/SPAN&gt;.log &lt;SPAN class="hljs-literal"&gt;warn&lt;/SPAN&gt;;             &lt;SPAN class="hljs-comment"&gt;# fixed path, not configurable here&lt;/SPAN&gt;

    &lt;SPAN class="hljs-comment"&gt;# SSL Client Certificate JavaScript Processing      # placeholder — unused unless mTLS configured&lt;/SPAN&gt;

    &lt;SPAN class="hljs-attribute"&gt;resolver&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;168.63.129.16&lt;/SPAN&gt; ipv6=&lt;SPAN class="hljs-literal"&gt;off&lt;/SPAN&gt;;                    &lt;SPAN class="hljs-comment"&gt;# Azure DNS resolver (deployment-specific)&lt;/SPAN&gt;

    &lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; /
    {
        &lt;SPAN class="hljs-comment"&gt;# === YOUR ADDITIONAL LOCATION BLOCK CONTENT IS INJECTED HERE ===&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;include&lt;/SPAN&gt;   /etc/cp/conf/rpmanager/include/waf_5_additional_location_config.conf;

 &lt;SPAN class="hljs-comment"&gt;#unused redirect;                                       # CloudGuard placeholder — not active&lt;/SPAN&gt;
 &lt;SPAN class="hljs-comment"&gt;#unused DNS server;&lt;/SPAN&gt;

        &lt;SPAN class="hljs-comment"&gt;# Generated upstream variable from Portal Reverse Proxy settings&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;set&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt; http://51.4.115.60:8080;

        &lt;SPAN class="hljs-comment"&gt;# THIS uses $request_uri — see Section 5 for why rewrites require a workaround&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$request_uri&lt;/SPAN&gt;;

        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;          &lt;SPAN class="hljs-comment"&gt;# repeated here even if set at server level&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; X-Forwarded-For &lt;SPAN class="hljs-variable"&gt;$proxy_add_x_forwarded_for&lt;/SPAN&gt;;
 &lt;SPAN class="hljs-comment"&gt;#unused access_log;&lt;/SPAN&gt;
 &lt;SPAN class="hljs-comment"&gt;#unused access syslog;&lt;/SPAN&gt;

        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Upgrade &lt;SPAN class="hljs-variable"&gt;$http_upgrade&lt;/SPAN&gt;;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Connection &lt;SPAN class="hljs-string"&gt;"Upgrade"&lt;/SPAN&gt;;
 &lt;SPAN class="hljs-comment"&gt;#unused header;                                         # placeholders for optional headers&lt;/SPAN&gt;
    }
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="713"&gt;&lt;STRONG&gt;Notable observations from the real output:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="714"&gt;
&lt;LI class="code-line" dir="auto" data-line="714"&gt;&lt;CODE&gt;#unused&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;comment lines are CloudGuard-generated placeholders for features that are configured elsewhere in the Portal (redirects, rate limits, custom headers, access logging). They are inert — nginx treats them as comments.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="715"&gt;&lt;CODE&gt;proxy_set_header Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;appears&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;twice&lt;/STRONG&gt;: once at the server block level (from Custom Headers) and once inside&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;. Both are generated by CloudGuard; the location-level one takes precedence for proxied requests.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="716"&gt;&lt;CODE&gt;access_log off&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is hardcoded. To enable nginx-level access logging you must add it via the Additional Server Block.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="717"&gt;The Azure DNS resolver (&lt;CODE&gt;168.63.129.16&lt;/CODE&gt;) is deployment-specific. On non-Azure gateways this will differ.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR data-line="719" /&gt;
&lt;H2 id="13-deployment-procedure-infinity-portal" class="code-line" dir="auto" data-line="721"&gt;13. Deployment Procedure (Infinity Portal)&lt;/H2&gt;
&lt;H3 id="step-1-prepare-the-location-block-file" class="code-line" dir="auto" data-line="723"&gt;Step 1: Prepare the location block file&lt;/H3&gt;
&lt;P class="code-line" data-line="725"&gt;Create a plain text file (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location-block.conf&lt;/CODE&gt;) with your rewrite sub-locations. Rules:&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="726"&gt;
&lt;LI class="code-line" dir="auto" data-line="726"&gt;ASCII only in comments&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="727"&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;upstream&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="728"&gt;Use literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;not variables&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="729"&gt;Test regex patterns locally with:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;echo "/your/path" | grep -P 'your_pattern'&lt;/CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="step-2-set-the-upstream-in-the-portal" class="code-line" dir="auto" data-line="731"&gt;Step 2: Set the upstream in the Portal&lt;/H3&gt;
&lt;P class="code-line" data-line="733"&gt;&lt;STRONG&gt;Policy → Asset → Reverse Proxy → WAF will reach the application at:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="code-line" data-line="735"&gt;Set this to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;&lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;&lt;/CODE&gt;. This defines&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$upstream_endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in the generated config and is used for health checks.&lt;/P&gt;
&lt;H3 id="step-3-set-the-host-header" class="code-line" dir="auto" data-line="737"&gt;Step 3: Set the Host header&lt;/H3&gt;
&lt;P class="code-line" data-line="739"&gt;&lt;STRONG&gt;Policy → Asset → Advanced Proxy Settings → Add custom headers&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="741"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="741"&gt;
&lt;TR class="code-line" dir="auto" data-line="741"&gt;
&lt;TH&gt;Name&lt;/TH&gt;
&lt;TH&gt;Value&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="743"&gt;
&lt;TR class="code-line" dir="auto" data-line="743"&gt;
&lt;TD&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;&amp;lt;expected-hostname-by-backend&amp;gt;&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="step-4-upload-the-location-block-file" class="code-line" dir="auto" data-line="745"&gt;Step 4: Upload the location block file&lt;/H3&gt;
&lt;P class="code-line" data-line="747"&gt;&lt;STRONG&gt;Policy → Asset → Advanced Proxy Settings → Additional location block instructions → Upload&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="code-line" data-line="749"&gt;Select your&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.conf&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file and click OK.&lt;/P&gt;
&lt;H3 id="step-5-enforce-the-policy" class="code-line" dir="auto" data-line="751"&gt;Step 5: Enforce the policy&lt;/H3&gt;
&lt;P class="code-line" data-line="753"&gt;Click&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Enforce&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Publish&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;depending on your portal version). CloudGuard will:&lt;/P&gt;
&lt;OL class="code-line" dir="auto" data-line="754"&gt;
&lt;LI class="code-line" dir="auto" data-line="754"&gt;Write your file to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="755"&gt;Regenerate the server block&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="756"&gt;Run&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;nginx -t&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="757"&gt;If the test passes: reload nginx (&lt;CODE&gt;nginx -s reload&lt;/CODE&gt;)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="758"&gt;If the test fails: nginx is not reloaded; all requests to the asset return HTTP 500&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="step-6-verify-see-section-14" class="code-line" dir="auto" data-line="760"&gt;Step 6: Verify (see Section 14)&lt;/H3&gt;
&lt;HR data-line="762" /&gt;
&lt;H2 id="14-validation-and-testing" class="code-line" dir="auto" data-line="764"&gt;14. Validation and Testing&lt;/H2&gt;
&lt;H3 id="verify-the-file-was-written-correctly" class="code-line" dir="auto" data-line="766"&gt;Verify the file was written correctly&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="768"&gt;&lt;SPAN class="hljs-comment"&gt;# Find your asset's include file&lt;/SPAN&gt;
sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf

&lt;SPAN class="hljs-comment"&gt;# Read it&lt;/SPAN&gt;
sudo &lt;SPAN class="hljs-built_in"&gt;cat&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf

&lt;SPAN class="hljs-comment"&gt;# Confirm nginx is running cleanly&lt;/SPAN&gt;
sudo nginx -t
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="test-each-rewrite-pattern-with-curl" class="code-line" dir="auto" data-line="779"&gt;Test each rewrite pattern with curl&lt;/H3&gt;
&lt;P class="code-line" data-line="781"&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;-v&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flag shows request/response headers. The backend JSON response echoes back&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;path&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;host&lt;/CODE&gt;, and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;query_string&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;for easy verification.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="783"&gt;&lt;SPAN class="hljs-comment"&gt;# Pattern 1 — prefix strip&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/chatbot
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /&lt;/SPAN&gt;

curl -v http://jwt.cpwaf.net/chatbot/items
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /items&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 2 — prefix replacement&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/api/v1/items
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /v1/items&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 3 — path injection&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/public/logo.png
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /static/public/logo.png&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 4 — full path swap&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/old-endpoint
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /new-endpoint&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 5 — regex reorder&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/users/42/profile
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /profile/42&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 6 — query string preservation&lt;/SPAN&gt;
curl -v &lt;SPAN class="hljs-string"&gt;"http://jwt.cpwaf.net/chatbot/search?foo=bar&amp;amp;x=1"&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /search?foo=bar&amp;amp;x=1&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Host header verification&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/
&lt;SPAN class="hljs-comment"&gt;# Expected: backend JSON shows "host": "cpfakedomain.com"&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Host enforcement (direct to backend — should 403)&lt;/SPAN&gt;
curl -v -H &lt;SPAN class="hljs-string"&gt;"Host: wronghost.example.com"&lt;/SPAN&gt; http://51.4.115.60:8080/
&lt;SPAN class="hljs-comment"&gt;# Expected: 403 from backend&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Host enforcement (direct to backend — should 200)&lt;/SPAN&gt;
curl -v -H &lt;SPAN class="hljs-string"&gt;"Host: cpfakedomain.com"&lt;/SPAN&gt; http://51.4.115.60:8080/
&lt;SPAN class="hljs-comment"&gt;# Expected: 200 from backend&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="824" /&gt;
&lt;H2 id="15-logging-implications" class="code-line" dir="auto" data-line="826"&gt;15. Logging Implications&lt;/H2&gt;
&lt;H3 id="access-log" class="code-line" dir="auto" data-line="828"&gt;Access log&lt;/H3&gt;
&lt;P class="code-line" data-line="830"&gt;By default, CloudGuard WAF's nginx has access logging&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;disabled&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in generated server blocks (&lt;CODE&gt;access_log off;&lt;/CODE&gt;). WAF-level access events are logged through the Check Point unified logging infrastructure (SmartConsole / Log &amp;amp; Monitor), not through nginx access logs.&lt;/P&gt;
&lt;P class="code-line" data-line="832"&gt;To enable raw nginx access logging for debugging, add to the Additional Server Block:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="834"&gt;&lt;SPAN class="hljs-attribute"&gt;access_log&lt;/SPAN&gt; /var/log/nginx/access_debug.log;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="838"&gt;This is a temporary debugging measure. Remove it before production use.&lt;/P&gt;
&lt;H3 id="error-log" class="code-line" dir="auto" data-line="840"&gt;Error log&lt;/H3&gt;
&lt;P class="code-line" data-line="842"&gt;The error log is configured at the server block level by CloudGuard:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="844"&gt;&lt;SPAN class="hljs-attribute"&gt;error_log&lt;/SPAN&gt; /var/log/nginx/&lt;SPAN class="hljs-literal"&gt;error&lt;/SPAN&gt;.log &lt;SPAN class="hljs-literal"&gt;warn&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="848"&gt;When a location block file contains a syntax error, nginx fails its config test and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;does not reload&lt;/STRONG&gt;. The error is visible in:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="850"&gt;sudo nginx -t 2&amp;gt;&amp;amp;1
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="854"&gt;If nginx rejects the config, all requests to the affected asset return HTTP 500, because nginx is running the previous (last-good) config, which does not include your changes.&lt;/P&gt;
&lt;H3 id="tracking-which-requests-hit-your-rewrite-rules" class="code-line" dir="auto" data-line="856"&gt;Tracking which requests hit your rewrite rules&lt;/H3&gt;
&lt;P class="code-line" data-line="858"&gt;Since access logging is off by default, the best way to observe what the backend receives is to instrument the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;backend&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to log the incoming request URI and Host header. The Flask backend in this project echoes both back as JSON, making it ideal for testing.&lt;/P&gt;
&lt;P class="code-line" data-line="860"&gt;Alternatively, enable access logging on the Additional Server Block temporarily and inspect&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/var/log/nginx/access_debug.log&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;on the gateway host:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="862"&gt;sudo &lt;SPAN class="hljs-built_in"&gt;tail&lt;/SPAN&gt; -f /var/log/nginx/access_debug.log
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="866" /&gt;
&lt;H2 id="16-troubleshooting-guide" class="code-line" dir="auto" data-line="868"&gt;16. Troubleshooting Guide&lt;/H2&gt;
&lt;H3 id="http-500-on-all-requests-to-the-asset-after-enforce" class="code-line" dir="auto" data-line="870"&gt;HTTP 500 on all requests to the asset after enforce&lt;/H3&gt;
&lt;P class="code-line" data-line="872"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;nginx config test failed. Your location block file has a syntax error.&lt;/P&gt;
&lt;P class="code-line" data-line="874"&gt;&lt;STRONG&gt;Diagnosis:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="875"&gt;sudo nginx -t 2&amp;gt;&amp;amp;1
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="879"&gt;&lt;STRONG&gt;Common causes and fixes:&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="881"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="881"&gt;
&lt;TR class="code-line" dir="auto" data-line="881"&gt;
&lt;TH&gt;Error message&lt;/TH&gt;
&lt;TH&gt;Cause&lt;/TH&gt;
&lt;TH&gt;Fix&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="883"&gt;
&lt;TR class="code-line" dir="auto" data-line="883"&gt;
&lt;TD&gt;&lt;CODE&gt;host not found in upstream "upstream"&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Used&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://upstream" target="_blank" rel="noopener"&gt;http://upstream&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;with a placeholder name&lt;/TD&gt;
&lt;TD&gt;Replace with the actual IP:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="884"&gt;
&lt;TD&gt;&lt;CODE&gt;unexpected "{"&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Used&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block in the location block file&lt;/TD&gt;
&lt;TD&gt;Remove — these are not allowed&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="885"&gt;
&lt;TD&gt;&lt;CODE&gt;invalid number of arguments&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Syntax error in a directive&lt;/TD&gt;
&lt;TD&gt;Check directive spelling and argument count&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="886"&gt;
&lt;TD&gt;&lt;CODE&gt;pcre_compile() failed&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Invalid regex&lt;/TD&gt;
&lt;TD&gt;Test your regex:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;echo "/path" | grep -P 'your_regex'&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="887"&gt;
&lt;TD&gt;Non-ASCII character error&lt;/TD&gt;
&lt;TD&gt;Unicode in comments (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;→&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;–&lt;/CODE&gt;)&lt;/TD&gt;
&lt;TD&gt;Replace with ASCII equivalents (&lt;CODE&gt;-&amp;gt;&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;-&lt;/CODE&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="rewrite-rules-uploaded-but-paths-are-not-being-rewritten" class="code-line" dir="auto" data-line="889"&gt;Rewrite rules uploaded but paths are not being rewritten&lt;/H3&gt;
&lt;P class="code-line" data-line="891"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives (without sub-&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;wrappers) have no effect because the generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass $upstream_endpoint$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;uses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;, which is never modified by rewrites.&lt;/P&gt;
&lt;P class="code-line" data-line="893"&gt;&lt;STRONG&gt;Diagnosis:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="894"&gt;&lt;SPAN class="hljs-comment"&gt;# Check what the backend actually receives&lt;/SPAN&gt;
curl -s http://&amp;lt;waf-hostname&amp;gt;/your-path | jq .path
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="899"&gt;If the backend still receives the original path, use sub-&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks with a literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(see Section 6).&lt;/P&gt;
&lt;H3 id="http-403-on-every-request-through-the-waf" class="code-line" dir="auto" data-line="901"&gt;HTTP 403 on every request through the WAF&lt;/H3&gt;
&lt;P class="code-line" data-line="903"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The upstream is enforcing a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header check and the WAF is forwarding the client's&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header instead of the backend's expected hostname.&lt;/P&gt;
&lt;P class="code-line" data-line="905"&gt;&lt;STRONG&gt;Diagnosis:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="906"&gt;curl -s http://&amp;lt;waf-hostname&amp;gt;/ | jq .received_host
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="910"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Add the correct Host header via Portal → Asset → Advanced Proxy Settings → Custom Headers:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;=&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;&amp;lt;backend-expected-hostname&amp;gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;H3 id="http-502-bad-gateway" class="code-line" dir="auto" data-line="913"&gt;HTTP 502 Bad Gateway&lt;/H3&gt;
&lt;P class="code-line" data-line="915"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The WAF cannot connect to the upstream.&lt;/P&gt;
&lt;P class="code-line" data-line="917"&gt;&lt;STRONG&gt;Checklist:&lt;/STRONG&gt;&lt;/P&gt;
&lt;OL class="code-line" dir="auto" data-line="918"&gt;
&lt;LI class="code-line" dir="auto" data-line="918"&gt;Is the upstream running?&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;curl &lt;A href="http://51.4.115.60:8080/" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080/&lt;/A&gt;&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="919"&gt;Is port 8080 open on the upstream firewall?&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;sudo ufw status&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="920"&gt;Is the upstream IP correct in the Portal?&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="921"&gt;If using sub-location&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;, is the hardcoded IP correct and reachable from the WAF?&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="rewrite-fires-but-query-string-is-lost" class="code-line" dir="auto" data-line="923"&gt;Rewrite fires but query string is lost&lt;/H3&gt;
&lt;P class="code-line" data-line="925"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flags instead of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;. These issue client-side redirects, and the redirect URL construction may drop query strings depending on nginx version.&lt;/P&gt;
&lt;P class="code-line" data-line="927"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;for all upstream proxy rewrites.&lt;/P&gt;
&lt;H3 id="trailing-slash-issues-eg-chatbot-not-matching-but-chatbot-does" class="code-line" dir="auto" data-line="929"&gt;Trailing slash issues (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;not matching but&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;does)&lt;/H3&gt;
&lt;P class="code-line" data-line="931"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The regex does not account for an optional trailing slash.&lt;/P&gt;
&lt;P class="code-line" data-line="933"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in the regex:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="934"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
&lt;SPAN class="hljs-comment"&gt;#               ^^  optional trailing slash&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="location-block-changes-not-visible-after-enforce" class="code-line" dir="auto" data-line="939"&gt;Location block changes not visible after enforce&lt;/H3&gt;
&lt;P class="code-line" data-line="941"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The Portal may have assigned a new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;waf_N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;index to your asset, and the server block now includes a different file.&lt;/P&gt;
&lt;P class="code-line" data-line="943"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="944"&gt;sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;SPAN class="hljs-comment"&gt;# Then read the file it points to&lt;/SPAN&gt;
sudo &lt;SPAN class="hljs-built_in"&gt;cat&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_&amp;lt;N&amp;gt;_additional_location_config.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="950"&gt;Always verify the actual included file rather than assuming the index is stable.&lt;/P&gt;
&lt;H3 id="rewrite--break-vs-rewrite--last--choosing-the-wrong-flag" class="code-line" dir="auto" data-line="952"&gt;&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;vs&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ... last&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— choosing the wrong flag&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="954"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="954"&gt;
&lt;TR class="code-line" dir="auto" data-line="954"&gt;
&lt;TH&gt;Scenario&lt;/TH&gt;
&lt;TH&gt;Correct flag&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="956"&gt;
&lt;TR class="code-line" dir="auto" data-line="956"&gt;
&lt;TD&gt;Rewriting the path for upstream proxy&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— stops rewriting, proxies with new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="957"&gt;
&lt;TD&gt;Rewriting to match a different&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;last&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— re-evaluates location matching&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="958"&gt;
&lt;TD&gt;Issuing a browser redirect&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="code-line" data-line="960"&gt;Using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;last&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in a proxy rewrite can cause infinite loops if the rewritten URI re-matches the same location, resulting in a 500.&lt;/P&gt;</description>
    <pubDate>Sun, 19 Apr 2026 11:18:09 GMT</pubDate>
    <dc:creator>Shay_Levin</dc:creator>
    <dc:date>2026-04-19T11:18:09Z</dc:date>
    <item>
      <title>URI Rewrite - Complete Implementation Reference</title>
      <link>https://community.checkpoint.com/t5/WAF/URI-Rewrite-Complete-Implementation-Reference/m-p/275721#M398</link>
      <description>&lt;H2 id="what-is-uri-rewriting-and-why-does-it-matter" class="code-line" dir="auto" data-line="7"&gt;What is URI Rewriting and Why Does it Matter?&lt;/H2&gt;
&lt;P class="code-line" data-line="9"&gt;A&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;URI rewrite&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is the act of changing the request path — silently, server-side — before it reaches the upstream application. The client sends one URL; the backend receives a different one. No redirect is issued; the client is unaware.&lt;/P&gt;
&lt;H3 id="why-it-is-needed" class="code-line" dir="auto" data-line="11"&gt;Why it is needed&lt;/H3&gt;
&lt;P class="code-line" data-line="13"&gt;Real-world deployments rarely have a clean 1:1 mapping between the public URL structure and the backend's internal URL structure. URI rewriting bridges that gap without requiring changes to either the client or the backend.&lt;/P&gt;
&lt;H3 id="common-use-cases" class="code-line" dir="auto" data-line="15"&gt;Common use cases&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="17"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="17"&gt;
&lt;TR class="code-line" dir="auto" data-line="17"&gt;
&lt;TH&gt;Use case&lt;/TH&gt;
&lt;TH&gt;Example&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="19"&gt;
&lt;TR class="code-line" dir="auto" data-line="19"&gt;
&lt;TD&gt;&lt;STRONG&gt;Expose a sub-path publicly, serve from root&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Public:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→ Backend:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/*&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="20"&gt;
&lt;TD&gt;&lt;STRONG&gt;Version translation&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Public:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api/v1/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→ Backend:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/v1/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(strip the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;prefix a gateway added)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="21"&gt;
&lt;TD&gt;&lt;STRONG&gt;Legacy URL migration&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Old:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/old-endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→ New:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/new-endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(keep old clients working)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="22"&gt;
&lt;TD&gt;&lt;STRONG&gt;Path normalization&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Add a prefix the backend expects:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/public/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/static/public/*&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="23"&gt;
&lt;TD&gt;&lt;STRONG&gt;Segment reordering&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;REST to internal:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/users/42/profile&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/profile/42&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="24"&gt;
&lt;TD&gt;&lt;STRONG&gt;Multi-service routing&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;One WAF asset routes&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/payments/*&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/orders/*&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/catalog/*&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to separate upstreams by rewriting paths&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="25"&gt;
&lt;TD&gt;&lt;STRONG&gt;WAF in front of a legacy app&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;The app was built with a hard-coded path structure that can't be changed; the WAF adapts incoming paths to match it&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="uri-rewrite-vs-redirect--key-distinction" class="code-line" dir="auto" data-line="27"&gt;URI rewrite vs redirect — key distinction&lt;/H3&gt;
&lt;P class="code-line" data-line="29"&gt;A&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;rewrite&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is invisible to the client (internal, server-side). A&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;redirect&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;tells the client to issue a new request to a different URL (HTTP 301/302, client-visible). For reverse proxy scenarios, you almost always want a rewrite — the client should not know or care about the backend's internal path structure.&lt;/P&gt;
&lt;HR data-line="31" /&gt;
&lt;H2 id="table-of-contents" class="code-line" dir="auto" data-line="33"&gt;Table of Contents&lt;/H2&gt;
&lt;OL class="code-line" dir="auto" data-line="35"&gt;
&lt;LI class="code-line" dir="auto" data-line="35"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#1-architecture-overview" target="_blank" rel="noopener" data-href="#1-architecture-overview"&gt;Architecture Overview&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="36"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#2-how-cloudguard-waf-manages-nginx" target="_blank" rel="noopener" data-href="#2-how-cloudguard-waf-manages-nginx"&gt;How CloudGuard WAF Manages NGINX&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="37"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#3-the-two-injection-points" target="_blank" rel="noopener" data-href="#3-the-two-injection-points"&gt;The Two Injection Points&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="38"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#4-what-uri-rewrite-means-in-this-context" target="_blank" rel="noopener" data-href="#4-what-uri-rewrite-means-in-this-context"&gt;What URI Rewrite Means in This Context&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="39"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#5-critical-limitation-request_uri-vs-uri" target="_blank" rel="noopener" data-href="#5-critical-limitation-request_uri-vs-uri"&gt;Critical Limitation: $request_uri vs $uri&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="40"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#6-the-workaround-per-path-location-blocks-with-literal-proxy_pass" target="_blank" rel="noopener" data-href="#6-the-workaround-per-path-location-blocks-with-literal-proxy_pass"&gt;The Workaround: Per-Path Location Blocks with Literal proxy_pass&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="41"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#7-location-block-file-reference" target="_blank" rel="noopener" data-href="#7-location-block-file-reference"&gt;Location Block File Reference&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="42"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#8-the-rewrite-directive-in-depth" target="_blank" rel="noopener" data-href="#8-the-rewrite-directive-in-depth"&gt;The rewrite Directive In Depth&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="43"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#9-nginx-variables-available-inside-the-location-block" target="_blank" rel="noopener" data-href="#9-nginx-variables-available-inside-the-location-block"&gt;NGINX Variables Available Inside the Location Block&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="44"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#10-setting-the-host-header" target="_blank" rel="noopener" data-href="#10-setting-the-host-header"&gt;Setting the Host Header&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="45"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#11-rewrite-pattern-catalogue" target="_blank" rel="noopener" data-href="#11-rewrite-pattern-catalogue"&gt;Rewrite Pattern Catalogue&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="46"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#12-generated-nginx-artifacts" target="_blank" rel="noopener" data-href="#12-generated-nginx-artifacts"&gt;Generated NGINX Artifacts&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="47"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#13-deployment-procedure-infinity-portal" target="_blank" rel="noopener" data-href="#13-deployment-procedure-infinity-portal"&gt;Deployment Procedure (Infinity Portal)&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="48"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#14-validation-and-testing" target="_blank" rel="noopener" data-href="#14-validation-and-testing"&gt;Validation and Testing&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="49"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#15-logging-implications" target="_blank" rel="noopener" data-href="#15-logging-implications"&gt;Logging Implications&lt;/A&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="50"&gt;&lt;A href="https://vscode-remote+ssh-002dremote-002bguard-002ddemo-002dvm.vscode-resource.vscode-cdn.net/home/adminuser/waf-rewrite/CLOUDGUARD_WAF_URI_REWRITE.md#16-troubleshooting-guide" target="_blank" rel="noopener" data-href="#16-troubleshooting-guide"&gt;Troubleshooting Guide&lt;/A&gt;&lt;/LI&gt;
&lt;/OL&gt;
&lt;HR data-line="52" /&gt;
&lt;H2 id="1-architecture-overview" class="code-line" dir="auto" data-line="54"&gt;1. Architecture Overview&lt;/H2&gt;
&lt;P class="code-line" data-line="56"&gt;CloudGuard WAF operates as an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;L7 reverse proxy&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in front of upstream application servers. All client traffic is routed through the WAF; the WAF inspects, optionally transforms, and forwards requests to the upstream.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="58"&gt;  Client (browser / curl / API)
          │
          │  HTTP/HTTPS  (public DNS, e.g. jwt.cpwaf.net)
          ▼
  ┌───────────────────────────────────────────────────────┐
  │           CloudGuard WAF — AppSec Gateway             │
  │                                                       │
  │  nginx (WAF-managed)                                  │
  │  ┌─────────────────────────────────────────────────┐  │
  │  │  server block: jwt.cpwaf.net:80/443           │  │
  │  │  location / {                                   │  │
  │  │    [Additional Location Block injected here]    │  │
  │  │    proxy_pass $upstream_endpoint$request_uri;   │  │ ← generated
  │  │  }                                              │  │
  │  └─────────────────────────────────────────────────┘  │
  └───────────────────────────────────────────────────────┘
          │
          │  HTTP  (internal / private network)
          │  Host: &amp;lt;as configured&amp;gt;
          ▼
  ┌─────────────────────────────┐
  │  Upstream Backend           │
  │  e.g. 51.4.115.60:8080         │
  └─────────────────────────────┘
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="85"&gt;&lt;STRONG&gt;Key facts:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="86"&gt;
&lt;LI class="code-line" dir="auto" data-line="86"&gt;The WAF terminates the client connection and opens a new connection to the upstream.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="87"&gt;URI rewriting happens&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inside the WAF&lt;/STRONG&gt;, before the upstream sees the request.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="88"&gt;The client never observes the rewrite (no HTTP redirect is issued).&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="89"&gt;The upstream receives the rewritten URI, not the original client URI.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR data-line="91" /&gt;
&lt;H2 id="2-how-cloudguard-waf-manages-nginx" class="code-line" dir="auto" data-line="93"&gt;2. How CloudGuard WAF Manages NGINX&lt;/H2&gt;
&lt;P class="code-line" data-line="95"&gt;CloudGuard WAF runs&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;nginx&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;as its proxy engine. Unlike self-managed nginx deployments, the admin&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;cannot directly edit&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;nginx.conf&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or any generated server block file. The WAF management plane (Infinity Portal) owns these files and regenerates them on every policy enforce.&lt;/P&gt;
&lt;H3 id="what-is-auto-generated-and-what-is-user-controlled" class="code-line" dir="auto" data-line="97"&gt;What is auto-generated and what is user-controlled&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="99"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="99"&gt;
&lt;TR class="code-line" dir="auto" data-line="99"&gt;
&lt;TH&gt;File / Component&lt;/TH&gt;
&lt;TH&gt;Who controls it&lt;/TH&gt;
&lt;TH&gt;Editable by admin?&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="101"&gt;
&lt;TR class="code-line" dir="auto" data-line="101"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/nginx.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="102"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No — overwritten on enforce&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="103"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;User&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(via Portal upload)&lt;/TD&gt;
&lt;TD&gt;Yes — this is the injection point&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="104"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/nginx/modules/*.conf&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="105"&gt;
&lt;TD&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/error-pages/&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;CloudGuard management&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;BLOCKQUOTE class="code-line" dir="auto" data-line="107"&gt;
&lt;P class="code-line" data-line="107"&gt;&lt;STRONG&gt;Important:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Even if you manually edit a generated server conf on the gateway host, those changes are&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;overwritten&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the next time you enforce a policy from the Infinity Portal. The only durable injection point is the Additional Location Block / Additional Server Block upload.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="generated-server-block-structure" class="code-line" dir="auto" data-line="109"&gt;Generated server block structure&lt;/H3&gt;
&lt;P class="code-line" data-line="111"&gt;For a WAF asset listening on port 80 for&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;jwt.cpwaf.net&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;proxying to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;51.4.115.60:8080&lt;/CODE&gt;, CloudGuard generates a file at:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="113"&gt;/etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="117"&gt;The relevant excerpt looks like this:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="119"&gt;&lt;SPAN class="hljs-section"&gt;server&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;listen&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;80&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;server_name&lt;/SPAN&gt; jwt.cpwaf.net;

    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_headers&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_body&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;

    &lt;SPAN class="hljs-comment"&gt;# ONLY present because "Host: cpfakedomain.com" was added under&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# Advanced Proxy Settings -&amp;gt; Custom Headers in the Portal.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# Without that setting this line does NOT appear in the generated config.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;

    &lt;SPAN class="hljs-attribute"&gt;resolver&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;168.63.129.16&lt;/SPAN&gt; ipv6=&lt;SPAN class="hljs-literal"&gt;off&lt;/SPAN&gt;;

    &lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; / {
        &lt;SPAN class="hljs-attribute"&gt;include&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_5_additional_location_config.conf;

        &lt;SPAN class="hljs-attribute"&gt;set&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt; http://51.4.115.60:8080;
        &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$request_uri&lt;/SPAN&gt;;   &lt;SPAN class="hljs-comment"&gt;# ← see Section 5&lt;/SPAN&gt;

        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; X-Forwarded-For &lt;SPAN class="hljs-variable"&gt;$proxy_add_x_forwarded_for&lt;/SPAN&gt;;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Upgrade &lt;SPAN class="hljs-variable"&gt;$http_upgrade&lt;/SPAN&gt;;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Connection &lt;SPAN class="hljs-string"&gt;"Upgrade"&lt;/SPAN&gt;;
    }
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="147"&gt;The include file (&lt;CODE&gt;waf_N_additional_location_config.conf&lt;/CODE&gt;) is where your uploaded Additional Location Block content lands. The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is an internal counter assigned by the WAF management plane — it is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;not predictable&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in advance and may change across policy enforces.&lt;/P&gt;
&lt;P class="code-line" data-line="149"&gt;To find which include file belongs to your asset at any point in time:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="151"&gt;sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="155" /&gt;
&lt;H2 id="3-the-two-injection-points" class="code-line" dir="auto" data-line="157"&gt;3. The Two Injection Points&lt;/H2&gt;
&lt;P class="code-line" data-line="159"&gt;Navigate to:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Infinity Portal → Policy → [Your Asset] → Advanced Proxy Settings&lt;/STRONG&gt;&lt;/P&gt;
&lt;H3 id="31-additional-location-block-instructions" class="code-line" dir="auto" data-line="161"&gt;3.1 Additional Location Block Instructions&lt;/H3&gt;
&lt;P class="code-line" data-line="163"&gt;Content is injected&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inside the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block&lt;/STRONG&gt;, before the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directive.&lt;/P&gt;
&lt;P class="code-line" data-line="165"&gt;&lt;STRONG&gt;Allowed directives:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="166"&gt;
&lt;LI class="code-line" dir="auto" data-line="166"&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="167"&gt;&lt;CODE&gt;set&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="168"&gt;&lt;CODE&gt;add_header&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="169"&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="170"&gt;&lt;CODE&gt;sub-&lt;/CODE&gt;location blocks (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location ~ ^/path { ... }&lt;/CODE&gt;) —&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;with caveats, see Section 6&lt;/STRONG&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="171"&gt;Most per-request nginx directives&lt;/LI&gt;
&lt;/UL&gt;
&lt;P class="code-line" data-line="173"&gt;&lt;STRONG&gt;NOT allowed (will cause nginx config test failure):&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="174"&gt;
&lt;LI class="code-line" dir="auto" data-line="174"&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— server-level block; belongs in Server Block&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="175"&gt;&lt;CODE&gt;http { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— global block; not injectable&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="176"&gt;&lt;CODE&gt;upstream { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— not injectable; use the Portal's Reverse Proxy settings&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="177"&gt;Bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;without a specific&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;wrapper —&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;partially allowed but ineffective; see Section 5&lt;/STRONG&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="32-additional-server-block-instructions" class="code-line" dir="auto" data-line="179"&gt;3.2 Additional Server Block Instructions&lt;/H3&gt;
&lt;P class="code-line" data-line="181"&gt;Content is injected&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inside the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block&lt;/STRONG&gt;, outside of any&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;.&lt;/P&gt;
&lt;P class="code-line" data-line="183"&gt;Use this for:&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="184"&gt;
&lt;LI class="code-line" dir="auto" data-line="184"&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives you want to apply to all locations&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="185"&gt;&lt;CODE&gt;map&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks (though&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;map&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is technically an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http&lt;/CODE&gt;-level directive in standard nginx — behavior may vary)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="186"&gt;Custom error pages&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="187"&gt;Access log configuration&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="33-custom-headers-proxy-settings" class="code-line" dir="auto" data-line="189"&gt;3.3 Custom Headers (Proxy Settings)&lt;/H3&gt;
&lt;P class="code-line" data-line="191"&gt;The Portal also provides a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Custom Headers&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;table (under Advanced Proxy Settings → Add custom headers). Headers added here are rendered as&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives at the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;server block level&lt;/STRONG&gt;, so they apply to every proxied request for that asset.&lt;/P&gt;
&lt;P class="code-line" data-line="193"&gt;&lt;STRONG&gt;This is the recommended way to set the upstream&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(see Section 10). Using Custom Headers is officially supported; manually writing&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inside the Additional Location Block is a workaround.&lt;/P&gt;
&lt;HR data-line="195" /&gt;
&lt;H2 id="4-what-uri-rewrite-means-in-this-context" class="code-line" dir="auto" data-line="197"&gt;4. What URI Rewrite Means in This Context&lt;/H2&gt;
&lt;P class="code-line" data-line="199"&gt;There are four distinct operations that are often conflated. Understanding the difference is essential before writing any rewrite rule.&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="201"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="201"&gt;
&lt;TR class="code-line" dir="auto" data-line="201"&gt;
&lt;TH&gt;Operation&lt;/TH&gt;
&lt;TH&gt;What happens&lt;/TH&gt;
&lt;TH&gt;Client sees redirect?&lt;/TH&gt;
&lt;TH&gt;Upstream sees rewritten path?&lt;/TH&gt;
&lt;TH&gt;Where to configure&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="203"&gt;
&lt;TR class="code-line" dir="auto" data-line="203"&gt;
&lt;TD&gt;&lt;STRONG&gt;Internal URI rewrite&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;WAF changes&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;before forwarding&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;TD&gt;Yes&lt;/TD&gt;
&lt;TD&gt;Additional Location Block (&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="204"&gt;
&lt;TD&gt;&lt;STRONG&gt;Client redirect&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;WAF sends HTTP 301/302 to client&lt;/TD&gt;
&lt;TD&gt;Yes&lt;/TD&gt;
&lt;TD&gt;No (client re-requests)&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;rewrite ... redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;return 301&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="205"&gt;
&lt;TD&gt;&lt;STRONG&gt;Upstream path via proxy_pass URL&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;proxy_pass appends a fixed path prefix&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;TD&gt;Yes (prefix substitution only)&lt;/TD&gt;
&lt;TD&gt;Portal Reverse Proxy URL field&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="206"&gt;
&lt;TD&gt;&lt;STRONG&gt;Server block routing&lt;/STRONG&gt;&lt;/TD&gt;
&lt;TD&gt;Different location blocks handle different paths&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;TD&gt;Depends on location&lt;/TD&gt;
&lt;TD&gt;Additional Location Block (nested&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="code-line" data-line="208"&gt;For CloudGuard WAF reverse proxy URI rewriting, you almost always want&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;internal URI rewrite&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— the client sends&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/old-path&lt;/CODE&gt;, the WAF forwards&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/new-path&lt;/CODE&gt;, the client is unaware.&lt;/P&gt;
&lt;HR data-line="210" /&gt;
&lt;H2 id="5-critical-limitation-request_uri-vs-uri" class="code-line" dir="auto" data-line="212"&gt;5. Critical Limitation:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;vs&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/H2&gt;
&lt;P class="code-line" data-line="214"&gt;This is the most important technical detail when implementing rewrites in CloudGuard WAF, and the source of the most common failure mode.&lt;/P&gt;
&lt;H3 id="how-nginx-handles-uri-variables" class="code-line" dir="auto" data-line="216"&gt;How nginx handles URI variables&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="218"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="218"&gt;
&lt;TR class="code-line" dir="auto" data-line="218"&gt;
&lt;TH&gt;Variable&lt;/TH&gt;
&lt;TH&gt;What it contains&lt;/TH&gt;
&lt;TH&gt;Modified by&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;?&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="220"&gt;
&lt;TR class="code-line" dir="auto" data-line="220"&gt;
&lt;TD&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Current normalized URI (path only, no query string)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Yes&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— updated each time a rewrite fires&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="221"&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Original URI as sent by client (path + query string)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;No&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— read-only, never changes&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="222"&gt;
&lt;TD&gt;&lt;CODE&gt;$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Query string (without&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;)&lt;/TD&gt;
&lt;TD&gt;No — but preserved by&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flag&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="223"&gt;
&lt;TD&gt;&lt;CODE&gt;$is_args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;if query string exists, empty otherwise&lt;/TD&gt;
&lt;TD&gt;No&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="the-problem-with-cloudguards-generated-proxy_pass" class="code-line" dir="auto" data-line="225"&gt;The problem with CloudGuard's generated proxy_pass&lt;/H3&gt;
&lt;P class="code-line" data-line="227"&gt;CloudGuard WAF generates the following inside the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="229"&gt;&lt;SPAN class="hljs-attribute"&gt;set&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt; http://51.4.115.60:8080;
&lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$request_uri&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="234"&gt;Because&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;uses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;, it always forwards the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;original&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;client URI — regardless of any&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directive that fires before it.&lt;/P&gt;
&lt;P class="code-line" data-line="236"&gt;&lt;STRONG&gt;Example:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="238"&gt;Client request:   GET /chatbot/items HTTP/1.1

rewrite fires:    $uri         = /items   ← updated ✓
                  $request_uri = /chatbot/items  ← unchanged ✗

proxy_pass sends: GET /chatbot/items   ← rewrite had zero effect
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="247"&gt;&lt;STRONG&gt;This means: bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives placed in the Additional Location Block have no effect on what the upstream receives when proxy_pass uses a variable like&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$upstream_endpoint$request_uri&lt;/CODE&gt;.&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="code-line" data-line="249"&gt;This is not a bug in nginx — it is the documented behavior when&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;references&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;explicitly. It becomes a limitation in CloudGuard WAF because the admin cannot change the generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;line.&lt;/P&gt;
&lt;H3 id="why-uriis_argsargs-would-fix-it" class="code-line" dir="auto" data-line="251"&gt;Why&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri$is_args$args&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;would fix it&lt;/H3&gt;
&lt;P class="code-line" data-line="253"&gt;If CloudGuard generated:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="254"&gt;&lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$uri&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$is_args&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$args&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="257"&gt;Then bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;rules in the Additional Location Block would work as expected, because&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is rewrite-aware. This is the correct approach for a rewrite-capable reverse proxy, but it is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;not what CloudGuard currently generates&lt;/STRONG&gt;.&lt;/P&gt;
&lt;HR data-line="259" /&gt;
&lt;H2 id="6-the-workaround-per-path-location-blocks-with-literal-proxy_pass" class="code-line" dir="auto" data-line="261"&gt;6. The Workaround: Per-Path Location Blocks with Literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;/H2&gt;
&lt;P class="code-line" data-line="263"&gt;Because bare rewrite rules are ineffective (see Section 5), the working approach is to define&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;sub-location blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inside the Additional Location Block file. Each sub-location block:&lt;/P&gt;
&lt;OL class="code-line" dir="auto" data-line="265"&gt;
&lt;LI class="code-line" dir="auto" data-line="265"&gt;Matches a specific path pattern&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="266"&gt;Applies the rewrite&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="267"&gt;Uses a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;literal&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;URL (not a variable) pointing directly to the upstream&lt;/LI&gt;
&lt;/OL&gt;
&lt;P class="code-line" data-line="269"&gt;When&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is specified as a literal URL (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;) and a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fires in the same location, nginx uses the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;rewritten&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— not&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— as the upstream path. This is documented nginx behavior for literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;+&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite break&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="271"&gt;&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;    &lt;SPAN class="hljs-comment"&gt;# literal URL → respects $uri after rewrite&lt;/SPAN&gt;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="how-it-works" class="code-line" dir="auto" data-line="278"&gt;How it works&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="280"&gt;Client request:   GET /chatbot/items HTTP/1.1

nginx matches:    location ~ ^/chatbot  ✓
rewrite fires:    $uri = /items
proxy_pass:       literal URL → nginx appends $uri
upstream receives: GET /items HTTP/1.1  ✓
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="why-this-works-but-proxy_pass-varrequest_uri-does-not" class="code-line" dir="auto" data-line="289"&gt;Why this works but&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass $var$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;does not&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="291"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="291"&gt;
&lt;TR class="code-line" dir="auto" data-line="291"&gt;
&lt;TH&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;form&lt;/TH&gt;
&lt;TH&gt;URI appended to upstream&lt;/TH&gt;
&lt;TH&gt;Rewrite-aware?&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="293"&gt;
&lt;TR class="code-line" dir="auto" data-line="293"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://backend" target="_blank" rel="noopener"&gt;http://backend&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(literal, no path)&lt;/TD&gt;
&lt;TD&gt;Rewritten&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;+&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$is_args$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Yes&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="294"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://backend/" target="_blank" rel="noopener"&gt;http://backend/&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(literal, with trailing slash)&lt;/TD&gt;
&lt;TD&gt;Replaces location prefix&lt;/TD&gt;
&lt;TD&gt;Yes (but path manipulation is prefix-based)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="295"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass $variable;&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(original, unmodified)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;No&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="296"&gt;
&lt;TD&gt;&lt;CODE&gt;proxy_pass $variable$request_uri;&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;No&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;BLOCKQUOTE class="code-line" dir="auto" data-line="298"&gt;
&lt;P class="code-line" data-line="298"&gt;&lt;STRONG&gt;Status:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This is an&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;inferred workaround&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;based on nginx's documented behavior and confirmed through testing on a live CloudGuard WAF deployment. It is not explicitly documented in Check Point's official CloudGuard WAF documentation as of the writing of this guide.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="constraint-the-upstream-ip-must-be-hardcoded" class="code-line" dir="auto" data-line="300"&gt;Constraint: the upstream IP must be hardcoded&lt;/H3&gt;
&lt;P class="code-line" data-line="302"&gt;The sub-location&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;must reference the upstream directly (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;). You cannot reference the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$upstream_endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;variable that CloudGuard defines, because using a variable in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;reintroduces the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;problem.&lt;/P&gt;
&lt;P class="code-line" data-line="304"&gt;If your upstream IP changes, you must update the Additional Location Block file and re-enforce.&lt;/P&gt;
&lt;HR data-line="306" /&gt;
&lt;H2 id="7-location-block-file-reference" class="code-line" dir="auto" data-line="308"&gt;7. Location Block File Reference&lt;/H2&gt;
&lt;H3 id="file-format" class="code-line" dir="auto" data-line="310"&gt;File format&lt;/H3&gt;
&lt;P class="code-line" data-line="312"&gt;The Additional Location Block file is a plain text file containing nginx directives. There is no wrapping&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block in the file itself — the content is injected directly inside the generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;.&lt;/P&gt;
&lt;P class="code-line" data-line="314"&gt;However, when using the sub-location workaround, you&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;do&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;include&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks in the file. These become nested locations inside&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;.&lt;/P&gt;
&lt;H3 id="what-to-put-in-the-file" class="code-line" dir="auto" data-line="316"&gt;What to put in the file&lt;/H3&gt;
&lt;P class="code-line" data-line="318"&gt;&lt;STRONG&gt;Pattern A — Bare rewrite (only effective if you can modify proxy_pass, or for redirect use cases):&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="320"&gt;&lt;SPAN class="hljs-comment"&gt;# This is INEFFECTIVE for upstream path rewriting in CloudGuard WAF&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# because proxy_pass uses $request_uri&lt;/SPAN&gt;
&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-path$&lt;/SPAN&gt; /new-path &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="326"&gt;&lt;STRONG&gt;Pattern B — Sub-location with literal proxy_pass (the working workaround):&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="328"&gt;&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/old-path&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-path/?(.*)$&lt;/SPAN&gt; /new-path/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="file-constraints" class="code-line" dir="auto" data-line="335"&gt;File constraints&lt;/H3&gt;
&lt;UL class="code-line" dir="auto" data-line="337"&gt;
&lt;LI class="code-line" dir="auto" data-line="337"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— nginx rejects these inside a location context&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="338"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— same reason&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="339"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;upstream { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— these are http-level; use the Portal's Reverse Proxy settings&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="340"&gt;&lt;STRONG&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;include&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— the file is already an include; recursive includes are not supported by the Portal upload mechanism&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="341"&gt;&lt;STRONG&gt;Avoid unicode characters in comments&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— some CloudGuard nginx builds reject non-ASCII characters in config files, causing nginx config test failure and HTTP 500 on all requests. Use only ASCII in comments.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="342"&gt;&lt;STRONG&gt;Always use ASCII&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;-&amp;gt;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;not&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;→&lt;/CODE&gt;&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in comments for the same reason.&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="verifying-the-file-was-applied" class="code-line" dir="auto" data-line="344"&gt;Verifying the file was applied&lt;/H3&gt;
&lt;P class="code-line" data-line="346"&gt;SSH to the gateway and run:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="348"&gt;&lt;SPAN class="hljs-comment"&gt;# Find which include file belongs to your asset&lt;/SPAN&gt;
sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf

&lt;SPAN class="hljs-comment"&gt;# Read the file&lt;/SPAN&gt;
sudo &lt;SPAN class="hljs-built_in"&gt;cat&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf

&lt;SPAN class="hljs-comment"&gt;# Test nginx config validity&lt;/SPAN&gt;
sudo nginx -t
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="359"&gt;If&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;nginx -t&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;fails, the enforce in the Portal will have produced a 500 error on all requests to that asset.&lt;/P&gt;
&lt;HR data-line="361" /&gt;
&lt;H2 id="8-the-rewrite-directive-in-depth" class="code-line" dir="auto" data-line="363"&gt;8. The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Directive In Depth&lt;/H2&gt;
&lt;H3 id="full-syntax" class="code-line" dir="auto" data-line="365"&gt;Full syntax&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="367"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt; regex replacement [flag];
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;TABLE class="code-line" dir="auto" data-line="371"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="371"&gt;
&lt;TR class="code-line" dir="auto" data-line="371"&gt;
&lt;TH&gt;Part&lt;/TH&gt;
&lt;TH&gt;Description&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="373"&gt;
&lt;TR class="code-line" dir="auto" data-line="373"&gt;
&lt;TD&gt;&lt;CODE&gt;regex&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;PCRE regular expression matched against&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(path only, no query string)&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="374"&gt;
&lt;TD&gt;&lt;CODE&gt;replacement&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;The new URI. Can reference capture groups via&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$1&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$2&lt;/CODE&gt;, etc.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="375"&gt;
&lt;TD&gt;&lt;CODE&gt;flag&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Controls what happens after the rewrite. See flags below.&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="flags" class="code-line" dir="auto" data-line="377"&gt;Flags&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="379"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="379"&gt;
&lt;TR class="code-line" dir="auto" data-line="379"&gt;
&lt;TH&gt;Flag&lt;/TH&gt;
&lt;TH&gt;Behavior&lt;/TH&gt;
&lt;TH&gt;Use in CloudGuard WAF&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="381"&gt;
&lt;TR class="code-line" dir="auto" data-line="381"&gt;
&lt;TD&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Stop processing rewrite rules. Proceed with the current location using the new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;. When combined with a literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;, forwards the rewritten&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to upstream.&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Use this for upstream path rewriting.&lt;/STRONG&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="382"&gt;
&lt;TD&gt;&lt;CODE&gt;last&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Stop processing rewrite rules. Re-initiate location matching with the new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;. Can match a different location block.&lt;/TD&gt;
&lt;TD&gt;Use with caution — can cause loops. Not recommended for proxy rewrites.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="383"&gt;
&lt;TD&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Issue HTTP 302 to the client with the replacement as the Location header.&lt;/TD&gt;
&lt;TD&gt;Use when you want the client to follow a new URL.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="384"&gt;
&lt;TD&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Issue HTTP 301 to the client.&lt;/TD&gt;
&lt;TD&gt;Use for permanent client-visible redirects.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="385"&gt;
&lt;TD&gt;&lt;EM&gt;(none)&lt;/EM&gt;&lt;/TD&gt;
&lt;TD&gt;Continue processing subsequent rewrite rules. The last matching rule applies.&lt;/TD&gt;
&lt;TD&gt;Useful for chaining, but the final&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;will still use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;.&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="regex-syntax-pcre" class="code-line" dir="auto" data-line="387"&gt;Regex syntax (PCRE)&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="389"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="389"&gt;
&lt;TR class="code-line" dir="auto" data-line="389"&gt;
&lt;TH&gt;Construct&lt;/TH&gt;
&lt;TH&gt;Meaning&lt;/TH&gt;
&lt;TH&gt;Example&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="391"&gt;
&lt;TR class="code-line" dir="auto" data-line="391"&gt;
&lt;TD&gt;&lt;CODE&gt;^&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Anchor: start of string&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/api&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches URIs starting with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="392"&gt;
&lt;TD&gt;&lt;CODE&gt;$&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Anchor: end of string&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;/endpoint$&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches URIs ending with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/endpoint&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="393"&gt;
&lt;TD&gt;&lt;CODE&gt;(.*)&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Capture group: zero or more of any character&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/chatbot/(.*)$&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;captures everything after&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot/&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="394"&gt;
&lt;TD&gt;&lt;CODE&gt;([^/]+)&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Capture group: one or more non-slash characters&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/users/([^/]+)/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;captures a path segment&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="395"&gt;
&lt;TD&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Makes the preceding character optional&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;/?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches optional trailing slash&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="396"&gt;
&lt;TD&gt;&lt;CODE&gt;$1&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$2&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Backreference to 1st, 2nd capture group&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;/$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;inserts first captured group&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="397"&gt;
&lt;TD&gt;&lt;CODE&gt;\.&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Escaped dot (literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.&lt;/CODE&gt;)&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;\.json$&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches URIs ending in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.json&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="398"&gt;
&lt;TD&gt;&lt;CODE&gt;(foo|bar)&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Alternation&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;^/(foo|bar)/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;matches&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/foo/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/bar/&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="query-string-behavior" class="code-line" dir="auto" data-line="400"&gt;Query string behavior&lt;/H3&gt;
&lt;P class="code-line" data-line="402"&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directive operates on&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;—&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;the path only, without the query string&lt;/STRONG&gt;. The query string (&lt;CODE&gt;$args&lt;/CODE&gt;) is handled separately:&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="404"&gt;
&lt;LI class="code-line" dir="auto" data-line="404"&gt;With&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;last&lt;/CODE&gt;: the original query string is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;automatically appended&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the rewritten URI when forwarded.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;GET /chatbot/search?foo=bar&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;rewritten to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/search&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;arrives at the upstream as&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/search?foo=bar&lt;/CODE&gt;.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="405"&gt;With&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;/&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;: the query string is appended to the redirect Location header.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="406"&gt;To&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;drop&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the query string in a rewrite: end the replacement with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ^/old$ /new? break;&lt;/CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="rewrite-evaluation-order" class="code-line" dir="auto" data-line="408"&gt;Rewrite evaluation order&lt;/H3&gt;
&lt;P class="code-line" data-line="410"&gt;When multiple&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives exist in the same context, nginx evaluates them&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;in order&lt;/STRONG&gt;. The first matching rule with a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or redirect flag stops processing. Without a flag, all rules are tested and the last match wins before proxy_pass.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="412"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api/v1/(.*)$&lt;/SPAN&gt; /v1/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;   &lt;SPAN class="hljs-comment"&gt;# matches /api/v1/* → stops here&lt;/SPAN&gt;
&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api/(.*)$&lt;/SPAN&gt; /legacy/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;   &lt;SPAN class="hljs-comment"&gt;# never reached for /api/v1/* paths&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="417" /&gt;
&lt;H2 id="9-nginx-variables-available-inside-the-location-block" class="code-line" dir="auto" data-line="419"&gt;9. NGINX Variables Available Inside the Location Block&lt;/H2&gt;
&lt;P class="code-line" data-line="421"&gt;These variables are available inside the Additional Location Block and behave as in standard nginx.&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="423"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="423"&gt;
&lt;TR class="code-line" dir="auto" data-line="423"&gt;
&lt;TH&gt;Variable&lt;/TH&gt;
&lt;TH&gt;Contains&lt;/TH&gt;
&lt;TH&gt;Notes&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="425"&gt;
&lt;TR class="code-line" dir="auto" data-line="425"&gt;
&lt;TD&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Current request URI (path only, no&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or query string)&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Updated by&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;/STRONG&gt;. Use this, not&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;, if you need the post-rewrite path.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="426"&gt;
&lt;TD&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Original URI as sent by client, including query string&lt;/TD&gt;
&lt;TD&gt;&lt;STRONG&gt;Read-only. Never modified.&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This is what CloudGuard's generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;uses.&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="427"&gt;
&lt;TD&gt;&lt;CODE&gt;$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Query string without the leading&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;foo=bar&amp;amp;x=1&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="428"&gt;
&lt;TD&gt;&lt;CODE&gt;$is_args&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;if&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$args&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is non-empty, otherwise empty string&lt;/TD&gt;
&lt;TD&gt;Useful for constructing URIs:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri$is_args$args&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="429"&gt;
&lt;TD&gt;&lt;CODE&gt;$host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;request header (or server name if absent)&lt;/TD&gt;
&lt;TD&gt;Value the client sent&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="430"&gt;
&lt;TD&gt;&lt;CODE&gt;$http_host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Raw&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header including port&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;jwt.cpwaf.net:8080&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="431"&gt;
&lt;TD&gt;&lt;CODE&gt;$remote_addr&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Client IP address&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="432"&gt;
&lt;TD&gt;&lt;CODE&gt;$scheme&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Request scheme:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;https&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="433"&gt;
&lt;TD&gt;&lt;CODE&gt;$server_name&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;nginx&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server_name&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;value for this virtual host&lt;/TD&gt;
&lt;TD&gt;&amp;nbsp;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="434"&gt;
&lt;TD&gt;&lt;CODE&gt;$http_&amp;lt;name&amp;gt;&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Any request header, lowercased, hyphens replaced with underscores&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$http_x_forwarded_for&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$http_authorization&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="435"&gt;
&lt;TD&gt;&lt;CODE&gt;$upstream_endpoint&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Set by CloudGuard to the configured upstream URL&lt;/TD&gt;
&lt;TD&gt;E.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;&lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— available but problematic in&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(see Section 5)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;HR data-line="437" /&gt;
&lt;H2 id="10-setting-the-host-header" class="code-line" dir="auto" data-line="439"&gt;10. Setting the Host Header&lt;/H2&gt;
&lt;P class="code-line" data-line="441"&gt;The upstream backend may enforce a specific&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header and reject requests with the wrong value (HTTP 403 or 421). CloudGuard WAF by default forwards the original client&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header to the upstream, which is almost never the correct backend hostname.&lt;/P&gt;
&lt;H3 id="recommended-method-custom-headers-in-the-portal" class="code-line" dir="auto" data-line="443"&gt;Recommended method: Custom Headers in the Portal&lt;/H3&gt;
&lt;P class="code-line" data-line="445"&gt;&lt;STRONG&gt;Infinity Portal → Policy → Asset → Advanced Proxy Settings → Add custom headers&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="447"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="447"&gt;
&lt;TR class="code-line" dir="auto" data-line="447"&gt;
&lt;TH&gt;Name&lt;/TH&gt;
&lt;TH&gt;Value&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="449"&gt;
&lt;TR class="code-line" dir="auto" data-line="449"&gt;
&lt;TD&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;cpfakedomain.com&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="code-line" data-line="451"&gt;This renders as&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header Host cpfakedomain.com;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;at the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;server block level&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in the generated nginx config, applying to all requests for this asset. This is the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;officially supported method&lt;/STRONG&gt;.&lt;/P&gt;
&lt;BLOCKQUOTE class="code-line" dir="auto" data-line="453"&gt;
&lt;P class="code-line" data-line="453"&gt;The Portal UI displays:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;EM&gt;"You don't need to add the proxy_set_header header, as it will be automatically included in the configuration."&lt;/EM&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;This note refers to standard forwarded headers (X-Forwarded-For, etc.) — it is not saying you cannot add Host. Adding Host via Custom Headers is intentional and works correctly.&lt;/P&gt;
&lt;/BLOCKQUOTE&gt;
&lt;H3 id="alternative-proxy_set_header-inside-the-additional-location-block" class="code-line" dir="auto" data-line="455"&gt;Alternative: proxy_set_header inside the Additional Location Block&lt;/H3&gt;
&lt;P class="code-line" data-line="457"&gt;If for any reason you need the Host header set only for specific sub-location blocks:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="459"&gt;&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/api&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
    &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="467"&gt;When using sub-location blocks (the workaround), server-level&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;are inherited&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;by sub-locations that do not override them. So if you set&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;via the Custom Headers UI, it applies inside your sub-location blocks as well — you do not need to repeat it.&lt;/P&gt;
&lt;H3 id="why-this-matters-for-the-demotest-setup" class="code-line" dir="auto" data-line="469"&gt;Why this matters for the demo/test setup&lt;/H3&gt;
&lt;P class="code-line" data-line="471"&gt;If the upstream enforces Host validation and you forget to set it:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="473"&gt;Client → WAF → Upstream
                ← 403 Forbidden (wrong Host: jwt.cpwaf.net, expected: cpfakedomain.com)
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="478"&gt;Without&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_set_header Host&lt;/CODE&gt;, the upstream receives whatever the client sent — typically the WAF's public DNS name. Every request through the WAF will return 403, and it will look like a WAF problem when it is actually a Host header problem. Always verify the Host header first when debugging 403 errors on a new asset.&lt;/P&gt;
&lt;HR data-line="480" /&gt;
&lt;H2 id="11-rewrite-pattern-catalogue" class="code-line" dir="auto" data-line="482"&gt;11. Rewrite Pattern Catalogue&lt;/H2&gt;
&lt;P class="code-line" data-line="484"&gt;All patterns below are for the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Additional Location Block&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file using the sub-location workaround. Replace&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;51.4.115.60:8080&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;with your upstream address.&lt;/P&gt;
&lt;H3 id="pattern-1--simple-prefix-strip" class="code-line" dir="auto" data-line="486"&gt;Pattern 1 — Simple prefix strip&lt;/H3&gt;
&lt;P class="code-line" data-line="488"&gt;Remove a path prefix before forwarding. Classic use case: a WAF asset is exposed at&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;but the upstream serves everything from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="490"&gt;&lt;SPAN class="hljs-comment"&gt;# /chatbot          -&amp;gt; /&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /chatbot/foo/bar  -&amp;gt; /foo/bar&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="499"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="500"&gt;
&lt;LI class="code-line" dir="auto" data-line="500"&gt;&lt;CODE&gt;^/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— URI starts with&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="501"&gt;&lt;CODE&gt;/?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— optional trailing slash after&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;chatbot&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="502"&gt;&lt;CODE&gt;(.*)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture everything after (may be empty)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="503"&gt;&lt;CODE&gt;/$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— prepend&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the captured group (handles the bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;→&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;case)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-2--prefix-replacement" class="code-line" dir="auto" data-line="505"&gt;Pattern 2 — Prefix replacement&lt;/H3&gt;
&lt;P class="code-line" data-line="507"&gt;Replace one path prefix with another. The client uses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api/v1/...&lt;/CODE&gt;, the upstream expects&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/v1/...&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="509"&gt;&lt;SPAN class="hljs-comment"&gt;# /api/v1/items  -&amp;gt; /v1/items&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /api/v1/users  -&amp;gt; /v1/users&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/api/v1&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api(/v1/.*)$&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="518"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="519"&gt;
&lt;LI class="code-line" dir="auto" data-line="519"&gt;&lt;CODE&gt;^/api&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— match starts at&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/api&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="520"&gt;&lt;CODE&gt;(/v1/.*)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/v1/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;and everything after it&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="521"&gt;&lt;CODE&gt;$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— the replacement IS the capture group (no extra prefix)&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-3--path-injection-add-a-prefix" class="code-line" dir="auto" data-line="523"&gt;Pattern 3 — Path injection (add a prefix)&lt;/H3&gt;
&lt;P class="code-line" data-line="525"&gt;The client accesses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/public/...&lt;/CODE&gt;, the upstream serves static assets from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/static/public/...&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="527"&gt;&lt;SPAN class="hljs-comment"&gt;# /public/logo.png       -&amp;gt; /static/public/logo.png&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /public/css/main.css   -&amp;gt; /static/public/css/main.css&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/public&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^(/public/.*)$&lt;/SPAN&gt; /static&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="536"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="537"&gt;
&lt;LI class="code-line" dir="auto" data-line="537"&gt;&lt;CODE&gt;^(/public/.*)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture the entire path starting from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/public/&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="538"&gt;&lt;CODE&gt;/static$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— prepend&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/static&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the full captured path&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-4--full-path-swap" class="code-line" dir="auto" data-line="540"&gt;Pattern 4 — Full path swap&lt;/H3&gt;
&lt;P class="code-line" data-line="542"&gt;An exact-match rewrite. No wildcards; the entire path is replaced.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="544"&gt;&lt;SPAN class="hljs-comment"&gt;# /old-endpoint  -&amp;gt; /new-endpoint  (exact match only)&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; = /old-endpoint {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-endpoint$&lt;/SPAN&gt; /new-endpoint &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="552"&gt;Using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location = /old-endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(exact match) is more efficient than regex for single-path swaps.&lt;/P&gt;
&lt;H3 id="pattern-5--regex-capture-with-segment-reordering" class="code-line" dir="auto" data-line="554"&gt;Pattern 5 — Regex capture with segment reordering&lt;/H3&gt;
&lt;P class="code-line" data-line="556"&gt;Reorder path segments. The client sends&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/users/&amp;lt;id&amp;gt;/profile&lt;/CODE&gt;, the upstream expects&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/profile/&amp;lt;id&amp;gt;&lt;/CODE&gt;.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="558"&gt;&lt;SPAN class="hljs-comment"&gt;# /users/42/profile    -&amp;gt; /profile/42&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# /users/alice/profile -&amp;gt; /profile/alice&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/users/[^/]+/profile$&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/users/([^/]+)/profile$&lt;/SPAN&gt; /profile/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="567"&gt;&lt;STRONG&gt;Regex explained:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="568"&gt;
&lt;LI class="code-line" dir="auto" data-line="568"&gt;&lt;CODE&gt;([^/]+)&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— capture one or more non-slash characters (the user ID)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="569"&gt;&lt;CODE&gt;/profile/$1&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— place the captured ID after&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/profile/&lt;/CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="pattern-6--query-string-preservation" class="code-line" dir="auto" data-line="571"&gt;Pattern 6 — Query string preservation&lt;/H3&gt;
&lt;P class="code-line" data-line="573"&gt;Query strings are preserved automatically with the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flag. No special handling is needed.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="575"&gt;&lt;SPAN class="hljs-comment"&gt;# /chatbot/search?foo=bar&amp;amp;x=1  -&amp;gt; /search?foo=bar&amp;amp;x=1&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="583"&gt;To&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;drop&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;the query string intentionally, append&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to the replacement:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="585"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt;? &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="pattern-7--multi-pattern-combined-file" class="code-line" dir="auto" data-line="589"&gt;Pattern 7 — Multi-pattern combined file&lt;/H3&gt;
&lt;P class="code-line" data-line="591"&gt;A complete Additional Location Block file covering all the above cases:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="593"&gt;&lt;SPAN class="hljs-comment"&gt;# Pattern 1 - Simple prefix strip: /chatbot/* -&amp;gt; /*&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/chatbot&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 2 - Prefix replacement: /api/v1/* -&amp;gt; /v1/*&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/api/v1&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/api(/v1/.*)$&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 3 - Path injection: /public/* -&amp;gt; /static/public/*&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/public&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^(/public/.*)$&lt;/SPAN&gt; /static&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 4 - Full path swap: /old-endpoint -&amp;gt; /new-endpoint&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; = /old-endpoint {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/old-endpoint$&lt;/SPAN&gt; /new-endpoint &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}

&lt;SPAN class="hljs-comment"&gt;# Pattern 5 - Regex reorder: /users/&amp;lt;id&amp;gt;/profile -&amp;gt; /profile/&amp;lt;id&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; &lt;SPAN class="hljs-regexp"&gt;~ ^/users/[^/]+/profile$&lt;/SPAN&gt; {
    &lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/users/([^/]+)/profile$&lt;/SPAN&gt; /profile/&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; http://51.4.115.60:8080;
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="625" /&gt;
&lt;H2 id="12-generated-nginx-artifacts" class="code-line" dir="auto" data-line="627"&gt;12. Generated NGINX Artifacts&lt;/H2&gt;
&lt;H3 id="file-locations-on-the-gateway-host" class="code-line" dir="auto" data-line="629"&gt;File locations on the gateway host&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line" dir="auto" data-line="631"&gt;/etc/cp/conf/rpmanager/
├── nginx.conf                          # Main nginx config (auto-generated, do not edit)
├── servers/
│   ├── 00_nginx_conf_include.conf      # Global includes (auto-generated)
│   ├── 80_jwt.cpwaf.net.conf         # Per-asset server block (auto-generated)
│   └── 127.0.0.1_5555.conf            # Internal health check (auto-generated)
└── include/
    ├── waf_0_additional_location_config.conf   # Injection point for asset 0
    ├── waf_1_additional_location_config.conf   # Injection point for asset 1
    ...
    └── waf_N_additional_location_config.conf   # Your file lands here
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="how-cloudguard-assigns-waf_n-files-to-assets" class="code-line" dir="auto" data-line="645"&gt;How CloudGuard assigns waf_N files to assets&lt;/H3&gt;
&lt;P class="code-line" data-line="647"&gt;CloudGuard assigns a sequential index&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(0–9, then a–f in hex) to each WAF asset. The mapping between asset and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is managed internally by the management plane and is&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;not guaranteed to be stable&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;across portal re-enforcements or gateway restarts. Always verify the current mapping with:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="649"&gt;sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="what-a-full-generated-server-block-looks-like-annotated" class="code-line" dir="auto" data-line="653"&gt;What a full generated server block looks like (annotated)&lt;/H3&gt;
&lt;P class="code-line" data-line="655"&gt;Verified output from&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;sudo cat /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;on a live CloudGuard WAF gateway:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="657"&gt;&lt;SPAN class="hljs-comment"&gt;# Auto-generated by CloudGuard WAF management. DO NOT EDIT MANUALLY.&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# Changes are overwritten on next policy enforce.&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Used internally for rate-limit logging decisions&lt;/SPAN&gt;
&lt;SPAN class="hljs-attribute"&gt;map&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$status&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$RateLimitLoggable&lt;/SPAN&gt; {
    429 1;
    &lt;SPAN class="hljs-attribute"&gt;default&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;0&lt;/SPAN&gt;;
}

&lt;SPAN class="hljs-section"&gt;server&lt;/SPAN&gt;
{
    &lt;SPAN class="hljs-attribute"&gt;listen&lt;/SPAN&gt;  &lt;SPAN class="hljs-number"&gt;80&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;server_name&lt;/SPAN&gt; jwt.cpwaf.net;

    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_headers&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;
    &lt;SPAN class="hljs-attribute"&gt;proxy_pass_request_body&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;on&lt;/SPAN&gt;;

    &lt;SPAN class="hljs-comment"&gt;# Generated ONLY because "Host: cpfakedomain.com" was added in&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# Portal -&amp;gt; Advanced Proxy Settings -&amp;gt; Custom Headers.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-comment"&gt;# This line is absent by default if no custom Host header is configured.&lt;/SPAN&gt;
    &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;

    &lt;SPAN class="hljs-attribute"&gt;access_log&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;off&lt;/SPAN&gt;;                                      &lt;SPAN class="hljs-comment"&gt;# access logging disabled by default&lt;/SPAN&gt;
    &lt;SPAN class="hljs-attribute"&gt;error_log&lt;/SPAN&gt; /var/log/nginx/&lt;SPAN class="hljs-literal"&gt;error&lt;/SPAN&gt;.log &lt;SPAN class="hljs-literal"&gt;warn&lt;/SPAN&gt;;             &lt;SPAN class="hljs-comment"&gt;# fixed path, not configurable here&lt;/SPAN&gt;

    &lt;SPAN class="hljs-comment"&gt;# SSL Client Certificate JavaScript Processing      # placeholder — unused unless mTLS configured&lt;/SPAN&gt;

    &lt;SPAN class="hljs-attribute"&gt;resolver&lt;/SPAN&gt; &lt;SPAN class="hljs-number"&gt;168.63.129.16&lt;/SPAN&gt; ipv6=&lt;SPAN class="hljs-literal"&gt;off&lt;/SPAN&gt;;                    &lt;SPAN class="hljs-comment"&gt;# Azure DNS resolver (deployment-specific)&lt;/SPAN&gt;

    &lt;SPAN class="hljs-section"&gt;location&lt;/SPAN&gt; /
    {
        &lt;SPAN class="hljs-comment"&gt;# === YOUR ADDITIONAL LOCATION BLOCK CONTENT IS INJECTED HERE ===&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;include&lt;/SPAN&gt;   /etc/cp/conf/rpmanager/include/waf_5_additional_location_config.conf;

 &lt;SPAN class="hljs-comment"&gt;#unused redirect;                                       # CloudGuard placeholder — not active&lt;/SPAN&gt;
 &lt;SPAN class="hljs-comment"&gt;#unused DNS server;&lt;/SPAN&gt;

        &lt;SPAN class="hljs-comment"&gt;# Generated upstream variable from Portal Reverse Proxy settings&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;set&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt; http://51.4.115.60:8080;

        &lt;SPAN class="hljs-comment"&gt;# THIS uses $request_uri — see Section 5 for why rewrites require a workaround&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;proxy_pass&lt;/SPAN&gt; &lt;SPAN class="hljs-variable"&gt;$upstream_endpoint&lt;/SPAN&gt;&lt;SPAN class="hljs-variable"&gt;$request_uri&lt;/SPAN&gt;;

        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Host cpfakedomain.com;          &lt;SPAN class="hljs-comment"&gt;# repeated here even if set at server level&lt;/SPAN&gt;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; X-Forwarded-For &lt;SPAN class="hljs-variable"&gt;$proxy_add_x_forwarded_for&lt;/SPAN&gt;;
 &lt;SPAN class="hljs-comment"&gt;#unused access_log;&lt;/SPAN&gt;
 &lt;SPAN class="hljs-comment"&gt;#unused access syslog;&lt;/SPAN&gt;

        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Upgrade &lt;SPAN class="hljs-variable"&gt;$http_upgrade&lt;/SPAN&gt;;
        &lt;SPAN class="hljs-attribute"&gt;proxy_set_header&lt;/SPAN&gt; Connection &lt;SPAN class="hljs-string"&gt;"Upgrade"&lt;/SPAN&gt;;
 &lt;SPAN class="hljs-comment"&gt;#unused header;                                         # placeholders for optional headers&lt;/SPAN&gt;
    }
}
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="713"&gt;&lt;STRONG&gt;Notable observations from the real output:&lt;/STRONG&gt;&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="714"&gt;
&lt;LI class="code-line" dir="auto" data-line="714"&gt;&lt;CODE&gt;#unused&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;comment lines are CloudGuard-generated placeholders for features that are configured elsewhere in the Portal (redirects, rate limits, custom headers, access logging). They are inert — nginx treats them as comments.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="715"&gt;&lt;CODE&gt;proxy_set_header Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;appears&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;twice&lt;/STRONG&gt;: once at the server block level (from Custom Headers) and once inside&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location /&lt;/CODE&gt;. Both are generated by CloudGuard; the location-level one takes precedence for proxied requests.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="716"&gt;&lt;CODE&gt;access_log off&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;is hardcoded. To enable nginx-level access logging you must add it via the Additional Server Block.&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="717"&gt;The Azure DNS resolver (&lt;CODE&gt;168.63.129.16&lt;/CODE&gt;) is deployment-specific. On non-Azure gateways this will differ.&lt;/LI&gt;
&lt;/UL&gt;
&lt;HR data-line="719" /&gt;
&lt;H2 id="13-deployment-procedure-infinity-portal" class="code-line" dir="auto" data-line="721"&gt;13. Deployment Procedure (Infinity Portal)&lt;/H2&gt;
&lt;H3 id="step-1-prepare-the-location-block-file" class="code-line" dir="auto" data-line="723"&gt;Step 1: Prepare the location block file&lt;/H3&gt;
&lt;P class="code-line" data-line="725"&gt;Create a plain text file (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location-block.conf&lt;/CODE&gt;) with your rewrite sub-locations. Rules:&lt;/P&gt;
&lt;UL class="code-line" dir="auto" data-line="726"&gt;
&lt;LI class="code-line" dir="auto" data-line="726"&gt;ASCII only in comments&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="727"&gt;No&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;upstream&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="728"&gt;Use literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;not variables&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="729"&gt;Test regex patterns locally with:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;echo "/your/path" | grep -P 'your_pattern'&lt;/CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3 id="step-2-set-the-upstream-in-the-portal" class="code-line" dir="auto" data-line="731"&gt;Step 2: Set the upstream in the Portal&lt;/H3&gt;
&lt;P class="code-line" data-line="733"&gt;&lt;STRONG&gt;Policy → Asset → Reverse Proxy → WAF will reach the application at:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="code-line" data-line="735"&gt;Set this to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;&lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;&lt;/CODE&gt;. This defines&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$upstream_endpoint&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in the generated config and is used for health checks.&lt;/P&gt;
&lt;H3 id="step-3-set-the-host-header" class="code-line" dir="auto" data-line="737"&gt;Step 3: Set the Host header&lt;/H3&gt;
&lt;P class="code-line" data-line="739"&gt;&lt;STRONG&gt;Policy → Asset → Advanced Proxy Settings → Add custom headers&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="741"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="741"&gt;
&lt;TR class="code-line" dir="auto" data-line="741"&gt;
&lt;TH&gt;Name&lt;/TH&gt;
&lt;TH&gt;Value&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="743"&gt;
&lt;TR class="code-line" dir="auto" data-line="743"&gt;
&lt;TD&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;&amp;lt;expected-hostname-by-backend&amp;gt;&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="step-4-upload-the-location-block-file" class="code-line" dir="auto" data-line="745"&gt;Step 4: Upload the location block file&lt;/H3&gt;
&lt;P class="code-line" data-line="747"&gt;&lt;STRONG&gt;Policy → Asset → Advanced Proxy Settings → Additional location block instructions → Upload&lt;/STRONG&gt;&lt;/P&gt;
&lt;P class="code-line" data-line="749"&gt;Select your&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;.conf&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;file and click OK.&lt;/P&gt;
&lt;H3 id="step-5-enforce-the-policy" class="code-line" dir="auto" data-line="751"&gt;Step 5: Enforce the policy&lt;/H3&gt;
&lt;P class="code-line" data-line="753"&gt;Click&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Enforce&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;Publish&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;depending on your portal version). CloudGuard will:&lt;/P&gt;
&lt;OL class="code-line" dir="auto" data-line="754"&gt;
&lt;LI class="code-line" dir="auto" data-line="754"&gt;Write your file to&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="755"&gt;Regenerate the server block&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="756"&gt;Run&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;nginx -t&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="757"&gt;If the test passes: reload nginx (&lt;CODE&gt;nginx -s reload&lt;/CODE&gt;)&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="758"&gt;If the test fails: nginx is not reloaded; all requests to the asset return HTTP 500&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="step-6-verify-see-section-14" class="code-line" dir="auto" data-line="760"&gt;Step 6: Verify (see Section 14)&lt;/H3&gt;
&lt;HR data-line="762" /&gt;
&lt;H2 id="14-validation-and-testing" class="code-line" dir="auto" data-line="764"&gt;14. Validation and Testing&lt;/H2&gt;
&lt;H3 id="verify-the-file-was-written-correctly" class="code-line" dir="auto" data-line="766"&gt;Verify the file was written correctly&lt;/H3&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="768"&gt;&lt;SPAN class="hljs-comment"&gt;# Find your asset's include file&lt;/SPAN&gt;
sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf

&lt;SPAN class="hljs-comment"&gt;# Read it&lt;/SPAN&gt;
sudo &lt;SPAN class="hljs-built_in"&gt;cat&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_N_additional_location_config.conf

&lt;SPAN class="hljs-comment"&gt;# Confirm nginx is running cleanly&lt;/SPAN&gt;
sudo nginx -t
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="test-each-rewrite-pattern-with-curl" class="code-line" dir="auto" data-line="779"&gt;Test each rewrite pattern with curl&lt;/H3&gt;
&lt;P class="code-line" data-line="781"&gt;The&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;-v&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flag shows request/response headers. The backend JSON response echoes back&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;path&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;host&lt;/CODE&gt;, and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;query_string&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;for easy verification.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="783"&gt;&lt;SPAN class="hljs-comment"&gt;# Pattern 1 — prefix strip&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/chatbot
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /&lt;/SPAN&gt;

curl -v http://jwt.cpwaf.net/chatbot/items
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /items&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 2 — prefix replacement&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/api/v1/items
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /v1/items&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 3 — path injection&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/public/logo.png
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /static/public/logo.png&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 4 — full path swap&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/old-endpoint
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /new-endpoint&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 5 — regex reorder&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/users/42/profile
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /profile/42&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Pattern 6 — query string preservation&lt;/SPAN&gt;
curl -v &lt;SPAN class="hljs-string"&gt;"http://jwt.cpwaf.net/chatbot/search?foo=bar&amp;amp;x=1"&lt;/SPAN&gt;
&lt;SPAN class="hljs-comment"&gt;# Expected: backend receives GET /search?foo=bar&amp;amp;x=1&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Host header verification&lt;/SPAN&gt;
curl -v http://jwt.cpwaf.net/
&lt;SPAN class="hljs-comment"&gt;# Expected: backend JSON shows "host": "cpfakedomain.com"&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Host enforcement (direct to backend — should 403)&lt;/SPAN&gt;
curl -v -H &lt;SPAN class="hljs-string"&gt;"Host: wronghost.example.com"&lt;/SPAN&gt; http://51.4.115.60:8080/
&lt;SPAN class="hljs-comment"&gt;# Expected: 403 from backend&lt;/SPAN&gt;

&lt;SPAN class="hljs-comment"&gt;# Host enforcement (direct to backend — should 200)&lt;/SPAN&gt;
curl -v -H &lt;SPAN class="hljs-string"&gt;"Host: cpfakedomain.com"&lt;/SPAN&gt; http://51.4.115.60:8080/
&lt;SPAN class="hljs-comment"&gt;# Expected: 200 from backend&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="824" /&gt;
&lt;H2 id="15-logging-implications" class="code-line" dir="auto" data-line="826"&gt;15. Logging Implications&lt;/H2&gt;
&lt;H3 id="access-log" class="code-line" dir="auto" data-line="828"&gt;Access log&lt;/H3&gt;
&lt;P class="code-line" data-line="830"&gt;By default, CloudGuard WAF's nginx has access logging&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;disabled&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in generated server blocks (&lt;CODE&gt;access_log off;&lt;/CODE&gt;). WAF-level access events are logged through the Check Point unified logging infrastructure (SmartConsole / Log &amp;amp; Monitor), not through nginx access logs.&lt;/P&gt;
&lt;P class="code-line" data-line="832"&gt;To enable raw nginx access logging for debugging, add to the Additional Server Block:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="834"&gt;&lt;SPAN class="hljs-attribute"&gt;access_log&lt;/SPAN&gt; /var/log/nginx/access_debug.log;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="838"&gt;This is a temporary debugging measure. Remove it before production use.&lt;/P&gt;
&lt;H3 id="error-log" class="code-line" dir="auto" data-line="840"&gt;Error log&lt;/H3&gt;
&lt;P class="code-line" data-line="842"&gt;The error log is configured at the server block level by CloudGuard:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="844"&gt;&lt;SPAN class="hljs-attribute"&gt;error_log&lt;/SPAN&gt; /var/log/nginx/&lt;SPAN class="hljs-literal"&gt;error&lt;/SPAN&gt;.log &lt;SPAN class="hljs-literal"&gt;warn&lt;/SPAN&gt;;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="848"&gt;When a location block file contains a syntax error, nginx fails its config test and&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;does not reload&lt;/STRONG&gt;. The error is visible in:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="850"&gt;sudo nginx -t 2&amp;gt;&amp;amp;1
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="854"&gt;If nginx rejects the config, all requests to the affected asset return HTTP 500, because nginx is running the previous (last-good) config, which does not include your changes.&lt;/P&gt;
&lt;H3 id="tracking-which-requests-hit-your-rewrite-rules" class="code-line" dir="auto" data-line="856"&gt;Tracking which requests hit your rewrite rules&lt;/H3&gt;
&lt;P class="code-line" data-line="858"&gt;Since access logging is off by default, the best way to observe what the backend receives is to instrument the&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;STRONG&gt;backend&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;to log the incoming request URI and Host header. The Flask backend in this project echoes both back as JSON, making it ideal for testing.&lt;/P&gt;
&lt;P class="code-line" data-line="860"&gt;Alternatively, enable access logging on the Additional Server Block temporarily and inspect&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/var/log/nginx/access_debug.log&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;on the gateway host:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="862"&gt;sudo &lt;SPAN class="hljs-built_in"&gt;tail&lt;/SPAN&gt; -f /var/log/nginx/access_debug.log
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;HR data-line="866" /&gt;
&lt;H2 id="16-troubleshooting-guide" class="code-line" dir="auto" data-line="868"&gt;16. Troubleshooting Guide&lt;/H2&gt;
&lt;H3 id="http-500-on-all-requests-to-the-asset-after-enforce" class="code-line" dir="auto" data-line="870"&gt;HTTP 500 on all requests to the asset after enforce&lt;/H3&gt;
&lt;P class="code-line" data-line="872"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;nginx config test failed. Your location block file has a syntax error.&lt;/P&gt;
&lt;P class="code-line" data-line="874"&gt;&lt;STRONG&gt;Diagnosis:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="875"&gt;sudo nginx -t 2&amp;gt;&amp;amp;1
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="879"&gt;&lt;STRONG&gt;Common causes and fixes:&lt;/STRONG&gt;&lt;/P&gt;
&lt;TABLE class="code-line" dir="auto" data-line="881"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="881"&gt;
&lt;TR class="code-line" dir="auto" data-line="881"&gt;
&lt;TH&gt;Error message&lt;/TH&gt;
&lt;TH&gt;Cause&lt;/TH&gt;
&lt;TH&gt;Fix&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="883"&gt;
&lt;TR class="code-line" dir="auto" data-line="883"&gt;
&lt;TD&gt;&lt;CODE&gt;host not found in upstream "upstream"&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Used&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://upstream" target="_blank" rel="noopener"&gt;http://upstream&lt;/A&gt;;&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;with a placeholder name&lt;/TD&gt;
&lt;TD&gt;Replace with the actual IP:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass &lt;A href="http://51.4.115.60:8080" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080&lt;/A&gt;;&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="884"&gt;
&lt;TD&gt;&lt;CODE&gt;unexpected "{"&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Used&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;server { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;http { }&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block in the location block file&lt;/TD&gt;
&lt;TD&gt;Remove — these are not allowed&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="885"&gt;
&lt;TD&gt;&lt;CODE&gt;invalid number of arguments&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Syntax error in a directive&lt;/TD&gt;
&lt;TD&gt;Check directive spelling and argument count&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="886"&gt;
&lt;TD&gt;&lt;CODE&gt;pcre_compile() failed&lt;/CODE&gt;&lt;/TD&gt;
&lt;TD&gt;Invalid regex&lt;/TD&gt;
&lt;TD&gt;Test your regex:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;echo "/path" | grep -P 'your_regex'&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="887"&gt;
&lt;TD&gt;Non-ASCII character error&lt;/TD&gt;
&lt;TD&gt;Unicode in comments (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;→&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;–&lt;/CODE&gt;)&lt;/TD&gt;
&lt;TD&gt;Replace with ASCII equivalents (&lt;CODE&gt;-&amp;gt;&lt;/CODE&gt;,&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;-&lt;/CODE&gt;)&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;H3 id="rewrite-rules-uploaded-but-paths-are-not-being-rewritten" class="code-line" dir="auto" data-line="889"&gt;Rewrite rules uploaded but paths are not being rewritten&lt;/H3&gt;
&lt;P class="code-line" data-line="891"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Bare&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;directives (without sub-&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;wrappers) have no effect because the generated&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass $upstream_endpoint$request_uri&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;uses&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$request_uri&lt;/CODE&gt;, which is never modified by rewrites.&lt;/P&gt;
&lt;P class="code-line" data-line="893"&gt;&lt;STRONG&gt;Diagnosis:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="894"&gt;&lt;SPAN class="hljs-comment"&gt;# Check what the backend actually receives&lt;/SPAN&gt;
curl -s http://&amp;lt;waf-hostname&amp;gt;/your-path | jq .path
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="899"&gt;If the backend still receives the original path, use sub-&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;blocks with a literal&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;(see Section 6).&lt;/P&gt;
&lt;H3 id="http-403-on-every-request-through-the-waf" class="code-line" dir="auto" data-line="901"&gt;HTTP 403 on every request through the WAF&lt;/H3&gt;
&lt;P class="code-line" data-line="903"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The upstream is enforcing a&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header check and the WAF is forwarding the client's&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;header instead of the backend's expected hostname.&lt;/P&gt;
&lt;P class="code-line" data-line="905"&gt;&lt;STRONG&gt;Diagnosis:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="906"&gt;curl -s http://&amp;lt;waf-hostname&amp;gt;/ | jq .received_host
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="910"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Add the correct Host header via Portal → Asset → Advanced Proxy Settings → Custom Headers:&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;Host&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;=&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;&amp;lt;backend-expected-hostname&amp;gt;&lt;/CODE&gt;&lt;/P&gt;
&lt;H3 id="http-502-bad-gateway" class="code-line" dir="auto" data-line="913"&gt;HTTP 502 Bad Gateway&lt;/H3&gt;
&lt;P class="code-line" data-line="915"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The WAF cannot connect to the upstream.&lt;/P&gt;
&lt;P class="code-line" data-line="917"&gt;&lt;STRONG&gt;Checklist:&lt;/STRONG&gt;&lt;/P&gt;
&lt;OL class="code-line" dir="auto" data-line="918"&gt;
&lt;LI class="code-line" dir="auto" data-line="918"&gt;Is the upstream running?&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;curl &lt;A href="http://51.4.115.60:8080/" target="_blank" rel="noopener"&gt;http://51.4.115.60:8080/&lt;/A&gt;&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="919"&gt;Is port 8080 open on the upstream firewall?&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;sudo ufw status&lt;/CODE&gt;&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="920"&gt;Is the upstream IP correct in the Portal?&lt;/LI&gt;
&lt;LI class="code-line" dir="auto" data-line="921"&gt;If using sub-location&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;proxy_pass&lt;/CODE&gt;, is the hardcoded IP correct and reachable from the WAF?&lt;/LI&gt;
&lt;/OL&gt;
&lt;H3 id="rewrite-fires-but-query-string-is-lost" class="code-line" dir="auto" data-line="923"&gt;Rewrite fires but query string is lost&lt;/H3&gt;
&lt;P class="code-line" data-line="925"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;flags instead of&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;. These issue client-side redirects, and the redirect URL construction may drop query strings depending on nginx version.&lt;/P&gt;
&lt;P class="code-line" data-line="927"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;for all upstream proxy rewrites.&lt;/P&gt;
&lt;H3 id="trailing-slash-issues-eg-chatbot-not-matching-but-chatbot-does" class="code-line" dir="auto" data-line="929"&gt;Trailing slash issues (e.g.&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot/&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;not matching but&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/chatbot&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;does)&lt;/H3&gt;
&lt;P class="code-line" data-line="931"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The regex does not account for an optional trailing slash.&lt;/P&gt;
&lt;P class="code-line" data-line="933"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;Use&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;/?&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in the regex:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-nginx" dir="auto" data-line="934"&gt;&lt;SPAN class="hljs-attribute"&gt;rewrite&lt;/SPAN&gt;&lt;SPAN class="hljs-regexp"&gt; ^/chatbot/?(.*)$&lt;/SPAN&gt; /&lt;SPAN class="hljs-variable"&gt;$1&lt;/SPAN&gt; &lt;SPAN class="hljs-literal"&gt;break&lt;/SPAN&gt;;
&lt;SPAN class="hljs-comment"&gt;#               ^^  optional trailing slash&lt;/SPAN&gt;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;H3 id="location-block-changes-not-visible-after-enforce" class="code-line" dir="auto" data-line="939"&gt;Location block changes not visible after enforce&lt;/H3&gt;
&lt;P class="code-line" data-line="941"&gt;&lt;STRONG&gt;Cause:&lt;/STRONG&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;The Portal may have assigned a new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;waf_N&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;index to your asset, and the server block now includes a different file.&lt;/P&gt;
&lt;P class="code-line" data-line="943"&gt;&lt;STRONG&gt;Fix:&lt;/STRONG&gt;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class="code-line language-bash" dir="auto" data-line="944"&gt;sudo grep &lt;SPAN class="hljs-string"&gt;"include"&lt;/SPAN&gt; /etc/cp/conf/rpmanager/servers/80_jwt.cpwaf.net.conf
&lt;SPAN class="hljs-comment"&gt;# Then read the file it points to&lt;/SPAN&gt;
sudo &lt;SPAN class="hljs-built_in"&gt;cat&lt;/SPAN&gt; /etc/cp/conf/rpmanager/include/waf_&amp;lt;N&amp;gt;_additional_location_config.conf
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P class="code-line" data-line="950"&gt;Always verify the actual included file rather than assuming the index is stable.&lt;/P&gt;
&lt;H3 id="rewrite--break-vs-rewrite--last--choosing-the-wrong-flag" class="code-line" dir="auto" data-line="952"&gt;&lt;CODE&gt;rewrite ... break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;vs&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;rewrite ... last&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— choosing the wrong flag&lt;/H3&gt;
&lt;TABLE class="code-line" dir="auto" data-line="954"&gt;
&lt;THEAD class="code-line" dir="auto" data-line="954"&gt;
&lt;TR class="code-line" dir="auto" data-line="954"&gt;
&lt;TH&gt;Scenario&lt;/TH&gt;
&lt;TH&gt;Correct flag&lt;/TH&gt;
&lt;/TR&gt;
&lt;/THEAD&gt;
&lt;TBODY class="code-line" dir="auto" data-line="956"&gt;
&lt;TR class="code-line" dir="auto" data-line="956"&gt;
&lt;TD&gt;Rewriting the path for upstream proxy&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;break&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— stops rewriting, proxies with new&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;$uri&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="957"&gt;
&lt;TD&gt;Rewriting to match a different&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;location&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;block&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;last&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;— re-evaluates location matching&lt;/TD&gt;
&lt;/TR&gt;
&lt;TR class="code-line" dir="auto" data-line="958"&gt;
&lt;TD&gt;Issuing a browser redirect&lt;/TD&gt;
&lt;TD&gt;&lt;CODE&gt;redirect&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;or&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;permanent&lt;/CODE&gt;&lt;/TD&gt;
&lt;/TR&gt;
&lt;/TBODY&gt;
&lt;/TABLE&gt;
&lt;P class="code-line" data-line="960"&gt;Using&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;CODE&gt;last&lt;/CODE&gt;&lt;SPAN&gt;&amp;nbsp;&lt;/SPAN&gt;in a proxy rewrite can cause infinite loops if the rewritten URI re-matches the same location, resulting in a 500.&lt;/P&gt;</description>
      <pubDate>Sun, 19 Apr 2026 11:18:09 GMT</pubDate>
      <guid>https://community.checkpoint.com/t5/WAF/URI-Rewrite-Complete-Implementation-Reference/m-p/275721#M398</guid>
      <dc:creator>Shay_Levin</dc:creator>
      <dc:date>2026-04-19T11:18:09Z</dc:date>
    </item>
  </channel>
</rss>

