1# Routers 2 3Connecting Requests to Services 4{: .subtitle } 5 6![routers](../../assets/img/routers.png) 7 8A router is in charge of connecting incoming requests to the services that can handle them. 9In the process, routers may use pieces of [middleware](../../middlewares/overview.md) to update the request, 10or act before forwarding the request to the service. 11 12## Configuration Example 13 14??? example "Requests /foo are Handled by service-foo -- Using the [File Provider](../../providers/file.md)" 15 16 ```yaml tab="YAML" 17 ## Dynamic configuration 18 http: 19 routers: 20 my-router: 21 rule: "Path(`/foo`)" 22 service: service-foo 23 ``` 24 25 ```toml tab="TOML" 26 ## Dynamic configuration 27 [http.routers] 28 [http.routers.my-router] 29 rule = "Path(`/foo`)" 30 service = "service-foo" 31 ``` 32 33??? example "Forwarding all (non-tls) requests on port 3306 to a database service" 34 35 **Dynamic Configuration** 36 37 ```yaml tab="File (YAML)" 38 ## Dynamic configuration 39 tcp: 40 routers: 41 to-database: 42 entryPoints: 43 - "mysql" 44 # Catch every request (only available rule for non-tls routers. See below.) 45 rule: "HostSNI(`*`)" 46 service: database 47 ``` 48 49 ```toml tab="File (TOML)" 50 ## Dynamic configuration 51 [tcp] 52 [tcp.routers] 53 [tcp.routers.to-database] 54 entryPoints = ["mysql"] 55 # Catch every request (only available rule for non-tls routers. See below.) 56 rule = "HostSNI(`*`)" 57 service = "database" 58 ``` 59 60 **Static Configuration** 61 62 ```yaml tab="File (YAML)" 63 ## Static configuration 64 entryPoints: 65 web: 66 address: ":80" 67 mysql: 68 address: ":3306" 69 ``` 70 71 ```toml tab="File (TOML)" 72 ## Static configuration 73 [entryPoints] 74 [entryPoints.web] 75 address = ":80" 76 [entryPoints.mysql] 77 address = ":3306" 78 ``` 79 80 ```bash tab="CLI" 81 ## Static configuration 82 --entryPoints.web.address=:80 83 --entryPoints.mysql.address=:3306 84 ``` 85 86## Configuring HTTP Routers 87 88!!! warning "The character `@` is not authorized in the router name" 89 90### EntryPoints 91 92If not specified, HTTP routers will accept requests from all defined entry points. 93If you want to limit the router scope to a set of entry points, set the `entryPoints` option. 94 95??? example "Listens to Every EntryPoint" 96 97 **Dynamic Configuration** 98 99 ```yaml tab="File (YAML)" 100 ## Dynamic configuration 101 http: 102 routers: 103 Router-1: 104 # By default, routers listen to every entry points 105 rule: "Host(`example.com`)" 106 service: "service-1" 107 ``` 108 109 ```toml tab="File (TOML)" 110 ## Dynamic configuration 111 [http.routers] 112 [http.routers.Router-1] 113 # By default, routers listen to every entry points 114 rule = "Host(`example.com`)" 115 service = "service-1" 116 ``` 117 118 **Static Configuration** 119 120 ```yaml tab="File (YAML)" 121 ## Static configuration 122 entryPoints: 123 web: 124 address: ":80" 125 websecure: 126 address: ":443" 127 other: 128 address: ":9090" 129 ``` 130 131 ```toml tab="File (TOML)" 132 ## Static configuration 133 [entryPoints] 134 [entryPoints.web] 135 address = ":80" 136 [entryPoints.websecure] 137 address = ":443" 138 [entryPoints.other] 139 address = ":9090" 140 ``` 141 142 ```bash tab="CLI" 143 ## Static configuration 144 --entrypoints.web.address=:80 145 --entrypoints.websecure.address=:443 146 --entrypoints.other.address=:9090 147 ``` 148 149??? example "Listens to Specific EntryPoints" 150 151 **Dynamic Configuration** 152 153 ```yaml tab="File (YAML)" 154 ## Dynamic configuration 155 http: 156 routers: 157 Router-1: 158 # won't listen to entry point web 159 entryPoints: 160 - "websecure" 161 - "other" 162 rule: "Host(`example.com`)" 163 service: "service-1" 164 ``` 165 166 ```toml tab="File (TOML)" 167 ## Dynamic configuration 168 [http.routers] 169 [http.routers.Router-1] 170 # won't listen to entry point web 171 entryPoints = ["websecure", "other"] 172 rule = "Host(`example.com`)" 173 service = "service-1" 174 ``` 175 176 **Static Configuration** 177 178 ```yaml tab="File (YAML)" 179 ## Static configuration 180 entryPoints: 181 web: 182 address: ":80" 183 websecure: 184 address: ":443" 185 other: 186 address: ":9090" 187 ``` 188 189 ```toml tab="File (TOML)" 190 ## Static configuration 191 [entryPoints] 192 [entryPoints.web] 193 address = ":80" 194 [entryPoints.websecure] 195 address = ":443" 196 [entryPoints.other] 197 address = ":9090" 198 ``` 199 200 ```bash tab="CLI" 201 ## Static configuration 202 --entrypoints.web.address=:80 203 --entrypoints.websecure.address=:443 204 --entrypoints.other.address=:9090 205 ``` 206 207### Rule 208 209Rules are a set of matchers configured with values, that determine if a particular request matches specific criteria. 210If the rule is verified, the router becomes active, calls middlewares, and then forwards the request to the service. 211 212??? tip "Backticks or Quotes?" 213 To set the value of a rule, use [backticks](https://en.wiktionary.org/wiki/backtick) ``` ` ``` or escaped double-quotes `\"`. 214 215 Single quotes `'` are not accepted as values are [Golang's String Literals](https://golang.org/ref/spec#String_literals). 216 217!!! example "Host is example.com" 218 219 ```toml 220 rule = "Host(`example.com`)" 221 ``` 222 223!!! example "Host is example.com OR Host is example.org AND path is /traefik" 224 225 ```toml 226 rule = "Host(`example.com`) || (Host(`example.org`) && Path(`/traefik`))" 227 ``` 228 229The table below lists all the available matchers: 230 231| Rule | Description | 232|------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------| 233| ```Headers(`key`, `value`)``` | Check if there is a key `key`defined in the headers, with the value `value` | 234| ```HeadersRegexp(`key`, `regexp`)``` | Check if there is a key `key`defined in the headers, with a value that matches the regular expression `regexp` | 235| ```Host(`example.com`, ...)``` | Check if the request domain (host header value) targets one of the given `domains`. | 236| ```HostHeader(`example.com`, ...)``` | Same as `Host`, only exists for historical reasons. | 237| ```HostRegexp(`example.com`, `{subdomain:[a-z]+}.example.com`, ...)``` | Match the request domain. See "Regexp Syntax" below. | 238| ```Method(`GET`, ...)``` | Check if the request method is one of the given `methods` (`GET`, `POST`, `PUT`, `DELETE`, `PATCH`, `HEAD`) | 239| ```Path(`/path`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`, ...)``` | Match exact request path. See "Regexp Syntax" below. | 240| ```PathPrefix(`/products/`, `/articles/{cat:[a-z]+}/{id:[0-9]+}`)``` | Match request prefix path. See "Regexp Syntax" below. | 241| ```Query(`foo=bar`, `bar=baz`)``` | Match Query String parameters. It accepts a sequence of key=value pairs. | 242| ```ClientIP(`10.0.0.0/16`, `::1`)``` | Match if the request client IP is one of the given IP/CIDR. It accepts IPv4, IPv6 and CIDR formats. | 243 244!!! important "Non-ASCII Domain Names" 245 246 Non-ASCII characters are not supported in `Host` and `HostRegexp` expressions, and by doing so the associated router will be invalid. 247 For the `Host` expression, domain names containing non-ASCII characters must be provided as punycode encoded values ([rfc 3492](https://tools.ietf.org/html/rfc3492)). 248 As well, when using the `HostRegexp` expressions, in order to match domain names containing non-ASCII characters, the regular expression should match a punycode encoded domain name. 249 250!!! important "Regexp Syntax" 251 252 `HostRegexp`, `PathPrefix`, and `Path` accept an expression with zero or more groups enclosed by curly braces, which are called named regexps. 253 Named regexps, of the form `{name:regexp}`, are the only expressions considered for regexp matching. 254 The regexp name (`name` in the above example) is an arbitrary value, that exists only for historical reasons. 255 256 Any `regexp` supported by [Go's regexp package](https://golang.org/pkg/regexp/) may be used. 257 258!!! info "Combining Matchers Using Operators and Parenthesis" 259 260 You can combine multiple matchers using the AND (`&&`) and OR (`||`) operators. You can also use parenthesis. 261 262!!! info "Invert a matcher" 263 264 You can invert a matcher by using the `!` operator. 265 266!!! important "Rule, Middleware, and Services" 267 268 The rule is evaluated "before" any middleware has the opportunity to work, and "before" the request is forwarded to the service. 269 270!!! info "Path Vs PathPrefix" 271 272 Use `Path` if your service listens on the exact path only. For instance, `Path: /products` would match `/products` but not `/products/shoes`. 273 274 Use a `*Prefix*` matcher if your service listens on a particular base path but also serves requests on sub-paths. 275 For instance, `PathPrefix: /products` would match `/products` but also `/products/shoes` and `/products/shirts`. 276 Since the path is forwarded as-is, your service is expected to listen on `/products`. 277 278!!! info "ClientIP matcher" 279 280 The `ClientIP` matcher will only match the request client IP and does not use the `X-Forwarded-For` header for matching. 281 282### Priority 283 284To 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. 285 286A value of `0` for the priority is ignored: `priority = 0` means that the default rules length sorting is used. 287 288??? info "How default priorities are computed" 289 290 ```yaml tab="File (YAML)" 291 ## Dynamic configuration 292 http: 293 routers: 294 Router-1: 295 rule: "HostRegexp(`.*\.traefik\.com`)" 296 # ... 297 Router-2: 298 rule: "Host(`foobar.traefik.com`)" 299 # ... 300 ``` 301 302 ```toml tab="File (TOML)" 303 ## Dynamic configuration 304 [http.routers] 305 [http.routers.Router-1] 306 rule = "HostRegexp(`.*\.traefik\.com`)" 307 # ... 308 [http.routers.Router-2] 309 rule = "Host(`foobar.traefik.com`)" 310 # ... 311 ``` 312 313 In this case, all requests with host `foobar.traefik.com` will be routed through `Router-1` instead of `Router-2`. 314 315 | Name | Rule | Priority | 316 |----------|--------------------------------------|----------| 317 | Router-1 | ```HostRegexp(`.*\.traefik\.com`)``` | 30 | 318 | Router-2 | ```Host(`foobar.traefik.com`)``` | 26 | 319 320 The previous table shows that `Router-1` has a higher priority than `Router-2`. 321 322 To solve this issue, the priority must be set. 323 324??? example "Set priorities -- using the [File Provider](../../providers/file.md)" 325 326 ```yaml tab="File (YAML)" 327 ## Dynamic configuration 328 http: 329 routers: 330 Router-1: 331 rule: "HostRegexp(`.*\.traefik\.com`)" 332 entryPoints: 333 - "web" 334 service: service-1 335 priority: 1 336 Router-2: 337 rule: "Host(`foobar.traefik.com`)" 338 entryPoints: 339 - "web" 340 priority: 2 341 service: service-2 342 ``` 343 344 ```toml tab="File (TOML)" 345 ## Dynamic configuration 346 [http.routers] 347 [http.routers.Router-1] 348 rule = "HostRegexp(`.*\.traefik\.com`)" 349 entryPoints = ["web"] 350 service = "service-1" 351 priority = 1 352 [http.routers.Router-2] 353 rule = "Host(`foobar.traefik.com`)" 354 entryPoints = ["web"] 355 priority = 2 356 service = "service-2" 357 ``` 358 359 In this configuration, the priority is configured to allow `Router-2` to handle requests with the `foobar.traefik.com` host. 360 361### Middlewares 362 363You can attach a list of [middlewares](../../middlewares/overview.md) to each HTTP router. 364The middlewares will take effect only if the rule matches, and before forwarding the request to the service. 365 366!!! warning "The character `@` is not authorized in the middleware name." 367 368!!! tip "Middlewares order" 369 370 Middlewares are applied in the same order as their declaration in **router**. 371 372??? example "With a [middleware](../../middlewares/overview.md) -- using the [File Provider](../../providers/file.md)" 373 374 ```yaml tab="YAML" 375 ## Dynamic configuration 376 http: 377 routers: 378 my-router: 379 rule: "Path(`/foo`)" 380 # declared elsewhere 381 middlewares: 382 - authentication 383 service: service-foo 384 ``` 385 386 ```toml tab="TOML" 387 ## Dynamic configuration 388 [http.routers] 389 [http.routers.my-router] 390 rule = "Path(`/foo`)" 391 # declared elsewhere 392 middlewares = ["authentication"] 393 service = "service-foo" 394 ``` 395 396### Service 397 398Each request must eventually be handled by a [service](../services/index.md), 399which is why each router definition should include a service target, 400which is basically where the request will be passed along to. 401 402In general, a service assigned to a router should have been defined, 403but there are exceptions for label-based providers. 404See the specific [docker](../providers/docker.md#service-definition), [rancher](../providers/rancher.md#service-definition), 405or [marathon](../providers/marathon.md#service-definition) documentation. 406 407!!! warning "The character `@` is not authorized in the service name." 408 409!!! important "HTTP routers can only target HTTP services (not TCP services)." 410 411### TLS 412 413#### General 414 415 When a TLS section is specified, it instructs Traefik that the current router is dedicated to HTTPS requests only (and that the router should ignore HTTP (non TLS) requests). 416Traefik will terminate the SSL connections (meaning that it will send decrypted data to the services). 417 418??? example "Configuring the router to accept HTTPS requests only" 419 420 ```yaml tab="File (YAML)" 421 ## Dynamic configuration 422 http: 423 routers: 424 Router-1: 425 rule: "Host(`foo-domain`) && Path(`/foo-path/`)" 426 service: service-id 427 # will terminate the TLS request 428 tls: {} 429 ``` 430 431 ```toml tab="File (TOML)" 432 ## Dynamic configuration 433 [http.routers] 434 [http.routers.Router-1] 435 rule = "Host(`foo-domain`) && Path(`/foo-path/`)" 436 service = "service-id" 437 # will terminate the TLS request 438 [http.routers.Router-1.tls] 439 ``` 440 441!!! important "Routers for HTTP & HTTPS" 442 443 If you need to define the same route for both HTTP and HTTPS requests, you will need to define two different routers: 444 one with the tls section, one without. 445 446 ??? example "HTTP & HTTPS routes" 447 448 ```yaml tab="File (YAML)" 449 ## Dynamic configuration 450 http: 451 routers: 452 my-https-router: 453 rule: "Host(`foo-domain`) && Path(`/foo-path/`)" 454 service: service-id 455 # will terminate the TLS request 456 tls: {} 457 458 my-http-router: 459 rule: "Host(`foo-domain`) && Path(`/foo-path/`)" 460 service: service-id 461 ``` 462 463 ```toml tab="File (TOML)" 464 ## Dynamic configuration 465 [http.routers] 466 [http.routers.my-https-router] 467 rule = "Host(`foo-domain`) && Path(`/foo-path/`)" 468 service = "service-id" 469 # will terminate the TLS request 470 [http.routers.my-https-router.tls] 471 472 [http.routers.my-http-router] 473 rule = "Host(`foo-domain`) && Path(`/foo-path/`)" 474 service = "service-id" 475 ``` 476 477#### `options` 478 479The `options` field enables fine-grained control of the TLS parameters. 480It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied only if a `Host` rule is defined. 481 482!!! info "Server Name Association" 483 484 Even though one might get the impression that a TLS options reference is mapped to a router, or a router rule, 485 one should realize that it is actually mapped only to the host name found in the `Host` part of the rule. 486 Of course, there could also be several `Host` parts in a rule, in which case the TLS options reference would be mapped to as many host names. 487 488 Another thing to keep in mind is: 489 the TLS option is picked from the mapping mentioned above and based on the server name provided during the TLS handshake, 490 and it all happens before routing actually occurs. 491 492!!! info "Domain Fronting" 493 494 In the case of domain fronting, 495 if the TLS options associated with the Host Header and the SNI are different then Traefik will respond with a status code `421`. 496 497??? example "Configuring the TLS options" 498 499 ```yaml tab="File (YAML)" 500 ## Dynamic configuration 501 http: 502 routers: 503 Router-1: 504 rule: "Host(`foo-domain`) && Path(`/foo-path/`)" 505 service: service-id 506 # will terminate the TLS request 507 tls: 508 options: foo 509 510 tls: 511 options: 512 foo: 513 minVersion: VersionTLS12 514 cipherSuites: 515 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 516 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 517 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 518 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 519 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 520 ``` 521 522 ```toml tab="File (TOML)" 523 ## Dynamic configuration 524 [http.routers] 525 [http.routers.Router-1] 526 rule = "Host(`foo-domain`) && Path(`/foo-path/`)" 527 service = "service-id" 528 # will terminate the TLS request 529 [http.routers.Router-1.tls] 530 options = "foo" 531 532 [tls.options] 533 [tls.options.foo] 534 minVersion = "VersionTLS12" 535 cipherSuites = [ 536 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 537 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", 538 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 539 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 540 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 541 ] 542 ``` 543 544!!! important "Conflicting TLS Options" 545 546 Since a TLS options reference is mapped to a host name, 547 if a configuration introduces a situation where the same host name (from a `Host` rule) gets matched with two TLS options references, 548 a conflict occurs, such as in the example below: 549 550 ```yaml tab="File (YAML)" 551 ## Dynamic configuration 552 http: 553 routers: 554 routerfoo: 555 rule: "Host(`snitest.com`) && Path(`/foo`)" 556 tls: 557 options: foo 558 559 routerbar: 560 rule: "Host(`snitest.com`) && Path(`/bar`)" 561 tls: 562 options: bar 563 ``` 564 565 ```toml tab="File (TOML)" 566 ## Dynamic configuration 567 [http.routers] 568 [http.routers.routerfoo] 569 rule = "Host(`snitest.com`) && Path(`/foo`)" 570 [http.routers.routerfoo.tls] 571 options = "foo" 572 573 [http.routers] 574 [http.routers.routerbar] 575 rule = "Host(`snitest.com`) && Path(`/bar`)" 576 [http.routers.routerbar.tls] 577 options = "bar" 578 ``` 579 580 If that happens, both mappings are discarded, and the host name (`snitest.com` in this case) for these routers gets associated with the default TLS options instead. 581 582#### `certResolver` 583 584If `certResolver` is defined, Traefik will try to generate certificates based on routers `Host` & `HostSNI` rules. 585 586```yaml tab="File (YAML)" 587## Dynamic configuration 588http: 589 routers: 590 routerfoo: 591 rule: "Host(`snitest.com`) && Path(`/foo`)" 592 tls: 593 certResolver: foo 594``` 595 596```toml tab="File (TOML)" 597## Dynamic configuration 598[http.routers] 599 [http.routers.routerfoo] 600 rule = "Host(`snitest.com`) && Path(`/foo`)" 601 [http.routers.routerfoo.tls] 602 certResolver = "foo" 603``` 604 605!!! info "Multiple Hosts in a Rule" 606 The rule ```Host(`test1.example.com`,`test2.example.com`)``` will request a certificate with the main domain `test1.example.com` and SAN `test2.example.com`. 607 608#### `domains` 609 610You can set SANs (alternative domains) for each main domain. 611Every domain must have A/AAAA records pointing to Traefik. 612Each domain & SAN will lead to a certificate request. 613 614```yaml tab="File (YAML)" 615## Dynamic configuration 616http: 617 routers: 618 routerbar: 619 rule: "Host(`snitest.com`) && Path(`/bar`)" 620 tls: 621 certResolver: "bar" 622 domains: 623 - main: "snitest.com" 624 sans: 625 - "*.snitest.com" 626``` 627 628```toml tab="File (TOML)" 629## Dynamic configuration 630[http.routers] 631 [http.routers.routerbar] 632 rule = "Host(`snitest.com`) && Path(`/bar`)" 633 [http.routers.routerbar.tls] 634 certResolver = "bar" 635 [[http.routers.routerbar.tls.domains]] 636 main = "snitest.com" 637 sans = ["*.snitest.com"] 638``` 639 640[ACME v2](https://community.letsencrypt.org/t/acme-v2-and-wildcard-certificate-support-is-live/55579) supports wildcard certificates. 641As described in [Let's Encrypt's post](https://community.letsencrypt.org/t/staging-endpoint-for-acme-v2/49605) wildcard certificates can only be generated through a [`DNS-01` challenge](../../https/acme.md#dnschallenge). 642 643Most likely the root domain should receive a certificate too, so it needs to be specified as SAN and 2 `DNS-01` challenges are executed. 644In this case the generated DNS TXT record for both domains is the same. 645Even though this behavior is [DNS RFC](https://community.letsencrypt.org/t/wildcard-issuance-two-txt-records-for-the-same-name/54528/2) compliant, 646it can lead to problems as all DNS providers keep DNS records cached for a given time (TTL) and this TTL can be greater than the challenge timeout making the `DNS-01` challenge fail. 647 648The Traefik ACME client library [lego](https://github.com/go-acme/lego) supports some but not all DNS providers to work around this issue. 649The [supported `provider` table](../../https/acme.md#providers) indicates if they allow generating certificates for a wildcard domain and its root domain. 650 651!!! important "Wildcard certificates can only be verified through a [`DNS-01` challenge](../../https/acme.md#dnschallenge)." 652 653!!! warning "Double Wildcard Certificates" 654 It is not possible to request a double wildcard certificate for a domain (for example `*.*.local.com`). 655 656## Configuring TCP Routers 657 658!!! warning "The character `@` is not authorized in the router name" 659 660### General 661 662If both HTTP routers and TCP routers listen to the same entry points, the TCP routers will apply *before* the HTTP routers. 663If no matching route is found for the TCP routers, then the HTTP routers will take over. 664 665### EntryPoints 666 667If not specified, TCP routers will accept requests from all defined entry points. 668If you want to limit the router scope to a set of entry points, set the entry points option. 669 670??? example "Listens to Every Entry Point" 671 672 **Dynamic Configuration** 673 674 ```yaml tab="File (YAML)" 675 ## Dynamic configuration 676 677 tcp: 678 routers: 679 Router-1: 680 # By default, routers listen to every entrypoints 681 rule: "HostSNI(`example.com`)" 682 service: "service-1" 683 # will route TLS requests (and ignore non tls requests) 684 tls: {} 685 ``` 686 687 ```toml tab="File (TOML)" 688 ## Dynamic configuration 689 690 [tcp.routers] 691 [tcp.routers.Router-1] 692 # By default, routers listen to every entrypoints 693 rule = "HostSNI(`example.com`)" 694 service = "service-1" 695 # will route TLS requests (and ignore non tls requests) 696 [tcp.routers.Router-1.tls] 697 ``` 698 699 **Static Configuration** 700 701 ```yaml tab="File (YAML)" 702 ## Static configuration 703 704 entryPoints: 705 web: 706 address: ":80" 707 websecure: 708 address: ":443" 709 other: 710 address: ":9090" 711 ``` 712 713 ```toml tab="File (TOML)" 714 ## Static configuration 715 716 [entryPoints] 717 [entryPoints.web] 718 address = ":80" 719 [entryPoints.websecure] 720 address = ":443" 721 [entryPoints.other] 722 address = ":9090" 723 ``` 724 725 ```bash tab="CLI" 726 ## Static configuration 727 --entrypoints.web.address=:80 728 --entrypoints.websecure.address=:443 729 --entrypoints.other.address=:9090 730 ``` 731 732??? example "Listens to Specific Entry Points" 733 734 **Dynamic Configuration** 735 736 ```yaml tab="File (YAML)" 737 ## Dynamic configuration 738 tcp: 739 routers: 740 Router-1: 741 # won't listen to entry point web 742 entryPoints: 743 - "websecure" 744 - "other" 745 rule: "HostSNI(`example.com`)" 746 service: "service-1" 747 # will route TLS requests (and ignore non tls requests) 748 tls: {} 749 ``` 750 751 ```toml tab="File (TOML)" 752 ## Dynamic configuration 753 [tcp.routers] 754 [tcp.routers.Router-1] 755 # won't listen to entry point web 756 entryPoints = ["websecure", "other"] 757 rule = "HostSNI(`example.com`)" 758 service = "service-1" 759 # will route TLS requests (and ignore non tls requests) 760 [tcp.routers.Router-1.tls] 761 ``` 762 763 **Static Configuration** 764 765 ```yaml tab="File (YAML)" 766 ## Static configuration 767 768 entryPoints: 769 web: 770 address: ":80" 771 websecure: 772 address: ":443" 773 other: 774 address: ":9090" 775 ``` 776 777 ```toml tab="File (TOML)" 778 ## Static configuration 779 780 [entryPoints] 781 [entryPoints.web] 782 address = ":80" 783 [entryPoints.websecure] 784 address = ":443" 785 [entryPoints.other] 786 address = ":9090" 787 ``` 788 789 ```bash tab="CLI" 790 ## Static configuration 791 --entrypoints.web.address=:80 792 --entrypoints.websecure.address=:443 793 --entrypoints.other.address=:9090 794 ``` 795 796### Rule 797 798| Rule | Description | 799|--------------------------------|-------------------------------------------------------------------------| 800| ```HostSNI(`domain-1`, ...)``` | Check if the Server Name Indication corresponds to the given `domains`. | 801 802!!! important "Non-ASCII Domain Names" 803 804 Non-ASCII characters are not supported in the `HostSNI` expression, and by doing so the associated TCP router will be invalid. 805 Domain names containing non-ASCII characters must be provided as punycode encoded values ([rfc 3492](https://tools.ietf.org/html/rfc3492)). 806 807!!! important "HostSNI & TLS" 808 809 It is important to note that the Server Name Indication is an extension of the TLS protocol. 810 Hence, only TLS routers will be able to specify a domain name with that rule. 811 However, non-TLS routers will have to explicitly use that rule with `*` (every domain) to state that every non-TLS request will be handled by the router. 812 813### Middlewares 814 815You can attach a list of [middlewares](../../middlewares/overview.md) to each TCP router. 816The middlewares will take effect only if the rule matches, and before connecting to the service. 817 818!!! warning "The character `@` is not allowed to be used in the middleware name." 819 820!!! tip "Middlewares order" 821 822 Middlewares are applied in the same order as their declaration in **router**. 823 824??? example "With a [middleware](../../middlewares/tcp/overview.md) -- using the [File Provider](../../providers/file.md)" 825 826 ```toml tab="TOML" 827 ## Dynamic configuration 828 [tcp.routers] 829 [tcp.routers.my-router] 830 rule = "HostSNI(`*`)" 831 # declared elsewhere 832 middlewares = ["ipwhitelist"] 833 service = "service-foo" 834 ``` 835 836 ```yaml tab="YAML" 837 ## Dynamic configuration 838 tcp: 839 routers: 840 my-router: 841 rule: "HostSNI(`*`)" 842 # declared elsewhere 843 middlewares: 844 - ipwhitelist 845 service: service-foo 846 ``` 847 848### Services 849 850You must attach a TCP [service](../services/index.md) per TCP router. 851Services are the target for the router. 852 853!!! important "TCP routers can only target TCP services (not HTTP services)." 854 855### TLS 856 857#### General 858 859When a TLS section is specified, 860it instructs Traefik that the current router is dedicated to TLS requests only (and that the router should ignore non-TLS requests). 861 862By default, a router with a TLS section will terminate the TLS connections, meaning that it will send decrypted data to the services. 863 864??? example "Router for TLS requests" 865 866 ```yaml tab="File (YAML)" 867 ## Dynamic configuration 868 tcp: 869 routers: 870 Router-1: 871 rule: "HostSNI(`foo-domain`)" 872 service: service-id 873 # will terminate the TLS request by default 874 tls: {} 875 ``` 876 877 ```toml tab="File (TOML)" 878 ## Dynamic configuration 879 [tcp.routers] 880 [tcp.routers.Router-1] 881 rule = "HostSNI(`foo-domain`)" 882 service = "service-id" 883 # will terminate the TLS request by default 884 [tcp.routers.Router-1.tls] 885 ``` 886 887#### `passthrough` 888 889As seen above, a TLS router will terminate the TLS connection by default. 890However, the `passthrough` option can be specified to set whether the requests should be forwarded "as is", keeping all data encrypted. 891 892It defaults to `false`. 893 894??? example "Configuring passthrough" 895 896 ```yaml tab="File (YAML)" 897 ## Dynamic configuration 898 tcp: 899 routers: 900 Router-1: 901 rule: "HostSNI(`foo-domain`)" 902 service: service-id 903 tls: 904 passthrough: true 905 ``` 906 907 ```toml tab="File (TOML)" 908 ## Dynamic configuration 909 [tcp.routers] 910 [tcp.routers.Router-1] 911 rule = "HostSNI(`foo-domain`)" 912 service = "service-id" 913 [tcp.routers.Router-1.tls] 914 passthrough = true 915 ``` 916 917#### `options` 918 919The `options` field enables fine-grained control of the TLS parameters. 920It refers to a [TLS Options](../../https/tls.md#tls-options) and will be applied only if a `HostSNI` rule is defined. 921 922!!! example "Configuring the tls options" 923 924 ```yaml tab="File (YAML)" 925 ## Dynamic configuration 926 tcp: 927 routers: 928 Router-1: 929 rule: "HostSNI(`foo-domain`)" 930 service: service-id 931 # will terminate the TLS request 932 tls: 933 options: foo 934 935 tls: 936 options: 937 foo: 938 minVersion: VersionTLS12 939 cipherSuites: 940 - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 941 - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 942 - TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 943 - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 944 - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 945 ``` 946 947 ```toml tab="File (TOML)" 948 ## Dynamic configuration 949 [tcp.routers] 950 [tcp.routers.Router-1] 951 rule = "HostSNI(`foo-domain`)" 952 service = "service-id" 953 # will terminate the TLS request 954 [tcp.routers.Router-1.tls] 955 options = "foo" 956 957 [tls.options] 958 [tls.options.foo] 959 minVersion = "VersionTLS12" 960 cipherSuites = [ 961 "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", 962 "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", 963 "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", 964 "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", 965 "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", 966 ] 967 ``` 968 969#### `certResolver` 970 971See [`certResolver` for HTTP router](./index.md#certresolver) for more information. 972 973```yaml tab="File (YAML)" 974## Dynamic configuration 975tcp: 976 routers: 977 routerfoo: 978 rule: "HostSNI(`snitest.com`)" 979 tls: 980 certResolver: foo 981``` 982 983```toml tab="File (TOML)" 984## Dynamic configuration 985[tcp.routers] 986 [tcp.routers.routerfoo] 987 rule = "HostSNI(`snitest.com`)" 988 [tcp.routers.routerfoo.tls] 989 certResolver = "foo" 990``` 991 992#### `domains` 993 994See [`domains` for HTTP router](./index.md#domains) for more information. 995 996```yaml tab="File (YAML)" 997## Dynamic configuration 998tcp: 999 routers: 1000 routerbar: 1001 rule: "HostSNI(`snitest.com`)" 1002 tls: 1003 certResolver: "bar" 1004 domains: 1005 - main: "snitest.com" 1006 sans: 1007 - "*.snitest.com" 1008``` 1009 1010```toml tab="File (TOML)" 1011## Dynamic configuration 1012[tcp.routers] 1013 [tcp.routers.routerbar] 1014 rule = "HostSNI(`snitest.com`)" 1015 [tcp.routers.routerbar.tls] 1016 certResolver = "bar" 1017 [[tcp.routers.routerbar.tls.domains]] 1018 main = "snitest.com" 1019 sans = ["*.snitest.com"] 1020``` 1021 1022## Configuring UDP Routers 1023 1024!!! warning "The character `@` is not allowed in the router name" 1025 1026### General 1027 1028Similarly to TCP, as UDP is the transport layer, there is no concept of a request, 1029so there is no notion of an URL path prefix to match an incoming UDP packet with. 1030Furthermore, as there is no good TLS support at the moment for multiple hosts, 1031there is no Host SNI notion to match against either. 1032Therefore, there is no criterion that could be used as a rule to match incoming packets in order to route them. 1033So UDP "routers" at this time are pretty much only load-balancers in one form or another. 1034 1035!!! important "Sessions and timeout" 1036 1037 Even though UDP is connectionless (and because of that), 1038 the implementation of an UDP router in Traefik relies on what we (and a couple of other implementations) call a `session`. 1039 It basically means that some state is kept about an ongoing communication between a client and a backend, 1040 notably so that the proxy knows where to forward a response packet from a backend. 1041 As expected, a `timeout` is associated to each of these sessions, 1042 so that they get cleaned out if they go through a period of inactivity longer than a given duration. 1043 Timeout can be configured using the `entryPoints.name.udp.timeout` option as described 1044 under [entry points](../entrypoints/#udp-options). 1045 1046### EntryPoints 1047 1048If not specified, UDP routers will accept packets from all defined (UDP) entry points. 1049If one wants to limit the router scope to a set of entry points, one should set the entry points option. 1050 1051??? example "Listens to Every Entry Point" 1052 1053 **Dynamic Configuration** 1054 1055 ```yaml tab="File (YAML)" 1056 ## Dynamic configuration 1057 1058 udp: 1059 routers: 1060 Router-1: 1061 # By default, routers listen to all UDP entrypoints 1062 # i.e. "other", and "streaming". 1063 service: "service-1" 1064 ``` 1065 1066 ```toml tab="File (TOML)" 1067 ## Dynamic configuration 1068 1069 [udp.routers] 1070 [udp.routers.Router-1] 1071 # By default, routers listen to all UDP entrypoints, 1072 # i.e. "other", and "streaming". 1073 service = "service-1" 1074 ``` 1075 1076 **Static Configuration** 1077 1078 ```yaml tab="File (YAML)" 1079 ## Static configuration 1080 1081 entryPoints: 1082 # not used by UDP routers 1083 web: 1084 address: ":80" 1085 # used by UDP routers 1086 other: 1087 address: ":9090/udp" 1088 streaming: 1089 address: ":9191/udp" 1090 ``` 1091 1092 ```toml tab="File (TOML)" 1093 ## Static configuration 1094 1095 [entryPoints] 1096 # not used by UDP routers 1097 [entryPoints.web] 1098 address = ":80" 1099 # used by UDP routers 1100 [entryPoints.other] 1101 address = ":9090/udp" 1102 [entryPoints.streaming] 1103 address = ":9191/udp" 1104 ``` 1105 1106 ```bash tab="CLI" 1107 ## Static configuration 1108 --entrypoints.web.address=":80" 1109 --entrypoints.other.address=":9090/udp" 1110 --entrypoints.streaming.address=":9191/udp" 1111 ``` 1112 1113??? example "Listens to Specific Entry Points" 1114 1115 **Dynamic Configuration** 1116 1117 ```yaml tab="File (YAML)" 1118 ## Dynamic configuration 1119 udp: 1120 routers: 1121 Router-1: 1122 # does not listen on "other" entry point 1123 entryPoints: 1124 - "streaming" 1125 service: "service-1" 1126 ``` 1127 1128 ```toml tab="File (TOML)" 1129 ## Dynamic configuration 1130 [udp.routers] 1131 [udp.routers.Router-1] 1132 # does not listen on "other" entry point 1133 entryPoints = ["streaming"] 1134 service = "service-1" 1135 ``` 1136 1137 **Static Configuration** 1138 1139 ```yaml tab="File (YAML)" 1140 ## Static configuration 1141 1142 entryPoints: 1143 web: 1144 address: ":80" 1145 other: 1146 address: ":9090/udp" 1147 streaming: 1148 address: ":9191/udp" 1149 ``` 1150 1151 ```toml tab="File (TOML)" 1152 ## Static configuration 1153 1154 [entryPoints] 1155 [entryPoints.web] 1156 address = ":80" 1157 [entryPoints.other] 1158 address = ":9090/udp" 1159 [entryPoints.streaming] 1160 address = ":9191/udp" 1161 ``` 1162 1163 ```bash tab="CLI" 1164 ## Static configuration 1165 --entrypoints.web.address=":80" 1166 --entrypoints.other.address=":9090/udp" 1167 --entrypoints.streaming.address=":9191/udp" 1168 ``` 1169 1170### Services 1171 1172There must be one (and only one) UDP [service](../services/index.md) referenced per UDP router. 1173Services are the target for the router. 1174 1175!!! important "UDP routers can only target UDP services (and not HTTP or TCP services)." 1176