mirror of
https://github.com/traefik/traefik.git
synced 2026-06-18 19:38:23 +03:00
Fix priority display in dashboard and ACME bypass redirect
This commit is contained in:
@@ -87,12 +87,13 @@ additionalArguments:
|
||||
|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------------------|:---------|
|
||||
| <a id="opt-address" href="#opt-address" title="#opt-address">`address`</a> | Define the port, and optionally the hostname, on which to listen for incoming connections and packets.<br /> It also defines the protocol to use (TCP or UDP).<br /> If no protocol is specified, the default is TCP. The format is:`[host]:port[/tcp\|/udp] | - | Yes |
|
||||
| <a id="opt-asDefault" href="#opt-asDefault" title="#opt-asDefault">`asDefault`</a> | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
|
||||
| <a id="opt-allowACMEByPass" href="#opt-allowACMEByPass" title="#opt-allowACMEByPass">`allowACMEByPass`</a> | Enables handling of ACME TLS and HTTP challenges with custom routers instead of the internal ACME router. | false | No |
|
||||
| <a id="opt-forwardedHeaders-trustedIPs" href="#opt-forwardedHeaders-trustedIPs" title="#opt-forwardedHeaders-trustedIPs">`forwardedHeaders.trustedIPs`</a> | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
|
||||
| <a id="opt-forwardedHeaders-insecure" href="#opt-forwardedHeaders-insecure" title="#opt-forwardedHeaders-insecure">`forwardedHeaders.insecure`</a> | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
|
||||
| <a id="opt-http-redirections-entryPoint-to" href="#opt-http-redirections-entryPoint-to" title="#opt-http-redirections-entryPoint-to">`http.redirections.`<br />`entryPoint.to`</a> | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
|
||||
| <a id="opt-http-redirections-entryPoint-scheme" href="#opt-http-redirections-entryPoint-scheme" title="#opt-http-redirections-entryPoint-scheme">`http.redirections.`<br />`entryPoint.scheme`</a> | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
|
||||
| <a id="opt-http-redirections-entryPoint-permanent" href="#opt-http-redirections-entryPoint-permanent" title="#opt-http-redirections-entryPoint-permanent">`http.redirections.`<br />`entryPoint.permanent`</a> | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |
|
||||
| <a id="opt-http-redirections-entryPoint-priority" href="#opt-http-redirections-entryPoint-priority" title="#opt-http-redirections-entryPoint-priority">`http.redirections.`<br />`entryPoint.priority`</a> | Default priority applied to the routers attached to the `entryPoint`. | MaxInt32-1 (2147483646) | No |
|
||||
| <a id="opt-http-redirections-entryPoint-priority" href="#opt-http-redirections-entryPoint-priority" title="#opt-http-redirections-entryPoint-priority">`http.redirections.`<br />`entryPoint.priority`</a> | Default priority applied to the routers attached to the `entryPoint`. | MaxInt-1 (`2147483646` on 32-bit, `9223372036854775806` on 64-bit) | No |
|
||||
| <a id="opt-http-encodedCharacters" href="#opt-http-encodedCharacters" title="#opt-http-encodedCharacters">`http.encodedCharacters`</a> | Defines which encoded characters are allowed in the request path. More information [here](#encoded-characters). | false | No |
|
||||
| <a id="opt-http-encodedCharacters-allowEncodedSlash" href="#opt-http-encodedCharacters-allowEncodedSlash" title="#opt-http-encodedCharacters-allowEncodedSlash">`http.encodedCharacters.`<br />`allowEncodedSlash`</a> | Defines whether requests with encoded slash characters in the path are allowed. | true | No |
|
||||
| <a id="opt-http-encodedCharacters-allowEncodedBackSlash" href="#opt-http-encodedCharacters-allowEncodedBackSlash" title="#opt-http-encodedCharacters-allowEncodedBackSlash">`http.encodedCharacters.`<br />`allowEncodedBackSlash`</a> | Defines whether requests with encoded back slash characters in the path are allowed. | true | No |
|
||||
@@ -144,6 +145,53 @@ The `asDefault` option has no effect on UDP entryPoints.
|
||||
When a UDP router does not define the entryPoints option, it is attached to all
|
||||
available UDP entryPoints.
|
||||
|
||||
### allowACMEByPass
|
||||
|
||||
By default, Traefik creates an internal router with the highest possible priority (`MaxInt`) to handle
|
||||
ACME HTTP and TLS challenges. This ensures that certificate challenges always succeed,
|
||||
but it also prevents any user-defined router from intercepting challenge requests on the same entrypoint.
|
||||
|
||||
When `allowACMEByPass` is set to `true` on an entrypoint:
|
||||
|
||||
- The internal ACME HTTP challenge router is created **without** an explicit high priority,
|
||||
allowing user-defined routers to handle challenge requests instead.
|
||||
- The TLS-ALPN challenge passthrough is enabled on the entrypoint,
|
||||
allowing user-defined TLS routers to handle TLS challenges.
|
||||
|
||||
This is useful when you need custom handling of ACME challenges,
|
||||
for example when using a dedicated service to solve HTTP-01 or TLS-ALPN-01 challenges.
|
||||
|
||||
!!! note
|
||||
|
||||
When no TLS challenge resolver is configured, `allowACMEByPass` is implicitly enabled
|
||||
for TLS passthrough on all entrypoints.
|
||||
|
||||
!!! note
|
||||
|
||||
When `allowACMEByPass` is enabled and the entrypoint has an HTTP redirect configured
|
||||
(via `http.redirections.entryPoint`), the redirect router automatically excludes
|
||||
the ACME challenge path (`/.well-known/acme-challenge/`).
|
||||
This allows user-defined ACME challenge routers to handle challenge requests
|
||||
without being overridden by the redirect.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
allowACMEByPass: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
allowACMEByPass = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.allowACMEByPass=true
|
||||
```
|
||||
|
||||
### http.middlewares
|
||||
|
||||
- You can attach a list of [middlewares](../../middlewares/http/overview.md)
|
||||
|
||||
@@ -229,8 +229,8 @@ Negative priority values are supported.
|
||||
|
||||
Traefik 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.
|
||||
- `(MaxInt32 - 1000)` = `2147482647` for 32-bit platforms,
|
||||
- `(MaxInt64 - 1000)` = `9223372036854774807` for 64-bit platforms.
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
noColor = true
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8888"
|
||||
allowACMEByPass = true
|
||||
[entryPoints.web.http.redirections.entryPoint]
|
||||
to = ":8443"
|
||||
scheme = "https"
|
||||
|
||||
[entryPoints.websecure]
|
||||
address = ":8443"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
## dynamic configuration ##
|
||||
|
||||
[http.routers]
|
||||
[http.routers.acme-challenge]
|
||||
entryPoints = ["web"]
|
||||
rule = "PathPrefix(`/.well-known/acme-challenge/`)"
|
||||
service = "acme-solver"
|
||||
|
||||
[http.services]
|
||||
[http.services.acme-solver]
|
||||
[http.services.acme-solver.loadBalancer]
|
||||
[[http.services.acme-solver.loadBalancer.servers]]
|
||||
url = "{{ .AcmeSolverURL }}"
|
||||
@@ -2227,3 +2227,40 @@ func waitForWritePartial(t *testing.T, conn net.Conn) {
|
||||
t.Fatalf("timeout waiting for connection timeout")
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestAllowACMEByPassRedirect() {
|
||||
// Start a local server that simulates an ACME challenge solver.
|
||||
acmeSolver := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
rw.WriteHeader(http.StatusOK)
|
||||
_, _ = rw.Write([]byte("acme-challenge-token"))
|
||||
}))
|
||||
defer acmeSolver.Close()
|
||||
|
||||
file := s.adaptFile("fixtures/simple_acme_bypass_redirect.toml", struct {
|
||||
AcmeSolverURL string
|
||||
}{
|
||||
AcmeSolverURL: acmeSolver.URL,
|
||||
})
|
||||
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
// Wait for Traefik to be ready with the user-defined ACME challenge router.
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 5*time.Second, try.BodyContains("acme-challenge@file"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
noRedirectClient := &http.Client{
|
||||
CheckRedirect: func(req *http.Request, via []*http.Request) error {
|
||||
return http.ErrUseLastResponse
|
||||
},
|
||||
}
|
||||
|
||||
// ACME challenge path should NOT be redirected — it should reach the solver.
|
||||
resp, err := noRedirectClient.Get("http://127.0.0.1:8888/.well-known/acme-challenge/test-token")
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusOK, resp.StatusCode)
|
||||
|
||||
// Normal path should be redirected to HTTPS.
|
||||
resp, err = noRedirectClient.Get("http://127.0.0.1:8888/other-path")
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusMovedPermanently, resp.StatusCode)
|
||||
}
|
||||
|
||||
@@ -17,8 +17,9 @@ import (
|
||||
type routerRepresentation struct {
|
||||
*runtime.RouterInfo
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
PriorityStr string `json:"priorityStr,omitempty"`
|
||||
}
|
||||
|
||||
func newRouterRepresentation(name string, rt *runtime.RouterInfo) routerRepresentation {
|
||||
@@ -27,9 +28,10 @@ func newRouterRepresentation(name string, rt *runtime.RouterInfo) routerRepresen
|
||||
}
|
||||
|
||||
return routerRepresentation{
|
||||
RouterInfo: rt,
|
||||
Name: name,
|
||||
Provider: getProviderName(name),
|
||||
RouterInfo: rt,
|
||||
Name: name,
|
||||
Provider: getProviderName(name),
|
||||
PriorityStr: strconv.FormatInt(int64(rt.Priority), 10),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,9 @@ import (
|
||||
type tcpRouterRepresentation struct {
|
||||
*runtime.TCPRouterInfo
|
||||
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Provider string `json:"provider,omitempty"`
|
||||
PriorityStr string `json:"priorityStr,omitempty"`
|
||||
}
|
||||
|
||||
func newTCPRouterRepresentation(name string, rt *runtime.TCPRouterInfo) tcpRouterRepresentation {
|
||||
@@ -25,6 +26,7 @@ func newTCPRouterRepresentation(name string, rt *runtime.TCPRouterInfo) tcpRoute
|
||||
TCPRouterInfo: rt,
|
||||
Name: name,
|
||||
Provider: getProviderName(name),
|
||||
PriorityStr: strconv.FormatInt(int64(rt.Priority), 10),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
@@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.baz`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"tls": {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.baz`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"tls": {
|
||||
|
||||
+1
@@ -8,6 +8,7 @@
|
||||
],
|
||||
"name": "foo / bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "disabled",
|
||||
@@ -26,6 +27,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.bar.other`)",
|
||||
"service": "fii-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.bar.other`)",
|
||||
"service": "fii-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "foo@otherprovider",
|
||||
"provider": "otherprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.foo.other`)",
|
||||
"service": "fii-service",
|
||||
"status": "enabled",
|
||||
@@ -22,6 +23,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`fii.bar.other`)",
|
||||
"service": "fii-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
+5
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar14@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar14`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@@ -18,6 +19,7 @@
|
||||
],
|
||||
"name": "bar15@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar15`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@@ -31,6 +33,7 @@
|
||||
],
|
||||
"name": "bar16@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar16`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@@ -44,6 +47,7 @@
|
||||
],
|
||||
"name": "bar17@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar17`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@@ -57,6 +61,7 @@
|
||||
],
|
||||
"name": "bar18@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar18`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
Vendored
+1
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`toto.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
Vendored
+2
@@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
@@ -26,6 +27,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
Vendored
+1
@@ -4,6 +4,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
],
|
||||
"name": "foo / bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service",
|
||||
"status": "warning",
|
||||
@@ -26,6 +27,7 @@
|
||||
],
|
||||
"name": "foo@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "bar-service@myprovider",
|
||||
"status": "disabled",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "warning",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service",
|
||||
"status": "warning",
|
||||
@@ -18,6 +19,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
+1
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "baz@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`toto.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
Vendored
+3
@@ -5,6 +5,7 @@
|
||||
],
|
||||
"name": "bar@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "warning",
|
||||
@@ -18,6 +19,7 @@
|
||||
],
|
||||
"name": "foo@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "disabled",
|
||||
@@ -31,6 +33,7 @@
|
||||
],
|
||||
"name": "test@myprovider",
|
||||
"provider": "myprovider",
|
||||
"priorityStr": "0",
|
||||
"rule": "Host(`foo.bar.other`)",
|
||||
"service": "foo-service@myprovider",
|
||||
"status": "enabled",
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"http": {
|
||||
"routers": {
|
||||
"web-to-websecure": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"middlewares": [
|
||||
"redirect-web-to-websecure"
|
||||
],
|
||||
"service": "noop@internal",
|
||||
"rule": "HostRegexp(`^.+$`) \u0026\u0026 !PathPrefix(`/.well-known/acme-challenge/`)",
|
||||
"ruleSyntax": "default"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"noop": {}
|
||||
},
|
||||
"middlewares": {
|
||||
"redirect-web-to-websecure": {
|
||||
"redirectScheme": {
|
||||
"scheme": "https",
|
||||
"port": "443",
|
||||
"permanent": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
"tls": {}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"http": {
|
||||
"routers": {
|
||||
"acme-http": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"service": "acme-http@internal",
|
||||
"rule": "PathPrefix(`/.well-known/acme-challenge/`)",
|
||||
"ruleSyntax": "default",
|
||||
"priority": 9223372036854775807
|
||||
},
|
||||
"web-to-websecure": {
|
||||
"entryPoints": [
|
||||
"web"
|
||||
],
|
||||
"middlewares": [
|
||||
"redirect-web-to-websecure"
|
||||
],
|
||||
"service": "noop@internal",
|
||||
"rule": "HostRegexp(`^.+$`)",
|
||||
"ruleSyntax": "default"
|
||||
}
|
||||
},
|
||||
"services": {
|
||||
"acme-http": {},
|
||||
"noop": {}
|
||||
},
|
||||
"middlewares": {
|
||||
"redirect-web-to-websecure": {
|
||||
"redirectScheme": {
|
||||
"scheme": "https",
|
||||
"port": "443",
|
||||
"permanent": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tcp": {},
|
||||
"tls": {}
|
||||
}
|
||||
@@ -161,11 +161,16 @@ func (i *Provider) redirection(ctx context.Context, cfg *dynamic.Configuration)
|
||||
continue
|
||||
}
|
||||
|
||||
rule := "HostRegexp(`^.+$`)"
|
||||
if ep.AllowACMEByPass {
|
||||
rule = "HostRegexp(`^.+$`) && !PathPrefix(`/.well-known/acme-challenge/`)"
|
||||
}
|
||||
|
||||
rtName := provider.Normalize(name + "-to-" + def.EntryPoint.To)
|
||||
mdName := "redirect-" + rtName
|
||||
|
||||
rt := &dynamic.Router{
|
||||
Rule: "HostRegexp(`^.+$`)",
|
||||
Rule: rule,
|
||||
// "default" stands for the default rule syntax in Traefik v3, i.e. the v3 syntax.
|
||||
RuleSyntax: "default",
|
||||
EntryPoints: []string{name},
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/traefik/traefik/v3/pkg/config/static"
|
||||
otypes "github.com/traefik/traefik/v3/pkg/observability/types"
|
||||
"github.com/traefik/traefik/v3/pkg/ping"
|
||||
acmeprovider "github.com/traefik/traefik/v3/pkg/provider/acme"
|
||||
"github.com/traefik/traefik/v3/pkg/provider/rest"
|
||||
"github.com/traefik/traefik/v3/pkg/types"
|
||||
)
|
||||
@@ -261,6 +262,60 @@ func Test_createConfiguration(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "redirection_with_acme_bypass.json",
|
||||
staticCfg: static.Configuration{
|
||||
EntryPoints: map[string]*static.EntryPoint{
|
||||
"web": {
|
||||
Address: ":80",
|
||||
AllowACMEByPass: true,
|
||||
HTTP: static.HTTPConfig{
|
||||
Redirections: &static.Redirections{
|
||||
EntryPoint: &static.RedirectEntryPoint{
|
||||
To: "websecure",
|
||||
Scheme: "https",
|
||||
Permanent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"websecure": {
|
||||
Address: ":443",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
desc: "redirection_without_acme_bypass.json",
|
||||
staticCfg: static.Configuration{
|
||||
EntryPoints: map[string]*static.EntryPoint{
|
||||
"web": {
|
||||
Address: ":80",
|
||||
HTTP: static.HTTPConfig{
|
||||
Redirections: &static.Redirections{
|
||||
EntryPoint: &static.RedirectEntryPoint{
|
||||
To: "websecure",
|
||||
Scheme: "https",
|
||||
Permanent: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"websecure": {
|
||||
Address: ":443",
|
||||
},
|
||||
},
|
||||
CertificatesResolvers: map[string]static.CertificateResolver{
|
||||
"default": {
|
||||
ACME: &acmeprovider.Configuration{
|
||||
HTTPChallenge: &acmeprovider.HTTPChallenge{
|
||||
EntryPoint: "web",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
|
||||
@@ -27,10 +27,10 @@ const RouterPanel = ({ data }: Props) => (
|
||||
<ProviderName css={{ ml: '$2' }}>{data.provider}</ProviderName>
|
||||
</ItemBlock>
|
||||
)}
|
||||
{data.priority && (
|
||||
{(data.priorityStr || data.priority) && (
|
||||
<ItemBlock title="Priority">
|
||||
<Tooltip label={data.priority.toString()} action="copy">
|
||||
<Text css={{ overflowWrap: 'break-word' }}>{data.priority.toString()}</Text>
|
||||
<Tooltip label={data.priorityStr ?? data.priority?.toString() ?? ''} action="copy">
|
||||
<Text css={{ overflowWrap: 'break-word' }}>{data.priorityStr ?? data.priority?.toString()}</Text>
|
||||
</Tooltip>
|
||||
</ItemBlock>
|
||||
)}
|
||||
|
||||
@@ -36,6 +36,7 @@ type Router = {
|
||||
status: 'enabled' | 'disabled' | 'warning'
|
||||
rule?: string
|
||||
priority?: number
|
||||
priorityStr?: string
|
||||
provider: string
|
||||
tls?: {
|
||||
options: string
|
||||
@@ -141,6 +142,8 @@ export const useResourceDetail = (name: string, resource: string, protocol = 'ht
|
||||
status: routeDetail.status,
|
||||
provider: routeDetail.provider,
|
||||
rule: routeDetail.rule,
|
||||
priority: routeDetail.priority,
|
||||
priorityStr: routeDetail.priorityStr,
|
||||
tls: routeDetail.tls,
|
||||
error: routeDetail.error,
|
||||
middlewares: validMiddlewares,
|
||||
|
||||
@@ -108,7 +108,8 @@
|
||||
"using": [
|
||||
"web-redirect"
|
||||
],
|
||||
"priority": 9223372036854776000,
|
||||
"priority": 9223372036854775806,
|
||||
"priorityStr": "9223372036854775806",
|
||||
"provider": "docker"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -59,7 +59,7 @@ export const makeRowRender = (protocol = 'http'): RenderRowType => {
|
||||
</Tooltip>
|
||||
</AriaTd>
|
||||
<AriaTd>
|
||||
<TooltipText text={row.priority} isTruncated />
|
||||
<TooltipText text={row.priorityStr ?? row.priority} isTruncated />
|
||||
</AriaTd>
|
||||
</ClickableRow>
|
||||
)
|
||||
|
||||
@@ -55,7 +55,7 @@ export const makeRowRender = (): RenderRowType => {
|
||||
</Tooltip>
|
||||
</AriaTd>
|
||||
<AriaTd>
|
||||
<TooltipText text={row.priority} isTruncated />
|
||||
<TooltipText text={row.priorityStr ?? row.priority} isTruncated />
|
||||
</AriaTd>
|
||||
</ClickableRow>
|
||||
)
|
||||
|
||||
@@ -42,7 +42,7 @@ export const makeRowRender = (): RenderRowType => {
|
||||
</Tooltip>
|
||||
</AriaTd>
|
||||
<AriaTd>
|
||||
<TooltipText text={row.priority} isTruncated />
|
||||
<TooltipText text={row.priorityStr ?? row.priority} isTruncated />
|
||||
</AriaTd>
|
||||
</ClickableRow>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user