Skip to main content

Stream route

Stream routes forward raw TCP and UDP connections to an upstream.

In the console Stream routesEngine resource stream_route

What 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 1883 to 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/8 under 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.

The Matching section of the console's New stream route form, filled with this example.
stream_route · as the console saves it
{
"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.

stream_route · as the console saves it
{
"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.

stream_route · as the console saves it
{
"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 example brokers.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: 65536 is 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 Type chash.
  • The engine assigns the id when 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​

Namenamestring
1 to 256 characters
Descriptiondescstring
up to 256 characters
Labelslabelsobject

Key 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 addressserver_addrstring

The address the connection arrives at: an IPv4 or IPv6 address or CIDR.

Server portserver_portinteger

The 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.

1 to 65535
Client addressremote_addrstring

IPv4 or IPv6 address or CIDR the connection must come from, for example 10.0.0.0/8.

Choose one:

  • One server nameThe connection must present this server name.
  • Several server namesThe connection must present one of these server names.
  • Any server nameThe server name a connection presents is not looked at.

One server name​

SNIsnistring

The server name a TLS client asks for. A leading * matches subdomains.

a host name, with an optional leading wildcard, or * alone
pattern^\*$|^\*?[0-9a-zA-Z-._\[\]:]+$

Several server names​

SNIssnisarray of strings

Several server names a TLS client may ask for, any of which matches. A leading * matches subdomains.

at least 1 item

Target​

Where matching connections are sent.

Choose one:

  • UpstreamSend matching connections to a shared upstream.
  • ServiceInherit the service's upstream and plugins.
  • Nodes on this stream routeDefine the backend here; nothing is shared.
  • NoneNo backend is chosen here, so the plugins must include traffic-split, the one stream plugin that picks an upstream; without it the save is refused.

Upstream​

Upstreamupstream_idstring or integerRequired
string 1 to 64 characters or integer at least 1 · letters, digits, dots, hyphens and underscores
pattern^[a-zA-Z0-9-_.]+$

Service​

Serviceservice_idstring or integerRequired

Through 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.

string 1 to 64 characters or integer at least 1 · letters, digits, dots, hyphens and underscores
pattern^[a-zA-Z0-9-_.]+$

Nodes on this stream route​

UpstreamupstreamobjectRequired

Has the settings of an upstream, kept here and shared with nothing; each field is described on that page.

TLS passthroughtls_passthroughbooleandefault false

Forwards 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.

PluginspluginsobjectRequired when Target is None

The stream plugins of this route, keyed by plugin name. The engine runs them by their priority, not by the order they are written in.

G8 dev · Apache APISIX® 3.19.0
Apache, Apache APISIX and APISIX are trademarks of The Apache Software Foundation.