Stream route
Stream routes forward raw TCP and UDP connections to an upstream.
stream_routeWhat a stream route is
A stream route forwards raw TCP and UDP connections to an upstream. It takes a connection by the port it arrives at, under Server port, and by the other rules of Matching that are set. Its target is a shared upstream, a service, or nodes listed on the stream route itself.
The gateway opens no port for a stream route: Server port has to be one its stream proxy already listens on. The bytes a client sends reach a node as they are, and the node's answer goes back to the client on the same connection.
When to use it
- Two read replicas of a PostgreSQL database that clients reach through one port of the gateway,
5432, spread over both. - MQTT clients that connect on
1883to a pool of brokers whose addresses come from DNS rather than a fixed list. - Devices that should keep reaching the same broker each time they connect, grouped by their own address with a consistent hash.
- A port that only clients of your own network may open, for example
10.0.0.0/8under Client address. - A TLS service whose encrypted stream goes on to the backend untouched, under TLS passthrough.
Not for an HTTP request matched by its path, host or method — see Route (Routes match incoming requests and send them to an upstream).
Guides
Pages that walk through a job with a stream route, step by step.
- Forward a TCP portCreate a stream route that forwards one port of the gateway to backend nodes, with no HTTP in between.
Set it up
Keep each client on the same broker by its address
Port 1883 must be one the gateway's stream proxy already listens on; the gateway opens no port for a stream route.
Under General set Name to mqtt-sticky. Under Matching set Server port to 1883. Under Target choose Nodes on this stream route and fill Upstream as in the JSON below.
{
"name": "mqtt-sticky",
"server_port": 1883,
"upstream": {
"type": "chash",
"hash_on": "vars",
"key": "remote_addr",
"nodes": {
"10.0.2.30:1883": 1,
"10.0.2.31:1883": 1
}
}
}
More scenarios
Forward one port to brokers found through DNS
Port 1883 must be one the gateway's stream proxy already listens on; the gateway opens no port for a stream route; DNS discovery must be enabled in its static configuration first.
Under General set Name to mqtt-brokers. Under Matching set Server port to 1883. Under Target choose Nodes on this stream route and fill Upstream as in the JSON below.
{
"name": "mqtt-brokers",
"server_port": 1883,
"upstream": {
"type": "roundrobin",
"discovery_type": "dns",
"service_name": "brokers.internal.example.com:1883"
}
}
Forward one port to two database replicas
Port 5432 must be one the gateway's stream proxy already listens on; the gateway opens no port for a stream route.
Under General set Name to postgres-replicas. Under Matching set Server port to 5432. Under Target choose Nodes on this stream route and fill Upstream as in the JSON below.
{
"name": "postgres-replicas",
"server_port": 5432,
"upstream": {
"type": "roundrobin",
"nodes": {
"10.0.2.10:5432": 1,
"10.0.2.11:5432": 1
}
}
}
Things to know
- Upstream — A connection reaches one of the nodes and the node's own answer comes back: an HTTP/1.0 request sent to the port of the two replicas is answered
HTTP/1.0 200 OK. - Upstream — With Discovery type at
dns, the name carries the port, for examplebrokers.internal.example.com:1883. DNS discovery has to be enabled in the gateway's static configuration first. - Plugins — Of the stream plugins only traffic-split picks a backend. A stream route with plugins and no target is refused when you save unless traffic-split is among them.
- Plugins — Only stream plugins can be added: an HTTP plugin like key-auth is refused when you save.
- Plugins — From a service, only its stream plugins run, and the stream route's own copy of a plugin wins over the service's. No global rule runs on a stream route.
- Server port — The port is a number up to 65535:
65536is refused when you save. - SNI — Read only by a TLS stream listener: a plain TCP connection never matches a stream route that names an SNI.
- SNIs — Read only by a TLS stream listener: a plain TCP connection never matches a stream route that names an SNI.
- Deleting a stream route makes the connections it matched fail at once.
- AdviceWhere clients should keep reaching the same node, hash on their address,
remote_addr, with the Typechash. - The engine assigns the
idwhen the object is created; it is not the name, and it is what other objects refer to.
Settings
The fields as the console shows them, section by section. A field under “When … is …” is there only while that value is set. A field that holds the settings of another kind links to that kind’s page.
General
namestringdescstringlabelsobjectKey and value pairs of your own, for grouping and filtering. They change nothing about traffic. An object whose keys are any name, each with a string as its value.
Matching
A connection is routed here when every rule below holds.
server_addrstringThe address the connection arrives at: an IPv4 or IPv6 address or CIDR.
server_portintegerThe port the connection arrives at. The engine opens no port for a stream route, so it must be one its stream proxy already listens on.
remote_addrstringIPv4 or IPv6 address or CIDR the connection must come from, for example 10.0.0.0/8.
Choose one:
One server name
snistringThe server name a TLS client asks for. A leading * matches subdomains.
pattern
^\*$|^\*?[0-9a-zA-Z-._\[\]:]+$Several server names
snisarray of stringsSeveral server names a TLS client may ask for, any of which matches. A leading * matches subdomains.
Target
Where matching connections are sent.
Choose one:
Upstream
upstream_idstring or integerRequiredpattern
^[a-zA-Z0-9-_.]+$Service
service_idstring or integerRequiredThrough a service, the stream route reaches only nodes named by IP address, in its own upstream and in the service's; a node named by host name closes every connection.
pattern
^[a-zA-Z0-9-_.]+$Nodes on this stream route
upstreamobjectRequiredHas the settings of an upstream, kept here and shared with nothing; each field is described on that page.
tls_passthroughbooleandefault falseForwards the encrypted stream to the target untouched; read only on a listener that accepts both terminated and passthrough TLS.
Plugins
Plugins on this stream route are managed in its Plugins tab.
pluginsobjectRequired when Target is NoneThe stream plugins of this route, keyed by plugin name. The engine runs them by their priority, not by the order they are written in.