From 98ef9a3e6fe2fa08625c892c11d1a390e82d6b5b Mon Sep 17 00:00:00 2001 From: Sjouke de Vries Date: Sun, 3 May 2026 10:36:16 +0200 Subject: [PATCH 1/4] docs(tasks): add documentation for Dynamic Modules configuration example Co-authored-by: Copilot Signed-off-by: Sjouke de Vries --- .../en/latest/tasks/extensibility/_index.md | 1 + .../tasks/extensibility/dynamic-modules.md | 256 ++++++++++++++++++ 2 files changed, 257 insertions(+) create mode 100644 site/content/en/latest/tasks/extensibility/dynamic-modules.md diff --git a/site/content/en/latest/tasks/extensibility/_index.md b/site/content/en/latest/tasks/extensibility/_index.md index 3079bb6844..9254243470 100644 --- a/site/content/en/latest/tasks/extensibility/_index.md +++ b/site/content/en/latest/tasks/extensibility/_index.md @@ -16,3 +16,4 @@ Envoy Gateway provides several ways to extend its functionality beyond the built - [WASM Extensions](wasm) - Run WebAssembly modules for high-performance custom logic - [External Processing](ext-proc) - Call external gRPC services during request processing - [Lua Extensions](lua) - Write lightweight scripting extensions +- [Dynamic Modules](dynamic-modules) - Load custom C++ modules at runtime for advanced extensibility diff --git a/site/content/en/latest/tasks/extensibility/dynamic-modules.md b/site/content/en/latest/tasks/extensibility/dynamic-modules.md new file mode 100644 index 0000000000..f2eda3528a --- /dev/null +++ b/site/content/en/latest/tasks/extensibility/dynamic-modules.md @@ -0,0 +1,256 @@ +--- +title: "Dynamic Modules" +--- + +This task provides instructions for configuring [Dynamic Modules](https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/advanced/dynamic_modules). + +Dynamic Modules are a critical extension mechanism that allows functionality to be loaded directly into the Envoy proxy process at runtime, typically as shared object files (`.so`). This approach enables customized filtering and request processing without requiring a full recompile of the core Envoy binary, streamlining deployments and upgrades. + +Envoy Gateway is able to load dynamic modules from the local filesystem using [EnvoyExtensionPolicy][]. This example demonstrates it's working by loading the [Coraza](https://www.coraza.io/) Web Application Firewall (WAF) using [Built On Envoy](https://builtonenvoy.io/) development toolkit. The module's full documentation can be found on the [Coraza WAF extension page](https://builtonenvoy.io/extensions/coraza-waf/). + +## Prerequisites + +{{< boilerplate prerequisites >}} + +## Coraza WAF Extension + +### Installation + +Add the dynamic module to the Envoy proxy container's filesystem and load it into Envoy. + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +**Note: verify version compatibility of the extension because of dynamic module forward compatibility.** + +[Image Volumes](https://kubernetes.io/docs/tasks/configure-pod-container/image-volumes/) are relatively new and only supported from Kubernetes `1.35` onwards. +Alternative ways of loading the dynamic module are: +- Building a custom docker image +- Copying from `InitContainer` to a shared volume + + +Verify the EnvoyProxy status: + +```shell +kubectl get envoyproxy/myproxy -o yaml +``` + +Attach to Gateway via a GatewayClass with `spec.parametersRef` + +```shell +kubectl patch gatewayclass eg --type=merge -p '{ + "spec": { + "parametersRef": { + "group": "gateway.envoyproxy.io", + "kind": "EnvoyProxy", + "name": "my-proxy", + "namespace": "envoy-gateway-system" + } + } +}' +``` + +The entire configuration can also be specified directly on the Gateway instead by using `spec.envoyProxy`. + +### Configuration + +Create a new EnvoyExtensionPolicy resource to configure the dynamic module for an entire Gateway or per HTTPRoute. + +This EnvoyExtensionPolicy targets the Gateway "eg" created with the quickstart. It loads the Coraza WAF extension with its configuration. + + +{{< tabpane text=true >}} +{{% tab header="Apply from stdin" %}} + +```shell +cat <}} + +Verify the Envoy Extension Policy configuration: + +```shell +kubectl get envoyextensionpolicy/waf-extension -o yaml +``` + +### Testing + +Ensure the `GATEWAY_HOST` environment variable from the [Quickstart](../../quickstart) is set. If not, follow the +Quickstart instructions to set the variable. + +```shell +echo $GATEWAY_HOST +``` + +Send a normal request to the backend service: + +```shell +curl -v -H "Host: www.example.com" "http://${GATEWAY_HOST}/" +``` + +You should get a `200 OK` response from the backend. + +Now send a request with a SQL injection payload to trigger the WAF: + +```shell +curl -v -H "Host: www.example.com" "http://${GATEWAY_HOST}/?id=1'+OR+'1'%3D'1" +``` + +The Coraza WAF should block the request and return a `403 Forbidden` response: + +``` +> GET /?id=1'+OR+'1'='1 HTTP/1.1 +> Host: www.example.com +[...] +< HTTP/1.1 403 Forbidden +< date: Sat, 03 May 2026 12:00:00 GMT +< content-length: 0 +< +``` + +## Clean-Up + +Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. + +Delete the EnvoyProxy and EnvoyExtensionPolicy: + +```shell +kubectl delete envoyproxy/my-proxy +kubectl delete envoyextensionpolicy/waf-extension +``` + +## Next Steps + +Checkout the [Developer Guide](/community/develop) to get involved in the project. + +[EnvoyProxy]: ../../../api/extension_types#envoyproxy +[EnvoyExtensionPolicy]: ../../../api/extension_types#envoyextensionpolicy +[DynamicModules]: ../../../api/extension_types#dynamicmoduleentry From a4883651a9a5f270d5c72a01ad337ea49bee3662 Mon Sep 17 00:00:00 2001 From: Sjouke de Vries Date: Sun, 3 May 2026 10:40:17 +0200 Subject: [PATCH 2/4] docs(tasks): dynamic-modules fix naming inconsistency for EnvoyProxy resource Signed-off-by: Sjouke de Vries --- site/content/en/latest/tasks/extensibility/dynamic-modules.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/en/latest/tasks/extensibility/dynamic-modules.md b/site/content/en/latest/tasks/extensibility/dynamic-modules.md index f2eda3528a..306bf8d6b6 100644 --- a/site/content/en/latest/tasks/extensibility/dynamic-modules.md +++ b/site/content/en/latest/tasks/extensibility/dynamic-modules.md @@ -66,7 +66,7 @@ Save and apply the following resource to your cluster: apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: - name: myproxy + name: my-proxy spec: provider: type: Kubernetes @@ -110,7 +110,7 @@ Alternative ways of loading the dynamic module are: Verify the EnvoyProxy status: ```shell -kubectl get envoyproxy/myproxy -o yaml +kubectl get envoyproxy/my-proxy -o yaml ``` Attach to Gateway via a GatewayClass with `spec.parametersRef` From d7916fd7a21fb4503eafe022e8d2569b1f159d52 Mon Sep 17 00:00:00 2001 From: Sjouke de Vries Date: Sun, 3 May 2026 10:46:32 +0200 Subject: [PATCH 3/4] docs(tasks): fix indentation for dynamic module path in EnvoyProxy spec Signed-off-by: Sjouke de Vries --- site/content/en/latest/tasks/extensibility/dynamic-modules.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/site/content/en/latest/tasks/extensibility/dynamic-modules.md b/site/content/en/latest/tasks/extensibility/dynamic-modules.md index 306bf8d6b6..0a226609b2 100644 --- a/site/content/en/latest/tasks/extensibility/dynamic-modules.md +++ b/site/content/en/latest/tasks/extensibility/dynamic-modules.md @@ -51,7 +51,7 @@ spec: source: type: Local local: - path: /etc/envoy/dynamic-modules/libcomposer.so + path: /etc/envoy/dynamic-modules/libcomposer.so doNotClose: true loadGlobally: false EOF @@ -91,7 +91,7 @@ spec: source: type: Local local: - path: /etc/envoy/dynamic-modules/libcomposer.so + path: /etc/envoy/dynamic-modules/libcomposer.so doNotClose: true loadGlobally: false ``` From 56929437384d5ce8b3530eb53da29f621c3c5d83 Mon Sep 17 00:00:00 2001 From: Sjouke de Vries Date: Sun, 3 May 2026 16:58:49 +0200 Subject: [PATCH 4/4] docs(tasks): fix linting for dynamic modules installation and configuration instructions Co-authored-by: Copilot Signed-off-by: Sjouke de Vries --- .../en/latest/tasks/extensibility/dynamic-modules.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/site/content/en/latest/tasks/extensibility/dynamic-modules.md b/site/content/en/latest/tasks/extensibility/dynamic-modules.md index 0a226609b2..dd02b428a1 100644 --- a/site/content/en/latest/tasks/extensibility/dynamic-modules.md +++ b/site/content/en/latest/tasks/extensibility/dynamic-modules.md @@ -16,7 +16,7 @@ Envoy Gateway is able to load dynamic modules from the local filesystem using [E ### Installation -Add the dynamic module to the Envoy proxy container's filesystem and load it into Envoy. +Add the dynamic module to the Envoy proxy container's filesystem and configure the [DynamicModules][] spec to load it into Envoy. {{< tabpane text=true >}} {{% tab header="Apply from stdin" %}} @@ -107,7 +107,7 @@ Alternative ways of loading the dynamic module are: - Copying from `InitContainer` to a shared volume -Verify the EnvoyProxy status: +Verify the [EnvoyProxy][] status: ```shell kubectl get envoyproxy/my-proxy -o yaml @@ -128,11 +128,11 @@ kubectl patch gatewayclass eg --type=merge -p '{ }' ``` -The entire configuration can also be specified directly on the Gateway instead by using `spec.envoyProxy`. +The entire configuration can also be specified directly on the Gateway instead by using `spec.envoyProxy`. ### Configuration -Create a new EnvoyExtensionPolicy resource to configure the dynamic module for an entire Gateway or per HTTPRoute. +Create a new EnvoyExtensionPolicy resource to configure the dynamic module for an entire Gateway or per HTTPRoute. This EnvoyExtensionPolicy targets the Gateway "eg" created with the quickstart. It loads the Coraza WAF extension with its configuration. @@ -240,7 +240,7 @@ The Coraza WAF should block the request and return a `403 Forbidden` response: Follow the steps from the [Quickstart](../../quickstart) to uninstall Envoy Gateway and the example manifest. -Delete the EnvoyProxy and EnvoyExtensionPolicy: +Delete the [EnvoyProxy][] and [EnvoyExtensionPolicy][]: ```shell kubectl delete envoyproxy/my-proxy