From dce807a329c55ceacc0560210583617463e2964b Mon Sep 17 00:00:00 2001 From: Brad Jones Date: Tue, 26 May 2020 08:56:04 -0600 Subject: [PATCH 01/12] Use "headers" instead of "header" in access log docs --- docs/content/observability/access-logs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/content/observability/access-logs.md b/docs/content/observability/access-logs.md index c09a8ebf4..0c54d485d 100644 --- a/docs/content/observability/access-logs.md +++ b/docs/content/observability/access-logs.md @@ -111,9 +111,9 @@ accessLog: --accesslog.filters.minduration=10ms ``` -### Limiting the Fields +### Limiting the Fields/Including Headers -You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.header` options +You can decide to limit the logged fields/headers to a given list with the `fields.names` and `fields.headers` options. Each field can be set to: @@ -121,7 +121,7 @@ Each field can be set to: - `drop` to drop the value - `redact` to replace the value with "redacted" -The `defaultMode` for `fields.header` is `drop`. +The `defaultMode` for `fields.headers` is `drop`. ```toml tab="File (TOML)" # Limiting the Logs to Specific Fields From 8c5846c4784cc381708ec757f5527729be7cb996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20B=C3=A1rta?= Date: Tue, 26 May 2020 21:54:03 +0200 Subject: [PATCH 02/12] Fix healthcheck.interval in docs --- docs/content/routing/providers/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/routing/providers/docker.md b/docs/content/routing/providers/docker.md index 46fa35f66..e19aafaa5 100644 --- a/docs/content/routing/providers/docker.md +++ b/docs/content/routing/providers/docker.md @@ -291,7 +291,7 @@ you'd add the label `traefik.http.services..loadbalancer.pa See [health check](../services/index.md#health-check) for more information. ```yaml - - "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10" + - "traefik.http.services.myservice.loadbalancer.healthcheck.interval=10s" ``` ??? info "`traefik.http.services..loadbalancer.healthcheck.path`" From f874c389bd68fb5b8008a2b77c66373b936cee3c Mon Sep 17 00:00:00 2001 From: Sergio Maria Matone Date: Wed, 27 May 2020 17:48:04 +0200 Subject: [PATCH 03/12] fixing typo in Provider KubernetesIngress at Routing documentation --- docs/content/routing/providers/kubernetes-ingress.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/routing/providers/kubernetes-ingress.md b/docs/content/routing/providers/kubernetes-ingress.md index 95622b002..3fcd8af7f 100644 --- a/docs/content/routing/providers/kubernetes-ingress.md +++ b/docs/content/routing/providers/kubernetes-ingress.md @@ -202,7 +202,7 @@ which in turn will create the resulting routers, services, handlers, etc. See [middlewares](../routers/index.md#middlewares) and [middlewares overview](../../middlewares/overview.md) for more information. ```yaml - traefik.ingress.kubernetes.io/router.middlewares: auth@file,prefix@kuberntescrd,cb@file + traefik.ingress.kubernetes.io/router.middlewares: auth@file,prefix@kubernetescrd,cb@file ``` ??? info "`traefik.ingress.kubernetes.io/router.priority`" From a1270d6cc7e2d24f3d461c13d3e628285889b969 Mon Sep 17 00:00:00 2001 From: Bo Jeanes Date: Fri, 29 May 2020 03:58:04 +1000 Subject: [PATCH 04/12] Use specified network for "container" network mode --- pkg/provider/docker/config.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/pkg/provider/docker/config.go b/pkg/provider/docker/config.go index dc7eb4f95..1f35e7897 100644 --- a/pkg/provider/docker/config.go +++ b/pkg/provider/docker/config.go @@ -345,7 +345,23 @@ func (p Provider) getIPAddress(ctx context.Context, container dockerData) string logger.Warnf("Unable to get IP address for container %s : Failed to inspect container ID %s, error: %s", container.Name, connectedContainer, err) return "" } - return p.getIPAddress(ctx, parseContainer(containerInspected)) + + // Check connected container for traefik.docker.network, falling back to + // the network specified on the current container. + containerParsed := parseContainer(containerInspected) + extraConf, err := p.getConfiguration(containerParsed) + + if err != nil { + logger.Warnf("Unable to get IP address for container %s : failed to get extra configuration for container %s: %s", container.Name, containerInspected.Name, err) + return "" + } + + if extraConf.Docker.Network == "" { + extraConf.Docker.Network = container.ExtraConf.Docker.Network + } + + containerParsed.ExtraConf = extraConf + return p.getIPAddress(ctx, containerParsed) } for _, network := range container.NetworkSettings.Networks { From b7fe55b6be5757830827b70a58d321b0e3b77341 Mon Sep 17 00:00:00 2001 From: Ludovic Fernandez Date: Wed, 3 Jun 2020 16:22:04 +0200 Subject: [PATCH 05/12] fix: dead link. --- docs/content/middlewares/headers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/middlewares/headers.md b/docs/content/middlewares/headers.md index cd9072a0c..c9740d917 100644 --- a/docs/content/middlewares/headers.md +++ b/docs/content/middlewares/headers.md @@ -311,7 +311,7 @@ This value can contains a list of allowed origins. More information including how to use the settings can be found on: - [Mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin) -- [w3](https://www.w3.org/TR/cors/#access-control-allow-origin-response-header) +- [w3](https://fetch.spec.whatwg.org/#http-access-control-allow-origin) - [IETF](https://tools.ietf.org/html/rfc6454#section-7.1) Traefik no longer supports the null value, as it is [no longer recommended as a return value](https://w3c.github.io/webappsec-cors-for-developers/#avoid-returning-access-control-allow-origin-null). From 12e462f383efc6c14a98933b0df34f67f8a7e6b1 Mon Sep 17 00:00:00 2001 From: Rick Herrick Date: Wed, 3 Jun 2020 10:24:04 -0500 Subject: [PATCH 06/12] Update kubernetes-crd.md --- .../routing/providers/kubernetes-crd.md | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/docs/content/routing/providers/kubernetes-crd.md b/docs/content/routing/providers/kubernetes-crd.md index f07d50573..7201fa994 100644 --- a/docs/content/routing/providers/kubernetes-crd.md +++ b/docs/content/routing/providers/kubernetes-crd.md @@ -108,24 +108,24 @@ The Kubernetes Ingress Controller, The Custom Resource Way. name: myingressroute namespace: default - spec: - entryPoints: - - web + spec: + entryPoints: + - web - routes: - - match: Host(`foo`) && PathPrefix(`/bar`) - kind: Rule - services: - - name: whoami - port: 80 + routes: + - match: Host(`foo`) && PathPrefix(`/bar`) + kind: Rule + services: + - name: whoami + port: 80 --- apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRouteTCP - metadata: - name: ingressroute.tcp + kind: IngressRouteTCP + metadata: + name: ingressroute.tcp namespace: default - + spec: entryPoints: - tcpep @@ -135,22 +135,22 @@ The Kubernetes Ingress Controller, The Custom Resource Way. services: - name: whoamitcp port: 8080 - + --- apiVersion: traefik.containo.us/v1alpha1 - kind: IngressRouteUDP - metadata: - name: ingressroute.udp - namespace: default - - spec: - entryPoints: - - fooudp - routes: - - kind: Rule - services: - - name: whoamiudp - port: 8080 + kind: IngressRouteUDP + metadata: + name: ingressroute.udp + namespace: default + + spec: + entryPoints: + - fooudp + routes: + - kind: Rule + services: + - name: whoamiudp + port: 8080 ``` ```yaml tab="Whoami" From 48c73d6a34add5160c203a201ed38250d736f362 Mon Sep 17 00:00:00 2001 From: Douglas De Toni Machado Date: Thu, 4 Jun 2020 06:04:04 -0300 Subject: [PATCH 07/12] Fix mem leak on UDP connections --- pkg/udp/conn.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pkg/udp/conn.go b/pkg/udp/conn.go index 0fec8ce04..516212ec2 100644 --- a/pkg/udp/conn.go +++ b/pkg/udp/conn.go @@ -177,7 +177,7 @@ func (l *Listener) newConn(rAddr net.Addr) *Conn { readCh: make(chan []byte), sizeCh: make(chan int), doneCh: make(chan struct{}), - ticker: time.NewTicker(timeoutTicker), + timeout: timeoutTicker, } } @@ -194,7 +194,7 @@ type Conn struct { muActivity sync.RWMutex lastActivity time.Time // the last time the session saw either read or write activity - ticker *time.Ticker // for timeouts + timeout time.Duration // for timeouts doneOnce sync.Once doneCh chan struct{} } @@ -204,12 +204,15 @@ type Conn struct { // that is to say it waits on readCh to receive the slice of bytes that the Read operation wants to read onto. // The Read operation receives the signal that the data has been written to the slice of bytes through the sizeCh. func (c *Conn) readLoop() { + ticker := time.NewTicker(c.timeout) + defer ticker.Stop() + for { if len(c.msgs) == 0 { select { case msg := <-c.receiveCh: c.msgs = append(c.msgs, msg) - case <-c.ticker.C: + case <-ticker.C: c.muActivity.RLock() deadline := c.lastActivity.Add(connTimeout) c.muActivity.RUnlock() @@ -229,7 +232,7 @@ func (c *Conn) readLoop() { c.sizeCh <- n case msg := <-c.receiveCh: c.msgs = append(c.msgs, msg) - case <-c.ticker.C: + case <-ticker.C: c.muActivity.RLock() deadline := c.lastActivity.Add(connTimeout) c.muActivity.RUnlock() @@ -281,6 +284,5 @@ func (c *Conn) Close() error { c.listener.mu.Lock() defer c.listener.mu.Unlock() delete(c.listener.conns, c.rAddr.String()) - c.ticker.Stop() return nil } From fb90a7889adfbc38f5351b2cb9729816fddffc33 Mon Sep 17 00:00:00 2001 From: Romain Date: Mon, 8 Jun 2020 13:30:03 +0200 Subject: [PATCH 08/12] Fix doc url for Aurora DNS provider --- docs/content/https/acme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/https/acme.md b/docs/content/https/acme.md index dddd74fbc..ef2a27310 100644 --- a/docs/content/https/acme.md +++ b/docs/content/https/acme.md @@ -282,7 +282,7 @@ For example, `CF_API_EMAIL_FILE=/run/secrets/traefik_cf-api-email` could be used |-------------------------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------| | [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) | | [Alibaba Cloud](https://www.alibabacloud.com) | `alidns` | `ALICLOUD_ACCESS_KEY`, `ALICLOUD_SECRET_KEY`, `ALICLOUD_REGION_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/alidns) | -| [Auroradns](https://www.pcextreme.com/aurora/dns) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | +| [Auroradns](https://www.pcextreme.com/dns-health-checks) | `auroradns` | `AURORA_USER_ID`, `AURORA_KEY`, `AURORA_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/auroradns) | | [Autodns](https://www.internetx.com/domains/autodns/) | `autodns` | `AUTODNS_API_USER`, `AUTODNS_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/autodns) | | [Azure](https://azure.microsoft.com/services/dns/) | `azure` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_SUBSCRIPTION_ID`, `AZURE_TENANT_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_METADATA_ENDPOINT]` | [Additional configuration](https://go-acme.github.io/lego/dns/azure) | | [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) | From 0d902671e509f52390163035e89c89f89296150e Mon Sep 17 00:00:00 2001 From: cbachert Date: Mon, 8 Jun 2020 17:12:04 +0100 Subject: [PATCH 09/12] Avoid overwriting already received UDP messages --- pkg/udp/conn.go | 6 +++-- pkg/udp/conn_test.go | 61 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/pkg/udp/conn.go b/pkg/udp/conn.go index 516212ec2..9aef31f2a 100644 --- a/pkg/udp/conn.go +++ b/pkg/udp/conn.go @@ -128,9 +128,11 @@ func (l *Listener) Shutdown(graceTimeout time.Duration) error { // we find that session, and otherwise we create a new one. // We then send the data the session's readLoop. func (l *Listener) readLoop() { - buf := make([]byte, receiveMTU) - for { + // Allocating a new buffer for every read avoids + // overwriting data in c.msgs in case the next packet is received + // before c.msgs is emptied via Read() + buf := make([]byte, receiveMTU) n, raddr, err := l.pConn.ReadFrom(buf) if err != nil { return diff --git a/pkg/udp/conn_test.go b/pkg/udp/conn_test.go index 91d3fe571..62c35d04a 100644 --- a/pkg/udp/conn_test.go +++ b/pkg/udp/conn_test.go @@ -10,6 +10,67 @@ import ( "github.com/stretchr/testify/require" ) +func TestConsecutiveWrites(t *testing.T) { + addr, err := net.ResolveUDPAddr("udp", ":0") + require.NoError(t, err) + + ln, err := Listen("udp", addr) + require.NoError(t, err) + defer func() { + err := ln.Close() + require.NoError(t, err) + }() + + go func() { + for { + conn, err := ln.Accept() + if err == errClosedListener { + return + } + require.NoError(t, err) + + go func() { + b := make([]byte, 2048) + b2 := make([]byte, 2048) + var n int + var n2 int + + n, err = conn.Read(b) + require.NoError(t, err) + // Wait to make sure that the second packet is received + time.Sleep(10 * time.Millisecond) + n2, err = conn.Read(b2) + require.NoError(t, err) + + _, err = conn.Write(b[:n]) + require.NoError(t, err) + _, err = conn.Write(b2[:n2]) + require.NoError(t, err) + }() + } + }() + + udpConn, err := net.Dial("udp", ln.Addr().String()) + require.NoError(t, err) + + // Send multiple packets of different content and length consecutively + // Read back packets afterwards and make sure that content matches + // This checks if any buffers are overwritten while the receiver is enqueuing multiple packets + b := make([]byte, 2048) + var n int + _, err = udpConn.Write([]byte("TESTLONG0")) + require.NoError(t, err) + _, err = udpConn.Write([]byte("1TEST")) + require.NoError(t, err) + + n, err = udpConn.Read(b) + require.NoError(t, err) + require.Equal(t, "TESTLONG0", string(b[:n])) + n, err = udpConn.Read(b) + require.NoError(t, err) + require.Equal(t, "1TEST", string(b[:n])) +} + func TestListenNotBlocking(t *testing.T) { addr, err := net.ResolveUDPAddr("udp", ":0") From 7694ff1761fba21768f16a5760a3b900fb51d5c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Franti=C5=A1ek=20H=C3=A1na?= Date: Tue, 9 Jun 2020 12:18:04 +0200 Subject: [PATCH 10/12] Fix v1-> v2 migration: unify domain name in documentation example --- docs/content/migration/v1-to-v2.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/migration/v1-to-v2.md b/docs/content/migration/v1-to-v2.md index 2a7006add..ea680a746 100644 --- a/docs/content/migration/v1-to-v2.md +++ b/docs/content/migration/v1-to-v2.md @@ -97,7 +97,7 @@ Then any router can refer to an instance of the wanted middleware. ```yaml tab="Docker" labels: - - "traefik.http.routers.router0.rule=Host(`example.com`) && PathPrefix(`/test`)" + - "traefik.http.routers.router0.rule=Host(`test.localhost`) && PathPrefix(`/test`)" - "traefik.http.routers.router0.middlewares=auth" - "traefik.http.middlewares.auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0" ``` From c0c540dc09ea3bbb3258813c6a372f3dc77745e9 Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Doumenjou Date: Wed, 10 Jun 2020 12:22:04 +0200 Subject: [PATCH 11/12] fix a broken link on Docker plugins documentation --- docs/content/providers/docker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/content/providers/docker.md b/docs/content/providers/docker.md index 968bb11a8..35c1ed0b4 100644 --- a/docs/content/providers/docker.md +++ b/docs/content/providers/docker.md @@ -154,7 +154,7 @@ You can specify which Docker API Endpoint to use with the directive [`endpoint`] - Authentication with Client Certificates as described in ["Protect the Docker daemon socket."](https://docs.docker.com/engine/security/https/) - Authorize and filter requests to restrict possible actions with [the TecnativaDocker Socket Proxy](https://github.com/Tecnativa/docker-socket-proxy). - - Authorization with the [Docker Authorization Plugin Mechanism](https://docs.docker.com/engine/extend/plugins_authorization/) + - Authorization with the [Docker Authorization Plugin Mechanism](https://web.archive.org/web/20190920092526/https://docs.docker.com/engine/extend/plugins_authorization/) - Accounting at networking level, by exposing the socket only inside a Docker private network, only available for Traefik. - Accounting at container level, by exposing the socket on a another container than Traefik's. With Swarm mode, it allows scheduling of Traefik on worker nodes, with only the "socket exposer" container on the manager nodes. From b0f7b7145352c89f5cec5fbe0c5e5d9ec54a5b2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Christian=20Gr=C3=BCnhage?= Date: Wed, 10 Jun 2020 14:32:03 +0200 Subject: [PATCH 12/12] refactor X-Forwarded-Proto --- .../forwardedheaders/forwarded_header.go | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pkg/middlewares/forwardedheaders/forwarded_header.go b/pkg/middlewares/forwardedheaders/forwarded_header.go index 4d796c55d..4bbae8a95 100644 --- a/pkg/middlewares/forwardedheaders/forwarded_header.go +++ b/pkg/middlewares/forwardedheaders/forwarded_header.go @@ -132,18 +132,18 @@ func (x *XForwarded) rewrite(outreq *http.Request) { xfProto := outreq.Header.Get(xForwardedProto) if xfProto == "" { - if outreq.TLS != nil { - outreq.Header.Set(xForwardedProto, "https") + if isWebsocketRequest(outreq) { + if outreq.TLS != nil { + outreq.Header.Set(xForwardedProto, "wss") + } else { + outreq.Header.Set(xForwardedProto, "ws") + } } else { - outreq.Header.Set(xForwardedProto, "http") - } - } - - if isWebsocketRequest(outreq) { - if outreq.Header.Get(xForwardedProto) == "https" || outreq.Header.Get(xForwardedProto) == "wss" { - outreq.Header.Set(xForwardedProto, "wss") - } else { - outreq.Header.Set(xForwardedProto, "ws") + if outreq.TLS != nil { + outreq.Header.Set(xForwardedProto, "https") + } else { + outreq.Header.Set(xForwardedProto, "http") + } } }