Kubernetes reverse proxy

In this example, the Next-Gen WAF agent runs in a sidecar container and proxies all incoming requests for inspection before sending them upstream to the application container.

Integrating the Next-Gen WAF agent

Refer to Agent container image integration

Next-Gen WAF agent as a reverse proxy in front of a web application without the Next-Gen WAF module

If your web application does not support a Next-Gen WAF module (or you prefer not to install a module), then you can configure the sigsci-agent container to run as a reverse proxy in front of the web application in the same pod.

To configure the Next-Gen WAF agent to run in reverse proxy mode in a sidecar container, you must:

  • Add the sigsci-agent container to the pod, configured in reverse proxy mode to:

    • listen for incoming requests (on a new port or by reconfiguring your application or Kubernetes service accordingly)
    • proxy requests to your web application container
  • Add an emptyDir{} volume as a place for the sigsci-agent to write temporary data.

The following configuration exposes an example application (helloworld) on port 8000, adding the sigsci-agent as a reverse proxy listener on a new port 8001 with an upstream of the example web application port 8000.

Add the Next-Gen WAF agent as a reverse proxy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
...
containers:
# Example helloworld app running on port 8000 without sigsci configured
- name: helloworld
image: signalsciences/example-helloworld:latest
imagePullPolicy: IfNotPresent
args:
- localhost:8000
ports:
- containerPort: 8000
# Next-Gen WAF agent running in reverse proxy mode (SIGSCI_REVPROXY_LISTENER configured)
- name: sigsci-agent
image: signalsciences/sigsci-agent:latest
imagePullPolicy: Always
env:
- name: SIGSCI_ACCESSKEYID
valueFrom:
secretKeyRef:
name: sigsci.my-site-name-here
key: accesskeyid
- name: SIGSCI_SECRETACCESSKEY
valueFrom:
secretKeyRef:
name: sigsci.my-site-name-here
key: secretaccesskey
# Configure the revproxy listener to listen on a new port 8001
# forwarding to the app on the original port 8000 as the upstream
- name: SIGSCI_REVPROXY_LISTENER
value: "http:{listener='http://0.0.0.0:8001',upstreams='http://0.0.0.0:8000',access-log='/dev/stdout'}"
ports:
- containerPort: 8001
securityContext:
# The sigsci-agent container should run with its root filesystem read only
readOnlyRootFilesystem: true
volumeMounts:
# Default volume mount location for sigsci-agent writeable data
# NOTE: Also change `SIGSCI_SHARED_CACHE_DIR` (default `/sigsci/tmp/cache`)
# if mountPath is changed, but best not to change.
- name: sigsci-tmp
mountPath: /sigsci/tmp

NOTE: The above modification assumes that sigsci secrets were added to the system.

Adding the Next-Gen WAF agent temp volume definition to the deployment

You must define the agent temp volume for use by the other containers in the pod. This example uses the builtin emptyDir: {} volume type.

...
volumes:
# Define a volume where sigsci-agent will write temp data and share the socket file,
# which is required with the root filesystem is mounted read only
- name: sigsci-tmp
emptyDir: {}

Changing the service definition and adding the Next-Gen WAF agent as a reverse proxy

In the example above, the sigsci-agent reverse proxy listens on a new port, leaving the original application listener in place. You may wish for requests to be routed to the sigsci-agent at the original application port to make the agent addition as seamless as possible. One way to do this is to modify the Kubernetes service definition to route traffic to the sigsci-agent reverse proxy listener port instead of directly to the web application.

Change the service definition to point to the Next-Gen WAF agent port

Change the service targetPort from pointing directly to the application, to instead point to the sigsci-agent reverse proxy listener port. The sigsci-agent will then proxy to the application port:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
ports:
- name: http
port: 8000
# Target is now sigsci-agent on port 8001
targetPort: 8001
selector:
app: helloworld
type: LoadBalancer