Traffic Policy
Traffic Policy is currently in preview. Breaking changes may occur at any time with no notice, including changes to the structure of policy documents, the behaviors of policies, and the pricing of this feature.
Overview
This module allows you to assign a policy to your endpoints containing a series of inbound and outbound rules that can be used to influence and control traffic to and from your upstream service.
Policy rules are composed of expressions that filter the traffic on which they are applicable and actions that should take effect.
Example Usage
- Agent CLI
- Agent Config
- SSH
- Go
- Javascript
- Python
- Rust
- Kubernetes Controller
ngrok tls 80 --policy-file /path/to/policy.yml
inbound:
- name: "LimitToKnownIPs"
expressions:
- "conn.client_ip != '8.8.8.8'"
- "conn.client_ip != '9.9.9.9'"
actions:
- type: deny
tunnels:
example:
proto: tls
addr: 443
policy:
inbound:
- name: EnforceTLS1.3
expressions:
- "conn.TLS.Version != 'TLS 1.3'"
actions:
- type: deny
- name: "LogRequestsFromKnownIP"
expressions:
- "conn.ClientIP == '110.0.0.1'"
actions:
- type: log
config:
metadata:
event: "known-ip"
data: "110.0.0.1"
Traffic Policy is not configurable via SSH
import (
"context"
"net"
"golang.ngrok.com/ngrok"
"golang.ngrok.com/ngrok/config"
)
func ngrokListener(ctx context.Context) (net.Listener, error) {
return ngrok.Listen(ctx,
config.TLSEndpoint(
config.WithPolicy(
policy.Policy{
Inbound: []policy.Rule{
{
Name: "LimitToKnownIPs",
Expressions: []string{
"conn.ClientIP != '8.8.8.8'",
"conn.ClientIP != '9.9.9.9'",
},
Actions: []policy.Action{
{
Type: "deny",
},
},
},
},
},
),
),
ngrok.WithAuthtokenFromEnv(),
)
}
Go Package Docs:
const ngrok = require("@ngrok/ngrok");
const fs = require("fs");
(async function () {
const listener = await ngrok.forward({
addr: 8080,
proto: "tls",
authtoken_from_env: true,
policy: fs.readFileSync("/path/to/policy.json", "utf8"),
});
console.log(`Ingress established at: ${listener.url()}`);
})();
{
"inbound":
[
{
"name": "DenyTrafficOutsideUS",
"expressions": ["conn.Geo.CountryCode != 'US'"],
"actions": [{ "type": "deny" }],
},
{
"name": "LogRequestsFromKnownIP",
"expressions": ["conn.ClientIP == '110.0.0.1"],
"actions":
[
{
"type": "log",
"config":
{ "metadata": { "event": "known-ip", "data": "110.0.0.1" } },
},
],
},
],
}
Javascript SDK Docs:
with open('/path/to/policy.json') as f:
policy = json.load(f)
listener = await session.http_endpoint().policy(policy).listen()
{
"inbound":
[
{
"name": "DenyTrafficOutsideUS",
"expressions": ["conn.Geo.CountryCode != 'US'"],
"actions": [{ "type": "deny" }],
},
{
"name": "LogRequestsFromKnownIP",
"expressions": ["conn.ClientIP == '110.0.0.1"],
"actions":
[
{
"type": "log",
"config":
{ "metadata": { "event": "known-ip", "data": "110.0.0.1" } },
},
],
},
],
}
Python SDK Docs:
Traffic Policy is coming soon via rust-sdk
---
apiVersion: ingress.k8s.ngrok.com/v1alpha1
kind: Domain
metadata:
name: tlsedgetest-ngrok-app
spec:
domain: tlsedgetest.ngrok.app
---
apiVersion: ingress.k8s.ngrok.com/v1alpha1
kind: TLSEdge
metadata:
name: test-edge
spec:
hostports:
- tlsedgetest.ngrok.app:443
backend:
labels:
app: tlsedgetest
policy:
inbound:
- name: "LimitToKnownIPs"
expressions:
- "conn.ClientIP != '8.8.8.8'"
- "conn.ClientIP != '9.9.9.9'"
actions:
- type: deny
---
apiVersion: ingress.k8s.ngrok.com/v1alpha1
kind: Tunnel
metadata:
name: test-tunnel
spec:
backend:
protocol: TLS
forwardsTo: kubernetes.default.svc:443
labels:
app: tlsedgetest
Behavior
Policy rules are evaluated sequentially in the order they are configured with inbound rules taking effect before the upstream server is reached and outbound rules taking effect after the upstream server responds. Whether or not the configured actions are performed is determined at runtime by the expressions.
Expression Evaluation
Policy expressions are written using the Common Expression Language (CEL). Policy expressions must evaluate to true
in order for policy actions to take effect. There is no behavioral difference between adding multiple expressions to a single policy rule and having one
single expression with multiple statements logically conjoined together (i.e. ["1 == 1 && 2 == 2"]
is the same
s ["1 == 1", "2 == 2"]
).
If no expressions are specified on a policy rule, its actions will always take effect.
Action Execution
If a policy's expressions are evaluated as a match against a connection, the policy's actions will be executed. If multiple actions are defined on a policy, the actions will execute sequentially.
See actions for all available actions.
Reference
Configuration
Parameter | Description |
---|---|
inbound | A list of policy rules that will be applied to inbound traffic in the order specified. |
outbound | A list of policy rules that will be applied to outbound traffic in the order specified. |
name | Policy rules can optionally be given a name for convenience. |
expressions | A list of CEL expressions that filter which traffic a policy rule will apply to. |
actions | A list of actions that will execute sequentially if the associated policy rule's expressions all match on the traffic. |
type | The type of action. |
config | The configuration details of how an action should execute. Each action has its own configuration structure. |
Edges
Traffic Policy is a TLS Edge module.
The Traffic Policy module can be configured vai the ngrok dashboard or API.