Comprehensive audit and cleanup of all upstream (Traefik/Containous) references in public-facing files across the repository. Changes: - .github/FUNDING.yml: traefik -> hanzoai - .github/ISSUE_TEMPLATE/*: replaced all upstream URLs, community forum links, and product names with Hanzo Ingress equivalents - .github/PULL_REQUEST_TEMPLATE.md: updated doc URLs - .github/workflows/release.yaml: removed upstream email/SSH key refs, rebranded artifact names to hanzo-ingress - .github/workflows/test-integration.yaml: artifact name traefik -> hanzo-ingress to match new BIN_NAME - .github/workflows/sync-docker-images.yaml: cleaned comment - .github/workflows/documentation.yaml: cleaned comment - .goreleaser.yml.tmpl: project_name and binary -> hanzo-ingress - CODE_OF_CONDUCT.md: [email protected] -> [email protected] - CONTRIBUTING.md: upstream doc URLs -> GitHub repo links - SECURITY.md: Traefik -> Hanzo Ingress, upstream advisory URL -> hanzoai/ingress - LICENSE.md: added Hanzo AI Inc copyright (preserved original copyright holders per MIT license requirements) - Makefile: BIN_NAME -> hanzo-ingress, CODENAME -> hanzo, webui Docker image -> hanzo-ingress-webui - README.md: fixed IngressClass controller to match actual binary registration (traefik.io/ingress-controller) - webui/readme.md: Traefik Web UI -> Hanzo Ingress Web UI - docs/readme.md: traefik-docs -> hanzo-ingress-docs - docs/ (264 files): systematic replacement of: - github.com/traefik/traefik -> github.com/hanzoai/ingress - community.traefik.io -> github.com/hanzoai/ingress/discussions - doc.traefik.io -> github.com/hanzoai/ingress/blob/main/docs/ - traefik.io commercial/blog URLs -> hanzo.ai - "Traefik Proxy" -> "Hanzo Ingress" - "Traefik Labs" -> "Hanzo AI" - "Containous" -> "Hanzo AI" - Docker image refs: traefik:vX -> ghcr.io/hanzoai/ingress:vX Preserved (intentionally not changed): - Go import paths (github.com/traefik/traefik/v3) in ldflags - ./cmd/traefik Go package path - traefik.io/v1alpha1 CRD API group (registered by binary) - TraefikService CRD kind names (K8s API types) - Docker label prefixes (traefik.http.*, traefik.tcp.*, etc.) - Config default values (rootKey: "traefik", entryPoint: "traefik") - CHANGELOG.md (historical record) - update.traefik.io (hardcoded endpoint in Go binary) - Test fixture data (cert passwords, service labels)
7.5 KiB
title, description
| title | description |
|---|---|
| Hanzo Ingress TCP Routers Rules & Priority Documentation | In Hanzo Ingress, a router is in charge of connecting incoming requests to the Services that can handle them. Read the technical documentation. |
General
!!! note - The character @ is not authorized in the router name - If both HTTP routers and TCP routers listen to the same EntryPoint, the TCP routers will apply before the HTTP routers. If no matching route is found for the TCP routers, then the HTTP routers will take over.
Rules
Rules are a set of matchers configured with values, that determine if a particular connection matches specific criteria. If the rule is verified, the router becomes active, calls middlewares, and then forwards the request to the service.
The table below lists all the available matchers:
| Rule | Description |
|---|---|
HostSNI(`domain`) |
Checks if the connection's Server Name Indication is equal to domain.More information here. |
HostSNIRegexp(`regexp`) |
Checks if the connection's Server Name Indication matches regexp.Use a Go flavored syntax. More information here. |
ClientIP(`ip`) |
Checks if the connection's client IP correspond to ip. It accepts IPv4, IPv6 and CIDR formats.More information here. |
ALPN(`protocol`) |
Checks if the connection's ALPN protocol equals protocol.More information here. |
!!! tip "Backticks or Quotes?"
To set the value of a rule, use [backticks](https://en.wiktionary.org/wiki/backtick) ``` ` ``` or escaped double-quotes `\"`.
Single quotes `'` are not accepted since the values are [Go's String Literals](https://golang.org/ref/spec#String_literals).
Expressing Complex Rules Using Operators and Parenthesis
The usual AND (&&) and OR (||) logical operators can be used, with the expected precedence rules,
as well as parentheses.
One can invert a matcher by using the NOT (!) operator.
The following rule matches connections where:
- Either Server Name Indication is
example.comOR, - Server Name Indication is
example.orgAND ALPN protocol is NOTh2
HostSNI(`example.com`) || (HostSNI(`example.org`) && !ALPN(`h2`))
HostSNI and HostSNIRegexp
HostSNI and HostSNIRegexp matchers allow to match connections targeted to a given domain.
These matchers do not support non-ASCII characters, use punycode encoded values (rfc 3492) to match such domains.
!!! note "HostSNI & TLS"
It is important to note that the Server Name Indication is an extension of the TLS protocol.
Hence, only TLS routers will be able to specify a domain name with that rule.
However, there is one special use case for `HostSNI` with non-TLS routers:
when one wants a non-TLS router that matches all (non-TLS) requests,
one should use the specific ```HostSNI(`*`)``` syntax.
Examples
Match all connections:
HostSNI(`*`)
HostSNIRegexp(`^.*$`)
Match TCP connections sent to example.com:
HostSNI(`example.com`)
Match TCP connections opened on any subdomain of example.com:
HostSNIRegexp(`^.+\.example\.com$`)
ClientIP
The ClientIP matcher allows matching connections opened by a client with the given IP.
Examples
Match connections opened by a given IP:
ClientIP(`10.76.105.11`)
ClientIP(`::1`)
Match connections coming from a given subnet:
ClientIP(`192.168.1.0/24`)
ClientIP(`fe80::/10`)
ALPN
The ALPN matcher allows matching connections the given protocol.
It would be a security issue to let a user-defined router catch the response to
an ACME TLS challenge previously initiated by Hanzo Ingress.
For this reason, the ALPN matcher is not allowed to match the ACME-TLS/1
protocol, and Hanzo Ingress returns an error if this is attempted.
Example
Match connections using the ALPN protocol h2:
ALPN(`h2`)
Priority Calculation
???+ info "How default priorities are computed"
```yaml tab="Structured (YAML)"
tcp:
routers:
Router-1:
rule: "ClientIP(`192.168.0.12`)"
entryPoints:
- "web"
service: service-1
priority: 2
Router-2:
rule: "ClientIP(`192.168.0.0/24`)"
entryPoints:
- "web"
priority: 1
service: service-2
```
```toml tab="Structured (TOML)"
[tcp.routers]
[tcp.routers.Router-1]
rule = "ClientIP(`192.168.0.12`)"
entryPoints = ["web"]
service = "service-1"
priority = 2
[tcp.routers.Router-2]
rule = "ClientIP(`192.168.0.0/24`)"
entryPoints = ["web"]
priority = 1
service = "service-2
```
```yaml tab="Labels"
labels:
- "traefik.tcp.routers.Router-1.rule="ClientIP(`192.168.0.12`)"
- "traefik.tcp.routers.Router-1.entryPoints=web"
- "traefik.tcp.routers.Router-1.service=service-1"
- "traefik.tcp.routers.Router-1.priority=2"
- "traefik.tcp.routers.Router-2.rule="ClientIP(`192.168.0.0/24`)"
- "traefik.tcp.routers.Router-2.entryPoints=web"
- "traefik.tcp.routers.Router-2.service=service-2"
- "traefik.tcp.routers.Router-2.priority=1"
```
```json tab="Tags"
{
//...
"Tags": [
"traefik.tcp.routers.Router-1.rule=ClientIP(`192.168.0.12`)",
"traefik.tcp.routers.Router-1.entryPoints=web",
"traefik.tcp.routers.Router-1.service=service-1",
"traefik.tcp.routers.Router-1.priority=2",
"traefik.tcp.routers.Router-2.rule=ClientIP(`192.168.0.0/24`)",
"traefik.tcp.routers.Router-2.entryPoints=web",
"traefik.tcp.routers.Router-2.service=service-2",
"traefik.tcp.routers.Router-2.priority=1"
]
}
```
In the example above, the priority is configured so that `Router-1` will handle requests from `192.168.0.12`.
To avoid path overlap, routes are sorted, by default, in descending order using rules length.
The priority is directly equal to the length of the rule, and so the longest length has the highest priority.
A value of 0 for the priority is ignored: priority: 0 means that the default rules length sorting is used.
Negative priority values are supported.
Hanzo Ingress reserves a range of priorities for its internal routers, the maximum user-defined router priority value is:
(MaxInt32 - 1000)for 32-bit platforms,(MaxInt64 - 1000)for 64-bit platforms.