Configuring agent reverse proxy deployments

IMPORTANT

This guide only applies to Next-Gen WAF customers with access to the Next-Gen WAF control panel. If you have access to the Next-Gen WAF product in the Fastly control panel, you can only deploy the Next-Gen WAF with the Edge WAF deployment method.

The Next-Gen WAF agent can be configured to run as a reverse proxy allowing it to interact directly with requests and responses without the need for a module. Running the agent in reverse proxy mode is ideal when a module for your web service does not yet exist or you do not want to modify your web service configuration - for example, while testing the product. In this mode, the agent sits inline as a service in front of your web service.

In reverse proxy mode, the agent will start one or more listeners and proxy all traffic received on them to the configured upstream server. Both HTTP, HTTPS (TLS) listeners can be enabled. Note that configuring the agent in reverse proxy mode will disable the RPC listener and the agent will not function with any modules.

Reverse proxy listener configuration

The reverse proxy mode supports multiple listeners. Each listener is defined in a revproxy-listener block that has its own set of directives. Each block must:

  • have a unique name in the format [revproxy-listener.NAME].
  • be located at the end of the configuration after all other global options.

For example, to configure a simple HTTP (no encryption) listener, update the agent.conf file (default: /etc/sigsci/agent.conf) to include the following configuration block as shown below that creates an HTTP reverse proxy listener named example1:

1
2
3
[revproxy-listener.example1]
listener = "http://203.0.113.13:80"
upstreams = "http://192.168.1.2:80"

The listener option is the address the agent will listen on in the form of a URL. In the example above, 203.0.113.13 is an example IP address and you will need to set an appropriate address for your network. If you are unsure, restricting to the loopback address (127.0.0.1) will allow local testing without allowing external access. The 0.0.0.0 meta-address can be used to listen across all addresses on the host.

The upstreams option defines the upstream hosts that the agent will proxy requests to. The upstream hosts are a comma-separated list of URLs. The scheme of the URLs specify the protocol that will be used for listening and proxying to the upstreams.

NOTE

When you add more than one host in a listener's upstreams option, requests are dynamically distributed between upstream hosts via round-robin load balancing. If your load balancer is configured for sticky sessions (session affinity), you will need to create a separate listener for every upstream host.

To configure a TLS encrypted listener, use the https scheme for the listener option and configure the tls-key and tls-cert options to point to files containing the key and cert. The upstreams scheme determines the protocol used to proxy to the upstream hosts.

Encrypt traffic to Upstream

1
2
3
4
5
[revproxy-listener.example2]
listener = "https://203.0.113.13:8080"
upstreams = "https://192.168.1.2:8443,https://192.168.1.3:8443"
tls-cert = "/etc/sigsci/server-cert.pem"
tls-key = "/etc/sigsci/server-key.pem"

Terminating TLS at the agent

This option is similar to the above with the only difference being the scheme used in the upstreams.

1
2
3
4
5
[revproxy-listener.example3]
listener = "https://203.0.113.13:8443"
upstreams = "http://192.168.1.2:8001,http://192.168.1.2:8002"
tls-cert = "/etc/sigsci/server-cert.pem"
tls-key = "/etc/sigsci/server-key.pem"
NOTE

In both options, the cert and key files can be the same file provided you concatenate both key and cert into one file.

After you have completed the desired configuration, reload the sigsci-agent configuration for the changes to take effect. On most systems this can be done by sending a SIGHUP signal to the agent process ID (e.g., kill -HUP 12345 where 12345 is the PID) or just restarting the agent.

The [revproxy-listener.NAME] configuration and its available options are documented on the agent configuration page.

Alternative configuration without a configuration file

If you are not using a configuration file, then you cannot use the new block format above and you must instead use an alternative format. This format can be used with a single --revproxy-listener command line option or via a single SIGSCI_REVPROXY_LISTENER environment variable.

Generic format for the alternative revproxy-listener value

listener1:{opt=val,...}; listener2:{...}; ...

Some example from above are repeated here in the alternative format.

Simple HTTP listener

SIGSCI_REVPROXY_LISTENER="example1:{listener=http://203.0.113.13:80,upstreams=http://192.168.1.2:80}"

Simple HTTPS listener

SIGSCI_REVPROXY_LISTENER="example2:{listener=https://203.0.113.13:443,upstreams=https://192.168.1.2:8443,tls-cert=/etc/sigsci/server-cert.pem,tls-key=/etc/sigsci/server-key.pem}"

Multiple listeners can be specified in a single option by separating each listener definition with a semicolon (;).

Multiple listeners

SIGSCI_REVPROXY_LISTENER="example1:{...}; example2:{...}"

Side effects and limitations

HTTP header names are normalized

The agent in reverse proxy mode will normalize all header names by capitalizing the first letter in each word. For example, example-header becomes Example-Header.

HTTP header order may not be maintained

Due to technical limitation, the agent in reverse proxy mode does not allow for tracking and maintaining the order of headers. The order of headers may change when sent to the upstream server. For example:

GET /test HTTP/1.1
Host: example.com
X-Example-Header: example
X-Test-Header: test
X-Other-Header: other
Accept: */*

This request may arrive at the upstream server as:

GET /test HTTP/1.1
Host: example.com
Accept: */*
X-Test-Header: test
X-Other-Header: other
X-Example-Header: example

Added headers

By default, the following headers are added to the upstream request:

  • X-Forwarded-For
  • X-Forwarded-Host
  • X-Forwarded-Proto
  • X-Forwarded-Server

In agent v3.7+, each listener can be configured with minimal-header-rewriting = true and these additional headers will not be added/modified. These headers will still be passed through if they exist in the request. Additionally, configuring a listener to not trust the proxy headers with trust-proxy-headers = false will strip these headers before sending to the upstream.

Additionally, the following headers will be added regardless of the above configurations:

  • X-Sigsci-Agentresponse
  • X-Sigsci-Tags (only if there were signals added)

HTTP/1.0 to upstream is upgraded to HTTP/1.1

Any HTTP/1.0 requests processed by the agent in reverse proxy mode will be upgraded to HTTP/1.1 when sent to the upstream. This means:

  • HTTP keepalives are enabled by default
  • HTTP/1.1 version is used in the request line
  • The HTTP Host header is added
  • The Accept-Encoding: gzip header is added

HTTP/0.9 is not supported

Go (which the agent is written in) does not support HTTP versions prior to HTTP/1.0. Any requests in the HTTP/0.9 format will result in a 400 Bad Request error response. This may affect some simple monitoring from older monitors and load balancers.

For example, GET / is a request in HTTP/0.9 format and would result in a 400 error. By contrast, GET / HTTP/1.0 is in the supported HTTP/1.0 format, which specifies the HTTP version.

Failing open

When the agent is running in reverse proxy mode, requests that have failed open are not sent to the cloud backend and therefore won't be visible on the requests page of the control panel.

F5 load balancer health checks

F5 load balancer health checks use HTTP/0.9 by default. However, the Next-Gen WAF reverse proxy does not support HTTP/0.9 because Go, which the Next-Gen WAF agent is written in, does not support it. This results in the F5 health checks failing with 400 Bad Request response codes.

To resolve this, force the F5 health checks to use HTTP/1.0 or HTTP/1.1 instead. Specify the HTTP version in the send string, which will force the monitor to send an HTTP/1.0 or 1.1 request instead.

Below is an example of an HTTP/0.9 GET request:

GET /index.html

By specifying HTTP/1.0, it will instead become an HTTP/1.0 GET request:

GET /index.html HTTP/1.0

For additional information about altering the F5 health check requests, see F5's official documentation.

Next steps

Verify the agent and module installation and explore module options.

Was this guide helpful?

Do not use this form to send sensitive information. If you need assistance, contact support. This form is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.