Istio EnvoyFilter Lua HttpCall: Why HTTPS Doesn't Always Play Nice
Istio's powerful EnvoyFilter allows fine-grained control over Envoy's behavior using Lua scripts. One common use case is using the HttpCall
function to interact with external services. However, many users encounter issues when trying to use HttpCall
with HTTPS connections. This article will delve into the reasons behind these challenges and provide solutions for overcoming them.
The Scenario: A Frustrating HTTPS Connection
Let's imagine you're trying to implement a simple EnvoyFilter that makes a secure HTTPS request to an external API:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: https-call-example
spec:
workloadSelector:
labels:
app: my-service
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INJECTION
listener:
portNumber: 8080
patch:
operation: INSERT_BEFORE
value:
code:
"@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v3.HttpFilter
name: lua-filter
config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
local response = request_handle:HttpCall({
method: "GET",
path: "/api/v1/data",
hostname: "api.example.com",
port: 443,
use_tls: true
})
-- Process response here
end
This EnvoyFilter aims to perform an HTTP GET
request to api.example.com
on port 443, using HTTPS. However, you'll likely find that this code snippet fails to connect successfully, often leading to errors related to certificate validation.
Understanding the Challenge: The Missing Pieces
The issue stems from the fact that Envoy, by default, doesn't automatically trust any certificates for HTTPS connections made within a Lua HttpCall
. This is a security measure to prevent potential vulnerabilities.
Here's a breakdown of the problem:
- Default behavior: Envoy, in its standard configuration, doesn't know about your external API's certificate. It relies on the root certificates present in the system's trust store.
- Certificate validation: When the
HttpCall
is made, Envoy attempts to verify the certificate presented by the API. Without proper trust configuration, this validation fails, leading to the connection error.
Solutions: Bridging the Gap
To resolve this, we need to provide Envoy with the necessary information to trust the API's certificate. There are two main approaches:
-
Trust Store Configuration:
- Using Secret Volumes: You can mount a secret volume containing the API's certificate into the Envoy container. This allows Envoy to use the specified certificate during verification.
- Manual Configuration: Alternatively, you can configure Envoy to use a specific trust store file through the
trust_chain
parameter in thehttp_connection_manager
configuration.
-
Disabling SSL Verification:
- Caution: This approach should only be used in controlled environments with a high level of trust in the external API, as it circumvents certificate validation.
Here's an example of how you can update your EnvoyFilter to include a trusted certificate:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: https-call-example
spec:
workloadSelector:
labels:
app: my-service
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INJECTION
listener:
portNumber: 8080
patch:
operation: INSERT_BEFORE
value:
code:
"@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v3.HttpFilter
name: lua-filter
config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
local response = request_handle:HttpCall({
method: "GET",
path: "/api/v1/data",
hostname: "api.example.com",
port: 443,
use_tls: true,
tls_context: {
alpn: "h2",
trust_chain: "path/to/certificate.pem"
}
})
-- Process response here
end
In this example, we've added the tls_context
parameter to the HttpCall
configuration. This allows you to specify the path to the certificate file (trust_chain
) that should be used for verification.
Conclusion
By understanding the reasons behind certificate validation issues and implementing the appropriate solutions, you can successfully use the Istio EnvoyFilter Lua HttpCall
function to interact with secure HTTPS services. Remember to prioritize security and only disable verification when absolutely necessary.
For further reference, consult the official Istio documentation on EnvoyFilter and the Lua filter configuration: