mirror of
https://github.com/containous/traefik.git
synced 2025-12-04 20:23:52 +03:00
Compare commits
112 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63a6172ec4 | ||
|
|
4d7d627319 | ||
|
|
0b6438b7c0 | ||
|
|
e15c11961f | ||
|
|
042feacf3e | ||
|
|
759e82c3c8 | ||
|
|
2d7262515d | ||
|
|
f3e199cd47 | ||
|
|
9232535cf6 | ||
|
|
79bb320f4c | ||
|
|
058b194604 | ||
|
|
effca0a603 | ||
|
|
998868450f | ||
|
|
ffd82c92cb | ||
|
|
34d7091f31 | ||
|
|
b04759a80b | ||
|
|
8441c476f1 | ||
|
|
4ff8eca572 | ||
|
|
1986610363 | ||
|
|
5cc2a8344c | ||
|
|
fc5359b6f6 | ||
|
|
c5d448fba9 | ||
|
|
c820d18ada | ||
|
|
19a2e2efc5 | ||
|
|
bcdb70b689 | ||
|
|
9896192efb | ||
|
|
c6daab54e3 | ||
|
|
a59bcb29b5 | ||
|
|
50931813f2 | ||
|
|
5ef853a0c5 | ||
|
|
b2b4b66b08 | ||
|
|
27326e6569 | ||
|
|
7ca90a4b18 | ||
|
|
a3685ee9fa | ||
|
|
8ae0379171 | ||
|
|
b0d8e08e2b | ||
|
|
ae79d4e5f0 | ||
|
|
bfcef58a4f | ||
|
|
f7a6f32784 | ||
|
|
92f798dfcd | ||
|
|
f174014d96 | ||
|
|
cd16321dd9 | ||
|
|
5f35c88805 | ||
|
|
23c7c78a1a | ||
|
|
08d5dfee01 | ||
|
|
b669981018 | ||
|
|
aa5f2b92d4 | ||
|
|
6b9738e675 | ||
|
|
b82290ac5b | ||
|
|
49b598d087 | ||
|
|
448785d830 | ||
|
|
9bc71b0010 | ||
|
|
160edff257 | ||
|
|
8816cb86a4 | ||
|
|
316be0782c | ||
|
|
14da838a21 | ||
|
|
a75b2384ea | ||
|
|
8bdca45861 | ||
|
|
7442162e3f | ||
|
|
dd5cb68cb1 | ||
|
|
299a16f0a4 | ||
|
|
545f2feacc | ||
|
|
e3caaf0791 | ||
|
|
f794f8a294 | ||
|
|
8cf22207b5 | ||
|
|
b7be71c02a | ||
|
|
6e9d713668 | ||
|
|
ddb32ef86f | ||
|
|
2087e11f55 | ||
|
|
a5d46fc6ef | ||
|
|
84742275a4 | ||
|
|
54a2d657f3 | ||
|
|
08b90ade94 | ||
|
|
8ba99adc50 | ||
|
|
b02946147d | ||
|
|
137c632793 | ||
|
|
e76b65f44d | ||
|
|
55ebaee4a7 | ||
|
|
4ff76e13c4 | ||
|
|
14e400bcd0 | ||
|
|
7cfd10db62 | ||
|
|
9d8a42111f | ||
|
|
0dfd12ee61 | ||
|
|
a3fd484728 | ||
|
|
f196de90e1 | ||
|
|
c2a294c872 | ||
|
|
8e5d4c6ae9 | ||
|
|
eb07a5ca1a | ||
|
|
84e20aa9c3 | ||
|
|
4e441d09ed | ||
|
|
8f5dd7bd9d | ||
|
|
86315e0f18 | ||
|
|
c20af070e3 | ||
|
|
8593581cbf | ||
|
|
8103992977 | ||
|
|
c5b92b5260 | ||
|
|
c19cf125e8 | ||
|
|
435d28c790 | ||
|
|
8272be0eda | ||
|
|
d2414feaff | ||
|
|
1aa450c028 | ||
|
|
f9ff6049d3 | ||
|
|
ee8305549a | ||
|
|
a31b026364 | ||
|
|
20d496268c | ||
|
|
5f3c30e37b | ||
|
|
38ac1e75a2 | ||
|
|
109a8712cc | ||
|
|
278e739242 | ||
|
|
db31a4c961 | ||
|
|
35ce6baaae | ||
|
|
95f20fc753 |
5
.github/workflows/build.yaml
vendored
5
.github/workflows/build.yaml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
@@ -51,7 +51,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -61,6 +61,7 @@ jobs:
|
||||
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Artifact webui
|
||||
uses: actions/download-artifact@v4
|
||||
|
||||
2
.github/workflows/check_doc.yml
vendored
2
.github/workflows/check_doc.yml
vendored
@@ -13,7 +13,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
2
.github/workflows/codeql.yml
vendored
2
.github/workflows/codeql.yml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: setup go
|
||||
uses: actions/setup-go@v5
|
||||
|
||||
9
.github/workflows/documentation.yml
vendored
9
.github/workflows/documentation.yml
vendored
@@ -1,6 +1,7 @@
|
||||
name: Build and Publish Documentation
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
@@ -19,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -39,9 +40,9 @@ jobs:
|
||||
run: curl -sSfL https://raw.githubusercontent.com/traefik/mixtus/master/godownloader.sh | sh -s -- -b $HOME/bin ${MIXTUS_VERSION}
|
||||
|
||||
- name: Build documentation
|
||||
run: $HOME/bin/structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug
|
||||
env:
|
||||
STRUCTOR_LATEST_TAG: ${{ vars.STRUCTOR_LATEST_TAG }}
|
||||
run: |
|
||||
STRUCTOR_LATEST_TAG=$(curl -s https://api.github.com/repos/traefik/traefik/releases/latest | jq -r '.tag_name')
|
||||
$HOME/bin/structor -o traefik -r traefik --dockerfile-url="https://raw.githubusercontent.com/traefik/traefik/v1.7/docs.Dockerfile" --menu.js-url="https://raw.githubusercontent.com/traefik/structor/master/traefik-menu.js.gotmpl" --rqts-url="https://raw.githubusercontent.com/traefik/structor/master/requirements-override.txt" --force-edit-url --exp-branch=master --debug
|
||||
|
||||
- name: Apply seo
|
||||
run: $HOME/bin/seo -path=./site -product=traefik
|
||||
|
||||
5
.github/workflows/experimental.yaml
vendored
5
.github/workflows/experimental.yaml
vendored
@@ -7,7 +7,7 @@ on:
|
||||
- v*
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
@@ -23,7 +23,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -33,6 +33,7 @@ jobs:
|
||||
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Build
|
||||
run: make generate binary
|
||||
|
||||
27
.github/workflows/release.yaml
vendored
27
.github/workflows/release.yaml
vendored
@@ -6,7 +6,7 @@ on:
|
||||
- 'v*.*.*'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
VERSION: ${{ github.ref_name }}
|
||||
TRAEFIKER_EMAIL: "traefiker@traefik.io"
|
||||
@@ -15,11 +15,11 @@ env:
|
||||
jobs:
|
||||
|
||||
build-webui:
|
||||
if: github.ref_type == 'tag'
|
||||
if: github.ref_type == 'tag' && github.repository == 'traefik/traefik'
|
||||
uses: ./.github/workflows/template-webui.yaml
|
||||
|
||||
build:
|
||||
if: github.ref_type == 'tag'
|
||||
if: github.ref_type == 'tag' && github.repository == 'traefik/traefik'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
@@ -30,7 +30,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -41,6 +41,7 @@ jobs:
|
||||
ImageOS: ${{ matrix.os }}
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Artifact webui
|
||||
uses: actions/download-artifact@v4
|
||||
@@ -80,7 +81,7 @@ jobs:
|
||||
retention-days: 1
|
||||
|
||||
release:
|
||||
if: github.ref_type == 'tag'
|
||||
if: github.ref_type == 'tag' && github.repository == 'traefik/traefik'
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
needs:
|
||||
@@ -88,10 +89,20 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Artifact webui
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: webui.tar.gz
|
||||
|
||||
- name: Untar webui
|
||||
run: |
|
||||
tar xvf webui.tar.gz
|
||||
rm webui.tar.gz
|
||||
|
||||
- name: Retrieve the secret and decode it to a file
|
||||
env:
|
||||
TRAEFIKER_RSA: ${{ secrets.TRAEFIKER_RSA }}
|
||||
@@ -115,13 +126,11 @@ jobs:
|
||||
tar cfz "dist/traefik-${VERSION}.src.tar.gz" \
|
||||
--exclude-vcs \
|
||||
--exclude .idea \
|
||||
--exclude .travis \
|
||||
--exclude .semaphoreci \
|
||||
--exclude .github \
|
||||
--exclude dist .
|
||||
|
||||
chown -R "$(id -u)":"$(id -g)" dist/
|
||||
gh release create ${VERSION} ./dist/**/traefik*.{zip,tar.gz} ./dist/traefik*.{tar.gz,txt} --repo traefik/traefik --title ${VERSION} --notes ${VERSION}
|
||||
gh release create ${VERSION} ./dist/**/traefik*.{zip,tar.gz} ./dist/traefik*.{tar.gz,txt} --repo traefik/traefik --title ${VERSION} --notes ${VERSION} --latest=false
|
||||
|
||||
./script/deploy.sh
|
||||
|
||||
|
||||
12
.github/workflows/template-webui.yaml
vendored
12
.github/workflows/template-webui.yaml
vendored
@@ -1,6 +1,8 @@
|
||||
name: Build Web UI
|
||||
on:
|
||||
workflow_call: {}
|
||||
env:
|
||||
SAFE_CHAIN_MINIMUM_PACKAGE_AGE_HOURS: 360 # 15 days
|
||||
jobs:
|
||||
|
||||
build-webui:
|
||||
@@ -8,7 +10,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -19,10 +21,16 @@ jobs:
|
||||
cache: yarn
|
||||
cache-dependency-path: webui/yarn.lock
|
||||
|
||||
- name: Setup safe-chain
|
||||
working-directory: ./webui
|
||||
run: |
|
||||
npm i -g @aikidosec/safe-chain
|
||||
safe-chain setup-ci
|
||||
|
||||
- name: Build webui
|
||||
working-directory: ./webui
|
||||
run: |
|
||||
yarn install
|
||||
yarn install --ignore-scripts
|
||||
yarn build
|
||||
|
||||
- name: Package webui
|
||||
|
||||
41
.github/workflows/test-integration.yaml
vendored
41
.github/workflows/test-integration.yaml
vendored
@@ -10,7 +10,7 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
CGO_ENABLED: 0
|
||||
|
||||
jobs:
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -28,12 +28,27 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
run: make binary-linux-amd64
|
||||
|
||||
- name: Save go cache build
|
||||
uses: actions/cache/save@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Artifact traefik binary
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: traefik
|
||||
path: ./dist/linux/amd64/traefik
|
||||
retention-days: 1
|
||||
|
||||
test-integration:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -47,7 +62,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -55,12 +70,26 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Build binary
|
||||
run: make binary
|
||||
- name: Download traefik binary
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: traefik
|
||||
path: ./dist/linux/amd64/
|
||||
|
||||
- name: Make binary executable
|
||||
run: chmod +x ./dist/linux/amd64/traefik
|
||||
|
||||
- name: Restore go cache build
|
||||
uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: |
|
||||
~/.cache/go-build
|
||||
key: ${{ runner.os }}-go-build-cache-${{ env.GO_VERSION }}-${{ hashFiles('**/go.sum') }}
|
||||
|
||||
- name: Generate go test Slice
|
||||
id: test_split
|
||||
|
||||
49
.github/workflows/test-unit.yaml
vendored
49
.github/workflows/test-unit.yaml
vendored
@@ -10,16 +10,18 @@ on:
|
||||
- 'script/gcg/**'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GO_VERSION: '1.24'
|
||||
|
||||
jobs:
|
||||
|
||||
test-unit:
|
||||
generate-packages:
|
||||
name: List Go Packages
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -27,19 +29,47 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Generate matrix
|
||||
id: set-matrix
|
||||
run: |
|
||||
matrix_output=$(go run ./internal/testsci/genmatrix.go)
|
||||
echo "$matrix_output"
|
||||
echo "$matrix_output" >> $GITHUB_OUTPUT
|
||||
|
||||
test-unit:
|
||||
runs-on: ubuntu-latest
|
||||
needs: generate-packages
|
||||
strategy:
|
||||
matrix:
|
||||
package: ${{ fromJson(needs.generate-packages.outputs.matrix) }}
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Go ${{ env.GO_VERSION }}
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
|
||||
- name: Tests
|
||||
run: make test-unit
|
||||
run: |
|
||||
go test -v -parallel 8 ${{ matrix.package.group }}
|
||||
|
||||
test-ui-unit:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -50,7 +80,12 @@ jobs:
|
||||
cache: 'yarn'
|
||||
cache-dependency-path: webui/yarn.lock
|
||||
|
||||
- name: Setup safe-chain
|
||||
run: |
|
||||
npm i -g @aikidosec/safe-chain
|
||||
safe-chain setup-ci
|
||||
|
||||
- name: UI unit tests
|
||||
run: |
|
||||
yarn --cwd webui install
|
||||
yarn --cwd webui install --ignore-scripts
|
||||
yarn --cwd webui test:unit:ci
|
||||
|
||||
17
.github/workflows/validate.yaml
vendored
17
.github/workflows/validate.yaml
vendored
@@ -6,8 +6,8 @@ on:
|
||||
- '*'
|
||||
|
||||
env:
|
||||
GO_VERSION: '1.23'
|
||||
GOLANGCI_LINT_VERSION: v1.62.0
|
||||
GO_VERSION: '1.24'
|
||||
GOLANGCI_LINT_VERSION: v2.0.2
|
||||
MISSPELL_VERSION: v0.6.0
|
||||
|
||||
jobs:
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -25,9 +25,10 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: golangci-lint
|
||||
uses: golangci/golangci-lint-action@v6
|
||||
uses: golangci/golangci-lint-action@v7
|
||||
with:
|
||||
version: "${{ env.GOLANGCI_LINT_VERSION }}"
|
||||
|
||||
@@ -36,7 +37,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -44,9 +45,10 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: Install misspell ${{ env.MISSPELL_VERSION }}
|
||||
run: curl -sfL https://raw.githubusercontent.com/golangci/misspell/master/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSPELL_VERSION}
|
||||
run: curl -sfL https://raw.githubusercontent.com/golangci/misspell/HEAD/install-misspell.sh | sh -s -- -b $(go env GOPATH)/bin ${MISSPELL_VERSION}
|
||||
|
||||
- name: Avoid generating webui
|
||||
run: touch webui/static/index.html
|
||||
@@ -59,7 +61,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -67,6 +69,7 @@ jobs:
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: ${{ env.GO_VERSION }}
|
||||
check-latest: true
|
||||
|
||||
- name: go generate
|
||||
run: |
|
||||
|
||||
569
.golangci.yml
569
.golangci.yml
@@ -1,284 +1,313 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
version: "2"
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
- fieldalignment
|
||||
gocyclo:
|
||||
min-complexity: 14
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 4
|
||||
misspell:
|
||||
locale: US
|
||||
funlen:
|
||||
lines: -1
|
||||
statements: 120
|
||||
forbidigo:
|
||||
forbid:
|
||||
- ^print(ln)?$
|
||||
- ^spew\.Print(f|ln)?$
|
||||
- ^spew\.Dump$
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: "github.com/instana/testify"
|
||||
desc: not allowed
|
||||
- pkg: "github.com/pkg/errors"
|
||||
desc: Should be replaced by standard lib errors package
|
||||
godox:
|
||||
keywords:
|
||||
- FIXME
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
- alias: composeapi
|
||||
pkg: github.com/docker/compose/v2/pkg/api
|
||||
formatters:
|
||||
enable:
|
||||
- gci
|
||||
- gofumpt
|
||||
exclusions:
|
||||
generated: lax
|
||||
paths:
|
||||
- pkg/provider/kubernetes/crd/generated/
|
||||
|
||||
# Standard Kubernetes rewrites:
|
||||
- alias: corev1
|
||||
pkg: "k8s.io/api/core/v1"
|
||||
- alias: netv1
|
||||
pkg: "k8s.io/api/networking/v1"
|
||||
- alias: netv1beta1
|
||||
pkg: "k8s.io/api/networking/v1beta1"
|
||||
- alias: admv1
|
||||
pkg: "k8s.io/api/admission/v1"
|
||||
- alias: admv1beta1
|
||||
pkg: "k8s.io/api/admission/v1beta1"
|
||||
- alias: extv1beta1
|
||||
pkg: "k8s.io/api/extensions/v1beta1"
|
||||
- alias: metav1
|
||||
pkg: "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
- alias: ktypes
|
||||
pkg: "k8s.io/apimachinery/pkg/types"
|
||||
- alias: kerror
|
||||
pkg: "k8s.io/apimachinery/pkg/api/errors"
|
||||
- alias: kclientset
|
||||
pkg: "k8s.io/client-go/kubernetes"
|
||||
- alias: kinformers
|
||||
pkg: "k8s.io/client-go/informers"
|
||||
- alias: ktesting
|
||||
pkg: "k8s.io/client-go/testing"
|
||||
- alias: kschema
|
||||
pkg: "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
- alias: kscheme
|
||||
pkg: "k8s.io/client-go/kubernetes/scheme"
|
||||
- alias: kversion
|
||||
pkg: "k8s.io/apimachinery/pkg/version"
|
||||
- alias: kubefake
|
||||
pkg: "k8s.io/client-go/kubernetes/fake"
|
||||
- alias: discoveryfake
|
||||
pkg: "k8s.io/client-go/discovery/fake"
|
||||
|
||||
# Kubernetes Gateway rewrites:
|
||||
- alias: gateclientset
|
||||
pkg: "sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned"
|
||||
- alias: gateinformers
|
||||
pkg: "sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions"
|
||||
- alias: gatev1alpha2
|
||||
pkg: "sigs.k8s.io/gateway-api/apis/v1alpha2"
|
||||
|
||||
# Traefik Kubernetes rewrites:
|
||||
- alias: containousv1alpha1
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1"
|
||||
- alias: traefikv1alpha1
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1"
|
||||
- alias: traefikclientset
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned"
|
||||
- alias: traefikinformers
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions"
|
||||
- alias: traefikscheme
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme"
|
||||
- alias: traefikcrdfake
|
||||
pkg: "github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake"
|
||||
tagalign:
|
||||
align: false
|
||||
sort: true
|
||||
order:
|
||||
- description
|
||||
- json
|
||||
- toml
|
||||
- yaml
|
||||
- yml
|
||||
- label
|
||||
- label-slice-as-struct
|
||||
- file
|
||||
- kv
|
||||
- export
|
||||
revive:
|
||||
rules:
|
||||
- name: struct-tag
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
disabled: true
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
gomoddirectives:
|
||||
replace-allow-list:
|
||||
- github.com/abbot/go-http-auth
|
||||
- github.com/gorilla/mux
|
||||
- github.com/mailgun/minheap
|
||||
- github.com/mailgun/multibuf
|
||||
- github.com/jaguilar/vt100
|
||||
- github.com/cucumber/godog
|
||||
testifylint:
|
||||
disable:
|
||||
- suite-dont-use-pkg
|
||||
- require-error
|
||||
- go-require
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- fmt.Fprintln
|
||||
linters:
|
||||
enable-all: true
|
||||
default: all
|
||||
disable:
|
||||
- sqlclosecheck # not relevant (SQL)
|
||||
- rowserrcheck # not relevant (SQL)
|
||||
- bodyclose # too many false-positive
|
||||
- containedctx # too many false-positive
|
||||
- contextcheck # too many false-positive
|
||||
- cyclop # duplicate of gocyclo
|
||||
- lll # Not relevant
|
||||
- gocyclo # FIXME must be fixed
|
||||
- gocognit # Too strict
|
||||
- nestif # Too many false-positive.
|
||||
- prealloc # Too many false-positive.
|
||||
- makezero # Not relevant
|
||||
- dupl # Too strict
|
||||
- gosec # Too strict
|
||||
- gochecknoinits
|
||||
- gochecknoglobals
|
||||
- wsl # Too strict
|
||||
- nlreturn # Not relevant
|
||||
- mnd # Too strict
|
||||
- stylecheck # skip because report issues related to some generated files.
|
||||
- testpackage # Too strict
|
||||
- tparallel # Not relevant
|
||||
- paralleltest # Not relevant
|
||||
- err113 # Too strict
|
||||
- exhaustive # Not relevant
|
||||
- exhaustruct # Not relevant
|
||||
- err113 # Too strict
|
||||
- wrapcheck # Too strict
|
||||
- noctx # Too strict
|
||||
- bodyclose # too many false-positive
|
||||
- forcetypeassert # Too strict
|
||||
- tagliatelle # Too strict
|
||||
- varnamelen # Not relevant
|
||||
- nilnil # Not relevant
|
||||
- ireturn # Not relevant
|
||||
- contextcheck # too many false-positive
|
||||
- containedctx # too many false-positive
|
||||
- maintidx # kind of duplicate of gocyclo
|
||||
- nonamedreturns # Too strict
|
||||
- gochecknoglobals
|
||||
- gochecknoinits
|
||||
- gocognit # Too strict
|
||||
- gocyclo # FIXME must be fixed
|
||||
- gosec # Too strict
|
||||
- gosmopolitan # not relevant
|
||||
- exportloopref # Not relevant since go1.22
|
||||
- ireturn # Not relevant
|
||||
- lll # Not relevant
|
||||
- maintidx # kind of duplicate of gocyclo
|
||||
- makezero # Not relevant
|
||||
- mnd # Too strict
|
||||
- nestif # Too many false-positive.
|
||||
- nilnil # Not relevant
|
||||
- nlreturn # Not relevant
|
||||
- noctx # Too strict
|
||||
- nonamedreturns # Too strict
|
||||
- paralleltest # Not relevant
|
||||
- prealloc # Too many false-positive.
|
||||
- rowserrcheck # not relevant (SQL)
|
||||
- sqlclosecheck # not relevant (SQL)
|
||||
- tagliatelle # Too strict
|
||||
- testpackage # Too strict
|
||||
- tparallel # Not relevant
|
||||
- varnamelen # Not relevant
|
||||
- wrapcheck # Too strict
|
||||
- wsl # Too strict
|
||||
|
||||
settings:
|
||||
depguard:
|
||||
rules:
|
||||
main:
|
||||
deny:
|
||||
- pkg: github.com/instana/testify
|
||||
desc: not allowed
|
||||
- pkg: github.com/pkg/errors
|
||||
desc: Should be replaced by standard lib errors package
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- fmt.Fprintln
|
||||
forbidigo:
|
||||
forbid:
|
||||
- pattern: ^print(ln)?$
|
||||
- pattern: ^spew\.Print(f|ln)?$
|
||||
- pattern: ^spew\.Dump$
|
||||
funlen:
|
||||
lines: -1
|
||||
statements: 120
|
||||
goconst:
|
||||
min-len: 3
|
||||
min-occurrences: 4
|
||||
gocyclo:
|
||||
min-complexity: 14
|
||||
godox:
|
||||
keywords:
|
||||
- FIXME
|
||||
gomoddirectives:
|
||||
toolchain-pattern: go1\.\d+\.\d+$
|
||||
tool-forbidden: true
|
||||
go-version-pattern: ^1\.\d+(\.0)?$
|
||||
replace-allow-list:
|
||||
- github.com/abbot/go-http-auth
|
||||
- github.com/gorilla/mux
|
||||
- github.com/mailgun/minheap
|
||||
- github.com/mailgun/multibuf
|
||||
- github.com/jaguilar/vt100
|
||||
- github.com/cucumber/godog
|
||||
govet:
|
||||
enable-all: true
|
||||
disable:
|
||||
- shadow
|
||||
- fieldalignment
|
||||
importas:
|
||||
no-unaliased: true
|
||||
alias:
|
||||
- pkg: github.com/docker/compose/v2/pkg/api
|
||||
alias: composeapi
|
||||
|
||||
# Standard Kubernetes rewrites:
|
||||
- pkg: k8s.io/api/core/v1
|
||||
alias: corev1
|
||||
- pkg: k8s.io/api/networking/v1
|
||||
alias: netv1
|
||||
- pkg: k8s.io/api/networking/v1beta1
|
||||
alias: netv1beta1
|
||||
- pkg: k8s.io/api/admission/v1
|
||||
alias: admv1
|
||||
- pkg: k8s.io/api/admission/v1beta1
|
||||
alias: admv1beta1
|
||||
- pkg: k8s.io/api/extensions/v1beta1
|
||||
alias: extv1beta1
|
||||
- pkg: k8s.io/apimachinery/pkg/apis/meta/v1
|
||||
alias: metav1
|
||||
- pkg: k8s.io/apimachinery/pkg/types
|
||||
alias: ktypes
|
||||
- pkg: k8s.io/apimachinery/pkg/api/errors
|
||||
alias: kerror
|
||||
- pkg: k8s.io/client-go/kubernetes
|
||||
alias: kclientset
|
||||
- pkg: k8s.io/client-go/informers
|
||||
alias: kinformers
|
||||
- pkg: k8s.io/client-go/testing
|
||||
alias: ktesting
|
||||
- pkg: k8s.io/apimachinery/pkg/runtime/schema
|
||||
alias: kschema
|
||||
- pkg: k8s.io/client-go/kubernetes/scheme
|
||||
alias: kscheme
|
||||
- pkg: k8s.io/apimachinery/pkg/version
|
||||
alias: kversion
|
||||
- pkg: k8s.io/client-go/kubernetes/fake
|
||||
alias: kubefake
|
||||
- pkg: k8s.io/client-go/discovery/fake
|
||||
alias: discoveryfake
|
||||
|
||||
# Kubernetes Gateway rewrites:
|
||||
- pkg: sigs.k8s.io/gateway-api/pkg/client/clientset/gateway/versioned
|
||||
alias: gateclientset
|
||||
- pkg: sigs.k8s.io/gateway-api/pkg/client/informers/gateway/externalversions
|
||||
alias: gateinformers
|
||||
- pkg: sigs.k8s.io/gateway-api/apis/v1alpha2
|
||||
alias: gatev1alpha2
|
||||
|
||||
# Traefik Kubernetes rewrites:
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikcontainous/v1alpha1
|
||||
alias: containousv1alpha1
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/traefikio/v1alpha1
|
||||
alias: traefikv1alpha1
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned
|
||||
alias: traefikclientset
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/informers/externalversions
|
||||
alias: traefikinformers
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/scheme
|
||||
alias: traefikscheme
|
||||
- pkg: github.com/traefik/traefik/v2/pkg/provider/kubernetes/crd/generated/clientset/versioned/fake
|
||||
alias: traefikcrdfake
|
||||
misspell:
|
||||
locale: US
|
||||
revive:
|
||||
rules:
|
||||
- name: struct-tag
|
||||
- name: blank-imports
|
||||
- name: context-as-argument
|
||||
- name: context-keys-type
|
||||
- name: dot-imports
|
||||
- name: error-return
|
||||
- name: error-strings
|
||||
- name: error-naming
|
||||
- name: exported
|
||||
disabled: true
|
||||
- name: if-return
|
||||
- name: increment-decrement
|
||||
- name: var-naming
|
||||
- name: var-declaration
|
||||
- name: package-comments
|
||||
disabled: true
|
||||
- name: range
|
||||
- name: receiver-naming
|
||||
- name: time-naming
|
||||
- name: unexported-return
|
||||
- name: indent-error-flow
|
||||
- name: errorf
|
||||
- name: empty-block
|
||||
- name: superfluous-else
|
||||
- name: unused-parameter
|
||||
disabled: true
|
||||
- name: unreachable-code
|
||||
- name: redefines-builtin-id
|
||||
tagalign:
|
||||
align: false
|
||||
sort: true
|
||||
order:
|
||||
- description
|
||||
- json
|
||||
- toml
|
||||
- yaml
|
||||
- yml
|
||||
- label
|
||||
- label-slice-as-struct
|
||||
- file
|
||||
- kv
|
||||
- export
|
||||
testifylint:
|
||||
disable:
|
||||
- suite-dont-use-pkg
|
||||
- require-error
|
||||
- go-require
|
||||
perfsprint:
|
||||
err-error: true
|
||||
errorf: true
|
||||
sprintf1: true
|
||||
strconcat: false
|
||||
staticcheck:
|
||||
checks:
|
||||
- all
|
||||
- '-ST1000'
|
||||
- '-ST1003'
|
||||
- '-ST1016'
|
||||
- '-ST1020'
|
||||
- '-ST1021'
|
||||
- '-ST1022'
|
||||
- '-QF1001'
|
||||
- '-QF1008' # TODO must be fixed
|
||||
|
||||
exclusions:
|
||||
generated: lax
|
||||
presets:
|
||||
- comments
|
||||
- std-error-handling
|
||||
rules:
|
||||
- path: (.+)_test.go
|
||||
linters:
|
||||
- canonicalheader
|
||||
- fatcontext
|
||||
- funlen
|
||||
- goconst
|
||||
- godot
|
||||
- path: (.+)_test.go
|
||||
text: ' always receives '
|
||||
linters:
|
||||
- unparam
|
||||
- path: pkg/server/service/bufferpool.go
|
||||
text: 'SA6002: argument should be pointer-like to avoid allocations'
|
||||
- path: pkg/server/middleware/middlewares.go
|
||||
text: Function 'buildConstructor' has too many statements
|
||||
linters:
|
||||
- funlen
|
||||
- path: pkg/tracing/haystack/logger.go
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tracing/tracing.go
|
||||
text: printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tls/tlsmanager_test.go
|
||||
text: 'SA1019: config.ClientCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/types/tls_test.go
|
||||
text: 'SA1019: tlsConfig.RootCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/provider/kubernetes/(crd|gateway)/client.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: pkg/metrics/metrics.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: integration/healthcheck_test.go
|
||||
text: Duplicate words \(wsp2,\) found
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/types/domain_test.go
|
||||
text: Duplicate words \(sub\) found
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/provider/kubernetes/gateway/client_mock_test.go
|
||||
text: 'unusedwrite: unused write to field'
|
||||
linters:
|
||||
- govet
|
||||
- path: pkg/provider/acme/local_store.go
|
||||
linters:
|
||||
- musttag
|
||||
- path: pkg/tls/certificate.go
|
||||
text: the methods of "Certificates" use pointer receiver and non-pointer receiver.
|
||||
linters:
|
||||
- recvcheck
|
||||
- path: pkg/config/static/static_config.go
|
||||
source: 'errors.New\("Consul Catalog provider'
|
||||
text: 'ST1005: error strings should not be capitalized'
|
||||
- path: pkg/config/static/static_config.go
|
||||
source: 'errors.New\("Consul provider'
|
||||
text: 'ST1005: error strings should not be capitalized'
|
||||
- path: pkg/config/static/static_config.go
|
||||
source: 'errors.New\("Nomad provider'
|
||||
text: 'ST1005: error strings should not be capitalized'
|
||||
- path: (.+)\.go
|
||||
text: 'struct-tag: unknown option ''inline'' in JSON tag'
|
||||
linters:
|
||||
- revive
|
||||
- path: (.+)\.go
|
||||
text: 'struct-tag: unknown option ''omitzero'' in TOML tag'
|
||||
linters:
|
||||
- revive
|
||||
- path: (.+)\.go$
|
||||
text: 'SA1019: http.CloseNotifier has been deprecated' # FIXME must be fixed
|
||||
- path: (.+)\.go$
|
||||
text: 'SA1019: cfg.(SSLRedirect|SSLTemporaryRedirect|SSLHost|SSLForceHost|FeaturePolicy) is deprecated'
|
||||
- path: (.+)\.go$
|
||||
text: 'SA1019: c.Providers.(ConsulCatalog|Consul|Nomad).Namespace is deprecated'
|
||||
paths:
|
||||
- pkg/provider/kubernetes/crd/generated/
|
||||
|
||||
issues:
|
||||
exclude-use-default: false
|
||||
max-issues-per-linter: 0
|
||||
max-same-issues: 0
|
||||
exclude-dirs:
|
||||
- pkg/provider/kubernetes/crd/generated/
|
||||
exclude:
|
||||
- 'Error return value of .((os\.)?std(out|err)\..*|.*Close|.*Flush|os\.Remove(All)?|.*printf?|os\.(Un)?Setenv). is not checked'
|
||||
- "should have a package comment, unless it's in another file for this package"
|
||||
- 'SA1019: http.CloseNotifier has been deprecated' # FIXME must be fixed
|
||||
- 'SA1019: cfg.SSLRedirect is deprecated'
|
||||
- 'SA1019: cfg.SSLTemporaryRedirect is deprecated'
|
||||
- 'SA1019: cfg.SSLHost is deprecated'
|
||||
- 'SA1019: cfg.SSLForceHost is deprecated'
|
||||
- 'SA1019: cfg.FeaturePolicy is deprecated'
|
||||
- 'SA1019: c.Providers.ConsulCatalog.Namespace is deprecated'
|
||||
- 'SA1019: c.Providers.Consul.Namespace is deprecated'
|
||||
- 'SA1019: c.Providers.Nomad.Namespace is deprecated'
|
||||
- 'fmt.Sprintf can be replaced with string'
|
||||
- 'SA1019: dockertypes.ContainerNode is deprecated'
|
||||
exclude-rules:
|
||||
- path: '(.+)_test.go'
|
||||
linters:
|
||||
- goconst
|
||||
- funlen
|
||||
- godot
|
||||
- canonicalheader
|
||||
- fatcontext
|
||||
- path: '(.+)_test.go'
|
||||
text: ' always receives '
|
||||
linters:
|
||||
- unparam
|
||||
- path: '(.+)\.go'
|
||||
text: 'struct-tag: unknown option ''inline'' in JSON tag'
|
||||
linters:
|
||||
- revive
|
||||
- path: pkg/server/service/bufferpool.go
|
||||
text: 'SA6002: argument should be pointer-like to avoid allocations'
|
||||
- path: pkg/server/middleware/middlewares.go
|
||||
text: "Function 'buildConstructor' has too many statements"
|
||||
linters:
|
||||
- funlen
|
||||
- path: pkg/tracing/haystack/logger.go
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tracing/tracing.go
|
||||
text: "printf-like formatting function 'SetErrorWithEvent' should be named 'SetErrorWithEventf'"
|
||||
linters:
|
||||
- goprintffuncname
|
||||
- path: pkg/tls/tlsmanager_test.go
|
||||
text: 'SA1019: config.ClientCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/types/tls_test.go
|
||||
text: 'SA1019: tlsConfig.RootCAs.Subjects has been deprecated since Go 1.18'
|
||||
- path: pkg/provider/kubernetes/(crd|gateway)/client.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: pkg/metrics/metrics.go
|
||||
linters:
|
||||
- interfacebloat
|
||||
- path: integration/healthcheck_test.go
|
||||
text: 'Duplicate words \(wsp2,\) found'
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/types/domain_test.go
|
||||
text: 'Duplicate words \(sub\) found'
|
||||
linters:
|
||||
- dupword
|
||||
- path: pkg/provider/kubernetes/gateway/client_mock_test.go
|
||||
text: 'unusedwrite: unused write to field'
|
||||
linters:
|
||||
- govet
|
||||
- path: pkg/provider/acme/local_store.go
|
||||
linters:
|
||||
- musttag
|
||||
- path: pkg/tls/certificate.go
|
||||
text: 'the methods of "Certificates" use pointer receiver and non-pointer receiver.'
|
||||
linters:
|
||||
- recvcheck
|
||||
|
||||
output:
|
||||
show-stats: true
|
||||
sort-results: true
|
||||
sort-order:
|
||||
- linter
|
||||
- file
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
version: v1.0
|
||||
name: Traefik Release - deprecated
|
||||
agent:
|
||||
machine:
|
||||
type: f1-standard-2
|
||||
os_image: ubuntu2204
|
||||
blocks:
|
||||
- name: 'Do nothing'
|
||||
task:
|
||||
jobs:
|
||||
- name: 'Do nothing'
|
||||
commands:
|
||||
- echo "Do nothing"
|
||||
171
CHANGELOG.md
171
CHANGELOG.md
@@ -1,3 +1,174 @@
|
||||
## [v2.11.32](https://github.com/traefik/traefik/tree/v2.11.32) (2025-12-04)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.31...v2.11.32)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[server]** Reject suspicious encoded characters ([#12360](https://github.com/traefik/traefik/pull/12360) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[plugins]** Validate plugin module name ([#12291](https://github.com/traefik/traefik/pull/12291) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[http3]** Bump github.com/quic-go/quic-go to v0.57.1 ([#12319](https://github.com/traefik/traefik/pull/12319) by [GreyXor](https://github.com/GreyXor))
|
||||
- **[http3]** Bump github.com/quic-go/quic-go to v0.57.0 ([#12308](https://github.com/traefik/traefik/pull/12308) by [GreyXor](https://github.com/GreyXor))
|
||||
- **[server]** Bump golang.org/x/crypto to v0.45.0 ([#12296](https://github.com/traefik/traefik/pull/12296) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- Update SECURITY.md to streamline information ([#12310](https://github.com/traefik/traefik/pull/12310) by [emilevauge](https://github.com/emilevauge))
|
||||
- Update SECURITY.md ([#12304](https://github.com/traefik/traefik/pull/12304) by [cwayne18](https://github.com/cwayne18))
|
||||
|
||||
## [v2.11.31](https://github.com/traefik/traefik/tree/v2.11.31) (2025-11-13)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.30...v2.11.31)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[docker,docker/swarm]** Auto-negotiate Docker API version ([#12262](https://github.com/traefik/traefik/pull/12262) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.30](https://github.com/traefik/traefik/tree/v2.11.30) (2025-10-28)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.29...v2.11.30)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[http3]** Bump github.com/quic-go/quic-go to v0.55.0 ([#12156](https://github.com/traefik/traefik/pull/12156) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[kv]** Fix KV key name used to check if connection is alive ([#12162](https://github.com/traefik/traefik/pull/12162) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[server]** Bump golang.org/x/net to v0.46.0 ([#12143](https://github.com/traefik/traefik/pull/12143) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[tracing]** Bump gopkg.in/DataDog/dd-trace-go.v1 to v1.74.6 ([#12083](https://github.com/traefik/traefik/pull/12083) by [hannahkm](https://github.com/hannahkm))
|
||||
|
||||
## [v2.11.29](https://github.com/traefik/traefik/tree/v2.11.29) (2025-08-26)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.28...v2.11.29)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.25.2 ([#11983](https://github.com/traefik/traefik/pull/11983) by [ldez](https://github.com/ldez))
|
||||
- **[docker]** Bump github.com/docker/docker to v28.3.3 ([#12007](https://github.com/traefik/traefik/pull/12007) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- Fix invalid links in documentation ([#11960](https://github.com/traefik/traefik/pull/11960) by [mloiseleur](https://github.com/mloiseleur))
|
||||
- Update releases docs for v3.5 ([#11949](https://github.com/traefik/traefik/pull/11949) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v2.11.28](https://github.com/traefik/traefik/tree/v2.11.28) (2025-07-23)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.27...v2.11.28)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[logs]** Redact logged install configuration ([#11907](https://github.com/traefik/traefik/pull/11907) by [jspdown](https://github.com/jspdown))
|
||||
- **[plugins]** Fix client arbitrary file access during archive extraction zipslip ([#11911](https://github.com/traefik/traefik/pull/11911) by [odaysec](https://github.com/odaysec))
|
||||
- **[server]** Disable MPTCP by default ([#11918](https://github.com/traefik/traefik/pull/11918) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Documentation:**
|
||||
- **[k8s/crd,k8s]** Remove all mentions of ordering for TLSOption CurvePreferences field ([#11924](https://github.com/traefik/traefik/pull/11924) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v2.11.27](https://github.com/traefik/traefik/tree/v2.11.27) (2025-07-11)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.26...v2.11.27)
|
||||
|
||||
**Bug fixes:**
|
||||
- Bump github.com/go-viper/mapstructure/v2 to v2.3.0 ([#11880](https://github.com/traefik/traefik/pull/11880) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.26](https://github.com/traefik/traefik/tree/v2.11.26) (2025-06-26)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.25...v2.11.26)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[middleware]** Do not log redis sentinel username and password ([#11819](https://github.com/traefik/traefik/pull/11819) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[kv]** Fix KV reference rendering ([#11815](https://github.com/traefik/traefik/pull/11815) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware,k8s/crd]** Fix typo in redirect middleware documentation ([#11830](https://github.com/traefik/traefik/pull/11830) by [rtribotte](https://github.com/rtribotte))
|
||||
- Update supported versions ([#11811](https://github.com/traefik/traefik/pull/11811) by [jnoordsij](https://github.com/jnoordsij))
|
||||
|
||||
## [v2.11.25](https://github.com/traefik/traefik/tree/v2.11.25) (2025-05-27)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.24...v2.11.25)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[k8s/ingress]** Fix panic for ingress with backend resource ([#11777](https://github.com/traefik/traefik/pull/11777) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[server]** Normalize request path ([#11768](https://github.com/traefik/traefik/pull/11768) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware,k8s]** Add multi-tenant TLS guidance to the docs ([#11724](https://github.com/traefik/traefik/pull/11724) by [sheddy-traefik](https://github.com/sheddy-traefik))
|
||||
- **[service]** Add a note about how to disable connection reuse with backends ([#11716](https://github.com/traefik/traefik/pull/11716) by [rtribotte](https://github.com/rtribotte))
|
||||
- Fix broken link in documentation ([#11761](https://github.com/traefik/traefik/pull/11761) by [sheddy-traefik](https://github.com/sheddy-traefik))
|
||||
- Change version for path sanitization migration guide ([#11702](https://github.com/traefik/traefik/pull/11702) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
## [v2.11.24](https://github.com/traefik/traefik/tree/v2.11.24) (2025-04-18)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.22...v2.11.24)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.23.1 ([#11690](https://github.com/traefik/traefik/pull/11690) by [ldez](https://github.com/ldez))
|
||||
- **[metrics]** Bump gopkg.in/DataDog/dd-trace-go.v1 to v1.72.2 ([#11693](https://github.com/traefik/traefik/pull/11693) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Add Content-Length header to preflight response ([#11682](https://github.com/traefik/traefik/pull/11682) by [lbenguigui](https://github.com/lbenguigui))
|
||||
- **[server]** Sanitize request path ([#11684](https://github.com/traefik/traefik/pull/11684) by [rtribotte](https://github.com/rtribotte))
|
||||
- Bump github.com/redis/go-redis/v9 to v9.7.3 ([#11695](https://github.com/traefik/traefik/pull/11695) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump golang.org/x/net to v0.38.0 ([#11691](https://github.com/traefik/traefik/pull/11691) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump golang.org/x/oauth2 to v0.28.0 ([#11689](https://github.com/traefik/traefik/pull/11689) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
**Documentation:**
|
||||
- **[middleware]** Add content-length best practice documentation ([#11697](https://github.com/traefik/traefik/pull/11697) by [sheddy-traefik](https://github.com/sheddy-traefik))
|
||||
- Typo fix on the Explanation Section for User Guide HTTP Challenge. ([#11676](https://github.com/traefik/traefik/pull/11676) by [YapWC](https://github.com/YapWC))
|
||||
|
||||
## [v2.11.23](https://github.com/traefik/traefik/tree/v2.11.23) (2025-04-17)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.22...v2.11.23)
|
||||
|
||||
Release canceled.
|
||||
|
||||
## [v2.11.22](https://github.com/traefik/traefik/tree/v2.11.22) (2025-03-31)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.21...v2.11.22)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[ecs,logs]** Bump AWS SDK to v2 ([#11359](https://github.com/traefik/traefik/pull/11359) by [Juneezee](https://github.com/Juneezee))
|
||||
- **[logs,tls]** Error level log for configuration-related TLS errors with backends ([#11611](https://github.com/traefik/traefik/pull/11611) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[rules]** Allow underscore character in HostSNI matcher ([#11557](https://github.com/traefik/traefik/pull/11557) by [rohitlohar45](https://github.com/rohitlohar45))
|
||||
- **[server]** Bump github.com/vulcand/oxy/v2 to v2.0.3 ([#11649](https://github.com/traefik/traefik/pull/11649) by [adamvduke](https://github.com/adamvduke))
|
||||
- **[server]** Bump golang.org/x/net to v0.37.0 ([#11632](https://github.com/traefik/traefik/pull/11632) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[webui]** Change boolean module properties default value to undefined ([#11639](https://github.com/traefik/traefik/pull/11639) by [rtribotte](https://github.com/rtribotte))
|
||||
- Bump github.com/golang-jwt/jwt to v4.5.2 and v5.2.2 ([#11634](https://github.com/traefik/traefik/pull/11634) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump github.com/redis/go-redis/v9 to v9.6.3 ([#11633](https://github.com/traefik/traefik/pull/11633) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump golang.org/x/net to v0.36.0 ([#11608](https://github.com/traefik/traefik/pull/11608) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- Bump github.com/go-jose/go-jose/v4 to v4.0.5 ([#11571](https://github.com/traefik/traefik/pull/11571) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[accesslogs]** Remove documentation for OriginStatusLine and DownstreamStatusLine accessLogs fields ([#11599](https://github.com/traefik/traefik/pull/11599) by [rtribotte](https://github.com/rtribotte))
|
||||
- **[middleware]** Clarifies that retry middleware uses TCP, not HTTP status codes ([#11603](https://github.com/traefik/traefik/pull/11603) by [geraldcroes](https://github.com/geraldcroes))
|
||||
- **[redis]** Add tip for dynamic configuration updates of Redis ([#11577](https://github.com/traefik/traefik/pull/11577) by [Alanxtl](https://github.com/Alanxtl))
|
||||
- Add Security Support ([#11610](https://github.com/traefik/traefik/pull/11610) by [nmengin](https://github.com/nmengin))
|
||||
|
||||
# [v2.11.21](https://github.com/traefik/traefik/tree/v2.11.21) (2025-02-24)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.20...v2.11.21)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Bump github.com/go-acme/lego/v4 to v4.22.2 ([#11537](https://github.com/traefik/traefik/pull/11537) by [ldez](https://github.com/ldez))
|
||||
- **[cli]** Bump github.com/traefik/paerser to v0.2.2 ([#11530](https://github.com/traefik/traefik/pull/11530) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Enable the retry middleware in the proxy ([#11536](https://github.com/traefik/traefik/pull/11536) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[middleware]** Retry should send headers on Write ([#11534](https://github.com/traefik/traefik/pull/11534) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.20](https://github.com/traefik/traefik/tree/v2.11.20) (2025-01-31)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.19...v2.11.20)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Graceful shutdown for ACME JSON write operation ([#11497](https://github.com/traefik/traefik/pull/11497) by [juliens](https://github.com/juliens))
|
||||
|
||||
**Documentation:**
|
||||
- Change docker-compose to docker compose ([#11496](https://github.com/traefik/traefik/pull/11496) by [khai-pi](https://github.com/khai-pi))
|
||||
|
||||
## [v2.11.19](https://github.com/traefik/traefik/tree/v2.11.19) (2025-01-29)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.18...v2.11.19)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[middleware]** Changing log message when client cert is not available to debug ([#11453](https://github.com/traefik/traefik/pull/11453) by [Nelwhix](https://github.com/Nelwhix))
|
||||
- **[service]** Do not create a logger instance for each proxy ([#11487](https://github.com/traefik/traefik/pull/11487) by [kevinpollet](https://github.com/kevinpollet))
|
||||
- **[webui]** Fix auto refresh not clearing on component unmount ([#11477](https://github.com/traefik/traefik/pull/11477) by [DoubleREW](https://github.com/DoubleREW))
|
||||
|
||||
**Documentation:**
|
||||
- Remove awesome.traefik.io reference in documentation section ([#11435](https://github.com/traefik/traefik/pull/11435) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.18](https://github.com/traefik/traefik/tree/v2.11.18) (2025-01-07)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.17...v2.11.18)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[websocket,server]** Disable http2 connect setting for websocket by default ([#11412](https://github.com/traefik/traefik/pull/11412) by [rtribotte](https://github.com/rtribotte))
|
||||
|
||||
## [v2.11.17](https://github.com/traefik/traefik/tree/v2.11.17) (2025-01-06)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.16...v2.11.17)
|
||||
|
||||
**Bug fixes:**
|
||||
- **[acme]** Update go-acme/lego to v4.21.0 ([#11368](https://github.com/traefik/traefik/pull/11368) by [ldez](https://github.com/ldez))
|
||||
- **[middleware]** Fix typo in basicauth note ([#11397](https://github.com/traefik/traefik/pull/11397) by [tieje](https://github.com/tieje))
|
||||
- **[service]** Configure ErrorLog in httputil.ReverseProxy ([#11344](https://github.com/traefik/traefik/pull/11344) by [peacewalker122](https://github.com/peacewalker122))
|
||||
- Bump golang.org/x/net to v0.33.0 ([#11365](https://github.com/traefik/traefik/pull/11365) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
**Documentation:**
|
||||
- **[acme]** Fix allowACMEByPass TOML example ([#11370](https://github.com/traefik/traefik/pull/11370) by [hannesbraun](https://github.com/hannesbraun))
|
||||
- **[k8s/crd]** Update copyright for 2025 ([#11383](https://github.com/traefik/traefik/pull/11383) by [kevinpollet](https://github.com/kevinpollet))
|
||||
|
||||
## [v2.11.16](https://github.com/traefik/traefik/tree/v2.11.16) (2024-12-16)
|
||||
[All Commits](https://github.com/traefik/traefik/compare/v2.11.15...v2.11.16)
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# syntax=docker/dockerfile:1.2
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
RUN apk add --no-cache --no-progress ca-certificates tzdata
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2024 Traefik Labs
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
12
Makefile
12
Makefile
@@ -13,6 +13,7 @@ DATE := $(shell date -u '+%Y-%m-%d_%I:%M:%S%p')
|
||||
# Default build target
|
||||
GOOS := $(shell go env GOOS)
|
||||
GOARCH := $(shell go env GOARCH)
|
||||
GOGC ?=
|
||||
|
||||
LINT_EXECUTABLES = misspell shellcheck
|
||||
|
||||
@@ -56,7 +57,7 @@ generate:
|
||||
#? binary: Build the binary
|
||||
binary: generate-webui dist
|
||||
@echo SHA: $(VERSION) $(CODENAME) $(DATE)
|
||||
CGO_ENABLED=0 GOGC=off GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS[*]} -ldflags "-s -w \
|
||||
CGO_ENABLED=0 GOGC=${GOGC} GOOS=${GOOS} GOARCH=${GOARCH} go build ${FLAGS[*]} -ldflags "-s -w \
|
||||
-X github.com/traefik/traefik/v2/pkg/version.Version=$(VERSION) \
|
||||
-X github.com/traefik/traefik/v2/pkg/version.Codename=$(CODENAME) \
|
||||
-X github.com/traefik/traefik/v2/pkg/version.BuildDate=$(DATE)" \
|
||||
@@ -94,7 +95,7 @@ test-unit:
|
||||
|
||||
.PHONY: test-integration
|
||||
#? test-integration: Run the integration tests
|
||||
test-integration: binary
|
||||
test-integration:
|
||||
GOOS=$(GOOS) GOARCH=$(GOARCH) go test ./integration -test.timeout=20m -failfast -v $(TESTFLAGS)
|
||||
|
||||
.PHONY: test-ui-unit
|
||||
@@ -169,18 +170,13 @@ docs-pull-images:
|
||||
.PHONY: generate-crd
|
||||
#? generate-crd: Generate CRD clientset and CRD manifests
|
||||
generate-crd:
|
||||
@$(CURDIR)/script/code-gen-docker.sh
|
||||
@$(CURDIR)/script/code-gen.sh
|
||||
|
||||
.PHONY: generate-genconf
|
||||
#? generate-genconf: Generate code from dynamic configuration github.com/traefik/genconf
|
||||
generate-genconf:
|
||||
go run ./cmd/internal/gen/
|
||||
|
||||
.PHONY: release-packages
|
||||
#? release-packages: Create packages for the release
|
||||
release-packages: generate-webui
|
||||
$(CURDIR)/script/release-packages.sh
|
||||
|
||||
.PHONY: fmt
|
||||
#? fmt: Format the Code
|
||||
fmt:
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
</picture>
|
||||
</p>
|
||||
|
||||
[](https://traefik-oss.semaphoreci.com/projects/traefik)
|
||||
[](https://doc.traefik.io/traefik)
|
||||
[](https://goreportcard.com/report/traefik/traefik)
|
||||
[](https://github.com/traefik/traefik/blob/master/LICENSE.md)
|
||||
@@ -91,8 +90,6 @@ You can access the simple HTML frontend of Traefik.
|
||||
|
||||
You can find the complete documentation of Traefik v2 at [https://doc.traefik.io/traefik/](https://doc.traefik.io/traefik/).
|
||||
|
||||
A collection of contributions around Traefik can be found at [https://awesome.traefik.io](https://awesome.traefik.io).
|
||||
|
||||
## Support
|
||||
|
||||
To get community support, you can:
|
||||
|
||||
15
SECURITY.md
15
SECURITY.md
@@ -1,10 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
You can join our security mailing list to be aware of the latest announcements from our security team.
|
||||
You can subscribe by sending an email to security+subscribe@traefik.io or on [the online viewer](https://groups.google.com/a/traefik.io/forum/#!forum/security).
|
||||
|
||||
Reported vulnerabilities can be found on [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik).
|
||||
|
||||
## Supported Versions
|
||||
|
||||
- We usually release 3/4 new versions (e.g. 1.1.0, 1.2.0, 1.3.0) per year.
|
||||
@@ -17,10 +12,10 @@ We use [Semantic Versioning](https://semver.org/).
|
||||
|
||||
| Version | Supported |
|
||||
|-----------|--------------------|
|
||||
| `2.2.x` | :white_check_mark: |
|
||||
| `< 2.2.x` | :x: |
|
||||
| `1.7.x` | :white_check_mark: |
|
||||
| `< 1.7.x` | :x: |
|
||||
| `3.6.x` | :white_check_mark: |
|
||||
| `< 3.6.x` | :x: |
|
||||
| `2.11.x` | :white_check_mark: |
|
||||
| `< 2.11.x` | :x: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
@@ -28,3 +23,5 @@ We want to keep Traefik safe for everyone.
|
||||
If you've discovered a security vulnerability in Traefik,
|
||||
we appreciate your help in disclosing it to us in a responsible manner,
|
||||
by creating a [security advisory](https://github.com/traefik/traefik/security/advisories).
|
||||
|
||||
Reported vulnerabilities can be found on [cve.mitre.org](https://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=traefik).
|
||||
|
||||
@@ -3,7 +3,6 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
stdlog "log"
|
||||
"net/http"
|
||||
@@ -34,6 +33,7 @@ import (
|
||||
"github.com/traefik/traefik/v2/pkg/provider/acme"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/aggregator"
|
||||
"github.com/traefik/traefik/v2/pkg/provider/traefik"
|
||||
"github.com/traefik/traefik/v2/pkg/redactor"
|
||||
"github.com/traefik/traefik/v2/pkg/safe"
|
||||
"github.com/traefik/traefik/v2/pkg/server"
|
||||
"github.com/traefik/traefik/v2/pkg/server/middleware"
|
||||
@@ -100,12 +100,11 @@ func runCmd(staticConfiguration *static.Configuration) error {
|
||||
|
||||
log.WithoutContext().Infof("Traefik version %s built on %s", version.Version, version.BuildDate)
|
||||
|
||||
jsonConf, err := json.Marshal(staticConfiguration)
|
||||
redactedStaticConfiguration, err := redactor.RemoveCredentials(staticConfiguration)
|
||||
if err != nil {
|
||||
log.WithoutContext().Errorf("Could not marshal static configuration: %v", err)
|
||||
log.WithoutContext().Debugf("Static configuration loaded [struct] %#v", staticConfiguration)
|
||||
log.WithoutContext().Errorf("Could not redact static configuration: %v", err)
|
||||
} else {
|
||||
log.WithoutContext().Debugf("Static configuration loaded %s", string(jsonConf))
|
||||
log.WithoutContext().Debugf("Static configuration loaded %s", redactedStaticConfiguration)
|
||||
}
|
||||
|
||||
if staticConfiguration.Global.CheckNewVersion {
|
||||
@@ -187,7 +186,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
acmeProviders := initACMEProvider(staticConfiguration, providerAggregator, tlsManager, httpChallengeProvider, tlsChallengeProvider)
|
||||
acmeProviders := initACMEProvider(staticConfiguration, providerAggregator, tlsManager, httpChallengeProvider, tlsChallengeProvider, routinesPool)
|
||||
|
||||
// Entrypoints
|
||||
|
||||
@@ -365,7 +364,7 @@ func switchRouter(routerFactory *server.RouterFactory, serverEntryPointsTCP serv
|
||||
}
|
||||
|
||||
// initACMEProvider creates an acme provider from the ACME part of globalConfiguration.
|
||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager, httpChallengeProvider, tlsChallengeProvider challenge.Provider) []*acme.Provider {
|
||||
func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.ProviderAggregator, tlsManager *traefiktls.Manager, httpChallengeProvider, tlsChallengeProvider challenge.Provider, routinesPool *safe.Pool) []*acme.Provider {
|
||||
localStores := map[string]*acme.LocalStore{}
|
||||
|
||||
var resolvers []*acme.Provider
|
||||
@@ -375,7 +374,7 @@ func initACMEProvider(c *static.Configuration, providerAggregator *aggregator.Pr
|
||||
}
|
||||
|
||||
if localStores[resolver.ACME.Storage] == nil {
|
||||
localStores[resolver.ACME.Storage] = acme.NewLocalStore(resolver.ACME.Storage)
|
||||
localStores[resolver.ACME.Storage] = acme.NewLocalStore(resolver.ACME.Storage, routinesPool)
|
||||
}
|
||||
|
||||
p := &acme.Provider{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
RUN apk --no-cache --no-progress add \
|
||||
build-base \
|
||||
@@ -9,13 +9,11 @@ RUN apk --no-cache --no-progress add \
|
||||
ruby \
|
||||
ruby-bigdecimal \
|
||||
ruby-dev \
|
||||
ruby-etc \
|
||||
ruby-ffi \
|
||||
ruby-json \
|
||||
zlib-dev
|
||||
|
||||
RUN gem install nokogiri --version 1.16.8 --no-document -- --use-system-libraries
|
||||
RUN gem install html-proofer --version 5.0.7 --no-document -- --use-system-libraries
|
||||
RUN gem install nokogiri --version 1.18.6 --no-document -- --use-system-libraries
|
||||
RUN gem install html-proofer --version 5.0.10 --no-document -- --use-system-libraries
|
||||
|
||||
# After Ruby, some NodeJS YAY!
|
||||
RUN apk --no-cache --no-progress add \
|
||||
|
||||
@@ -4,23 +4,33 @@
|
||||
|
||||
Below is a non-exhaustive list of versions and their maintenance status:
|
||||
|
||||
| Version | Release Date | Community Support |
|
||||
|---------|--------------|--------------------|
|
||||
| 3.1 | Jul 15, 2024 | Yes |
|
||||
| 3.0 | Apr 29, 2024 | Ended Jul 15, 2024 |
|
||||
| 2.11 | Feb 12, 2024 | Ends Apr 29, 2025 |
|
||||
| 2.10 | Apr 24, 2023 | Ended Feb 12, 2024 |
|
||||
| 2.9 | Oct 03, 2022 | Ended Apr 24, 2023 |
|
||||
| 2.8 | Jun 29, 2022 | Ended Oct 03, 2022 |
|
||||
| 2.7 | May 24, 2022 | Ended Jun 29, 2022 |
|
||||
| 2.6 | Jan 24, 2022 | Ended May 24, 2022 |
|
||||
| 2.5 | Aug 17, 2021 | Ended Jan 24, 2022 |
|
||||
| 2.4 | Jan 19, 2021 | Ended Aug 17, 2021 |
|
||||
| 2.3 | Sep 23, 2020 | Ended Jan 19, 2021 |
|
||||
| 2.2 | Mar 25, 2020 | Ended Sep 23, 2020 |
|
||||
| 2.1 | Dec 11, 2019 | Ended Mar 25, 2020 |
|
||||
| 2.0 | Sep 16, 2019 | Ended Dec 11, 2019 |
|
||||
| 1.7 | Sep 24, 2018 | Ended Dec 31, 2021 |
|
||||
| Version | Release Date | Active Support | Security Support |
|
||||
|---------|--------------|--------------------|-------------------|
|
||||
| 3.5 | Jul 23, 2025 | Yes | Yes |
|
||||
| 3.4 | May 05, 2025 | Ended Jul 23, 2025 | No |
|
||||
| 3.3 | Jan 06, 2025 | Ended May 05, 2025 | No |
|
||||
| 3.2 | Oct 28, 2024 | Ended Jan 06, 2025 | No |
|
||||
| 3.1 | Jul 15, 2024 | Ended Oct 28, 2024 | No |
|
||||
| 3.0 | Apr 29, 2024 | Ended Jul 15, 2024 | No |
|
||||
| 2.11 | Feb 12, 2024 | Ended Apr 29, 2025 | Ends Feb 01, 2026 |
|
||||
| 2.10 | Apr 24, 2023 | Ended Feb 12, 2024 | No |
|
||||
| 2.9 | Oct 03, 2022 | Ended Apr 24, 2023 | No |
|
||||
| 2.8 | Jun 29, 2022 | Ended Oct 03, 2022 | No |
|
||||
| 2.7 | May 24, 2022 | Ended Jun 29, 2022 | No |
|
||||
| 2.6 | Jan 24, 2022 | Ended May 24, 2022 | No |
|
||||
| 2.5 | Aug 17, 2021 | Ended Jan 24, 2022 | No |
|
||||
| 2.4 | Jan 19, 2021 | Ended Aug 17, 2021 | No |
|
||||
| 2.3 | Sep 23, 2020 | Ended Jan 19, 2021 | No |
|
||||
| 2.2 | Mar 25, 2020 | Ended Sep 23, 2020 | No |
|
||||
| 2.1 | Dec 11, 2019 | Ended Mar 25, 2020 | No |
|
||||
| 2.0 | Sep 16, 2019 | Ended Dec 11, 2019 | No |
|
||||
| 1.7 | Sep 24, 2018 | Ended Dec 31, 2021 | No |
|
||||
|
||||
??? example "Active Support / Security Support"
|
||||
|
||||
- **Active support**: Receives any bug fixes.
|
||||
|
||||
- **Security support**: Receives only critical bug and security fixes.
|
||||
|
||||
This page is maintained and updated periodically to reflect our roadmap and any decisions affecting the end of support for Traefik Proxy.
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ services:
|
||||
Start your `reverse-proxy` with the following command:
|
||||
|
||||
```shell
|
||||
docker-compose up -d reverse-proxy
|
||||
docker compose up -d reverse-proxy
|
||||
```
|
||||
|
||||
You can open a browser and go to `http://localhost:8080/api/rawdata` to see Traefik's API rawdata (you'll go back there once you have launched a service in step 2).
|
||||
@@ -68,7 +68,7 @@ The above defines `whoami`: a web service that outputs information about the mac
|
||||
Start the `whoami` service with the following command:
|
||||
|
||||
```shell
|
||||
docker-compose up -d whoami
|
||||
docker compose up -d whoami
|
||||
```
|
||||
|
||||
Go back to your browser (`http://localhost:8080/api/rawdata`) and see that Traefik has automatically detected the new container and updated its own configuration.
|
||||
@@ -92,7 +92,7 @@ IP: 172.27.0.3
|
||||
Run more instances of your `whoami` service with the following command:
|
||||
|
||||
```shell
|
||||
docker-compose up -d --scale whoami=2
|
||||
docker compose up -d --scale whoami=2
|
||||
```
|
||||
|
||||
Go back to your browser (`http://localhost:8080/api/rawdata`) and see that Traefik has automatically detected the new instance of the container.
|
||||
|
||||
@@ -316,17 +316,22 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
|
||||
| Provider Name | Provider Code | Environment Variables | |
|
||||
|------------------------------------------------------------------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
|
||||
| [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) |
|
||||
| [ACME DNS](https://github.com/joohoi/acme-dns) | `acme-dns` | `ACME_DNS_API_BASE`, `ACME_DNS_STORAGE_PATH`, `ACME_DNS_STORAGE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/acme-dns) |
|
||||
| [Active24](https://www.active24.cz) | `active24` | `ACTIVE24_API_KEY`, `ACTIVE24_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/active24) |
|
||||
| [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) |
|
||||
| [all-inkl](https://all-inkl.com) | `allinkl` | `ALL_INKL_LOGIN`, `ALL_INKL_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/allinkl) |
|
||||
| [ArvanCloud](https://www.arvancloud.ir/en) | `arvancloud` | `ARVANCLOUD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/arvancloud) |
|
||||
| [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/) (DEPRECATED) | `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) |
|
||||
| [Axelname](https://axelname.ru) | `axelname` | `AXELNAME_NICKNAME`, `AXELNAME_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/axelname) |
|
||||
| [Azion](https://www.azion.com/en/products/edge-dns/) | `azion` | `AZION_PERSONAL_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/azion) |
|
||||
| [Azure](https://azure.microsoft.com/services/dns/) (DEPRECATED) | `azure` | DEPRECATED use `azuredns` instead. | [Additional configuration](https://go-acme.github.io/lego/dns/azure) |
|
||||
| [AzureDNS](https://azure.microsoft.com/services/dns/) | `azuredns` | `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET`, `AZURE_TENANT_ID`, `AZURE_SUBSCRIPTION_ID`, `AZURE_RESOURCE_GROUP`, `[AZURE_ENVIRONMENT]`, `[AZURE_PRIVATE_ZONE]`, `[AZURE_ZONE_NAME]` | [Additional configuration](https://go-acme.github.io/lego/dns/azuredns) |
|
||||
| [Baidu Cloud](https://cloud.baidu.com) | `baiducloud` | `BAIDUCLOUD_ACCESS_KEY_ID`, `BAIDUCLOUD_SECRET_ACCESS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/baiducloud) |
|
||||
| [Bindman](https://github.com/labbsr0x/bindman-dns-webhook) | `bindman` | `BINDMAN_MANAGER_ADDRESS` | [Additional configuration](https://go-acme.github.io/lego/dns/bindman) |
|
||||
| [Blue Cat](https://www.bluecatnetworks.com/) | `bluecat` | `BLUECAT_SERVER_URL`, `BLUECAT_USER_NAME`, `BLUECAT_PASSWORD`, `BLUECAT_CONFIG_NAME`, `BLUECAT_DNS_VIEW` | [Additional configuration](https://go-acme.github.io/lego/dns/bluecat) |
|
||||
| [Brandit](https://www.brandit.com) (DEPRECATED) | `brandit` | `BRANDIT_API_USERNAME`, `BRANDIT_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/brandit) |
|
||||
| [BookMyName](https://www.bookmyname.com) | `bookmyname` | `BOOKMYNAME_USERNAME`, `BOOKMYNAME_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/bookmyname) |
|
||||
| [Brandit](https://www.brandit.com) (DEPRECATED) | `brandit` | DEPRECATED | [Additional configuration](https://go-acme.github.io/lego/dns/brandit) |
|
||||
| [Bunny](https://bunny.net) | `bunny` | `BUNNY_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/bunny) |
|
||||
| [Checkdomain](https://www.checkdomain.de/) | `checkdomain` | `CHECKDOMAIN_TOKEN`, | [Additional configuration](https://go-acme.github.io/lego/dns/checkdomain/) |
|
||||
| [Civo](https://www.civo.com/) | `civo` | `CIVO_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/civo) |
|
||||
@@ -334,7 +339,8 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [CloudDNS](https://vshosting.eu/) | `clouddns` | `CLOUDDNS_CLIENT_ID`, `CLOUDDNS_EMAIL`, `CLOUDDNS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/clouddns) |
|
||||
| [Cloudflare](https://www.cloudflare.com) | `cloudflare` | `CF_API_EMAIL`, `CF_API_KEY` [^5] or `CF_DNS_API_TOKEN`, `[CF_ZONE_API_TOKEN]` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudflare) |
|
||||
| [ClouDNS](https://www.cloudns.net/) | `cloudns` | `CLOUDNS_AUTH_ID`, `CLOUDNS_AUTH_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudns) |
|
||||
| [CloudXNS](https://www.cloudxns.net) (DEPRECATED) | `cloudxns` | `CLOUDXNS_API_KEY`, `CLOUDXNS_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
|
||||
| [CloudXNS](https://www.cloudxns.net) (DEPRECATED) | `cloudxns` | DEPRECATED | [Additional configuration](https://go-acme.github.io/lego/dns/cloudxns) |
|
||||
| [ConoHa v3](https://www.conoha.jp/) | `conohav3` | `CONOHAV3_TENANT_ID`, `CONOHAV3_API_USER_ID`, `CONOHAV3_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conohav3) |
|
||||
| [ConoHa](https://www.conoha.jp) | `conoha` | `CONOHA_TENANT_ID`, `CONOHA_API_USERNAME`, `CONOHA_API_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/conoha) |
|
||||
| [Constellix](https://constellix.com) | `constellix` | `CONSTELLIX_API_KEY`, `CONSTELLIX_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/constellix) |
|
||||
| [Core-Networks](https://www.core-networks.de) | `corenetworks` | `CORENETWORKS_LOGIN`, `CORENETWORKS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/corenetworks) |
|
||||
@@ -346,18 +352,20 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [DNS Made Easy](https://dnsmadeeasy.com) | `dnsmadeeasy` | `DNSMADEEASY_API_KEY`, `DNSMADEEASY_API_SECRET`, `DNSMADEEASY_SANDBOX` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsmadeeasy) |
|
||||
| [dnsHome.de](https://www.dnshome.de) | `dnsHomede` | `DNSHOMEDE_CREDENTIALS` | [Additional configuration](https://go-acme.github.io/lego/dns/dnshomede) |
|
||||
| [DNSimple](https://dnsimple.com) | `dnsimple` | `DNSIMPLE_OAUTH_TOKEN`, `DNSIMPLE_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/dnsimple) |
|
||||
| [DNSPod](https://www.dnspod.com/) | `dnspod` | `DNSPOD_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) |
|
||||
| [DNSPod](https://www.dnspod.com/) (DEPRECATED) | `dnspod` | DEPRECATED use `tencentcloud` instead. | [Additional configuration](https://go-acme.github.io/lego/dns/dnspod) |
|
||||
| [Domain Offensive (do.de)](https://www.do.de/) | `dode` | `DODE_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/dode) |
|
||||
| [Domeneshop](https://domene.shop) | `domeneshop` | `DOMENESHOP_API_TOKEN`, `DOMENESHOP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/domeneshop) |
|
||||
| [DreamHost](https://www.dreamhost.com/) | `dreamhost` | `DREAMHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dreamhost) |
|
||||
| [Duck DNS](https://www.duckdns.org/) | `duckdns` | `DUCKDNS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/duckdns) |
|
||||
| [Dyn](https://dyn.com) | `dyn` | `DYN_CUSTOMER_NAME`, `DYN_USER_NAME`, `DYN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyn) |
|
||||
| [DynDnsFree.de](https://www.dyndnsfree.de) | `dyndnsfree` | `DYNDNSFREE_USERNAME`, `DYNDNSFREE_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/dyndnsfree) |
|
||||
| [Dynu](https://www.dynu.com) | `dynu` | `DYNU_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/dynu) |
|
||||
| [EasyDNS](https://easydns.com/) | `easydns` | `EASYDNS_TOKEN`, `EASYDNS_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/easydns) |
|
||||
| [EdgeDNS](https://www.akamai.com/) | `edgedns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) |
|
||||
| [Efficient IP](https://efficientip.com) | `efficientip` | `EFFICIENTIP_USERNAME`, `EFFICIENTIP_PASSWORD`, `EFFICIENTIP_HOSTNAME`, `EFFICIENTIP_DNS_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/efficientip) |
|
||||
| [Epik](https://www.epik.com) | `epik` | `EPIK_SIGNATURE` | [Additional configuration](https://go-acme.github.io/lego/dns/epik) |
|
||||
| [Exoscale](https://www.exoscale.com) | `exoscale` | `EXOSCALE_API_KEY`, `EXOSCALE_API_SECRET`, `EXOSCALE_ENDPOINT` | [Additional configuration](https://go-acme.github.io/lego/dns/exoscale) |
|
||||
| [F5 XC](https://www.f5.com/products/distributed-cloud-services) | `f5xc` | `F5XC_API_TOKEN`, `F5XC_TENANT_NAME`, `F5XC_GROUP_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/f5xc) |
|
||||
| [Fast DNS](https://www.akamai.com/) | `fastdns` | `AKAMAI_CLIENT_TOKEN`, `AKAMAI_CLIENT_SECRET`, `AKAMAI_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/edgedns) |
|
||||
| [Freemyip.com](https://freemyip.com) | `freemyip` | `FREEMYIP_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/freemyip) |
|
||||
| [G-Core](https://gcore.com/dns/) | `gcore` | `GCORE_PERMANENT_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/gcore) |
|
||||
@@ -366,7 +374,7 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Glesys](https://glesys.com/) | `glesys` | `GLESYS_API_USER`, `GLESYS_API_KEY`, `GLESYS_DOMAIN` | [Additional configuration](https://go-acme.github.io/lego/dns/glesys) |
|
||||
| [GoDaddy](https://www.godaddy.com) | `godaddy` | `GODADDY_API_KEY`, `GODADDY_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/godaddy) |
|
||||
| [Google Cloud DNS](https://cloud.google.com/dns/docs/) | `gcloud` | `GCE_PROJECT`, Application Default Credentials [^2] [^3], [`GCE_SERVICE_ACCOUNT_FILE`] | [Additional configuration](https://go-acme.github.io/lego/dns/gcloud) |
|
||||
| [Google Domains](https://domains.google) | `googledomains` | `GOOGLE_DOMAINS_ACCESS_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/googledomains) |
|
||||
| [Google Domains](https://domains.google) (DEPRECATED) | `googledomains` | DEPRECATED | [Additional configuration](https://go-acme.github.io/lego/dns/googledomains) |
|
||||
| [Hetzner](https://hetzner.com) | `hetzner` | `HETZNER_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hetzner) |
|
||||
| [hosting.de](https://www.hosting.de) | `hostingde` | `HOSTINGDE_API_KEY`, `HOSTINGDE_ZONE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/hostingde) |
|
||||
| [Hosttech](https://www.hosttech.eu) | `hosttech` | `HOSTTECH_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/hosttech) |
|
||||
@@ -393,9 +401,12 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Loopia](https://loopia.com/) | `loopia` | `LOOPIA_API_PASSWORD`, `LOOPIA_API_USER` | [Additional configuration](https://go-acme.github.io/lego/dns/loopia) |
|
||||
| [LuaDNS](https://luadns.com) | `luadns` | `LUADNS_API_USERNAME`, `LUADNS_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/luadns) |
|
||||
| [Mail-in-a-Box](https://mailinabox.email) | `mailinabox` | `MAILINABOX_EMAIL`, `MAILINABOX_PASSWORD`, `MAILINABOX_BASE_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/mailinabox) |
|
||||
| [ManageEngine CloudDNS](https://clouddns.manageengine.com) | `manageengine` | `MANAGEENGINE_CLIENT_ID`, `MANAGEENGINE_CLIENT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/manageengine) |
|
||||
| [Metaname](https://metaname.net) | `metaname` | `METANAME_ACCOUNT_REFERENCE`, `METANAME_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/metaname) |
|
||||
| [Metaregistrar](https://metaregistrar.com) | `metaregistrar` | `METAREGISTRAR_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/metaregistrar) |
|
||||
| [mijn.host](https://mijn.host/) | `mijnhost` | `MIJNHOST_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/mijnhost) |
|
||||
| [Mittwald](https://www.mittwald.de) | `mittwald` | `MITTWALD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/mittwald) |
|
||||
| [myaddr.{tools,dev,io}](https://myaddr.tools/) | `myaddr` | `MYADDR_PRIVATE_KEYS_MAPPING` | [Additional configuration](https://go-acme.github.io/lego/dns/myaddr) |
|
||||
| [MyDNS.jp](https://www.mydns.jp/) | `mydnsjp` | `MYDNSJP_MASTER_ID`, `MYDNSJP_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mydnsjp) |
|
||||
| [Mythic Beasts](https://www.mythic-beasts.com) | `mythicbeasts` | `MYTHICBEASTS_USER_NAME`, `MYTHICBEASTS_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/mythicbeasts) |
|
||||
| [name.com](https://www.name.com/) | `namedotcom` | `NAMECOM_USERNAME`, `NAMECOM_API_TOKEN`, `NAMECOM_SERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/namedotcom) |
|
||||
@@ -417,12 +428,14 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Porkbun](https://porkbun.com/) | `porkbun` | `PORKBUN_SECRET_API_KEY`, `PORKBUN_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/porkbun) |
|
||||
| [PowerDNS](https://www.powerdns.com) | `pdns` | `PDNS_API_KEY`, `PDNS_API_URL` | [Additional configuration](https://go-acme.github.io/lego/dns/pdns) |
|
||||
| [Rackspace](https://www.rackspace.com/cloud/dns) | `rackspace` | `RACKSPACE_USER`, `RACKSPACE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rackspace) |
|
||||
| [Rainyun/雨云](https://www.rainyun.com) | `rainyun` | `RAINYUN_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rainyun) |
|
||||
| [RcodeZero](https://www.rcodezero.at) | `rcodezero` | `RCODEZERO_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/rcodezero) |
|
||||
| [reg.ru](https://www.reg.ru) | `regru` | `REGRU_USERNAME`, `REGRU_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/regru) |
|
||||
| [Regfish](https://regfish.de) | `regfish` | `regfish` | [Additional configuration](https://go-acme.github.io/lego/dns/regfish) |
|
||||
| [RFC2136](https://tools.ietf.org/html/rfc2136) | `rfc2136` | `RFC2136_TSIG_KEY`, `RFC2136_TSIG_SECRET`, `RFC2136_TSIG_ALGORITHM`, `RFC2136_NAMESERVER` | [Additional configuration](https://go-acme.github.io/lego/dns/rfc2136) |
|
||||
| [RimuHosting](https://rimuhosting.com) | `rimuhosting` | `RIMUHOSTING_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/rimuhosting) |
|
||||
| [Route 53](https://aws.amazon.com/route53/) | `route53` | `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, `[AWS_REGION]`, `[AWS_HOSTED_ZONE_ID]` or a configured user/instance IAM profile. | [Additional configuration](https://go-acme.github.io/lego/dns/route53) |
|
||||
| [RU Center](https://nic.ru/) | `nicru` | `NICRU_USER`, `NICRU_PASSWORD`, `NICRU_SERVICE_ID`, `NICRU_SECRET`, `NICRU_SERVICE_NAME` | [Additional configuration](https://go-acme.github.io/lego/dns/nicru) |
|
||||
| [Sakura Cloud](https://cloud.sakura.ad.jp/) | `sakuracloud` | `SAKURACLOUD_ACCESS_TOKEN`, `SAKURACLOUD_ACCESS_TOKEN_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/sakuracloud) |
|
||||
| [Scaleway](https://www.scaleway.com) | `scaleway` | `SCW_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/scaleway) |
|
||||
| [Selectel v2](https://selectel.ru/en/) | `selectelv2` | `SELECTELV2_ACCOUNT_ID`, `SELECTELV2_PASSWORD`, `SELECTELV2_PROJECT_ID`, `SELECTELV2_USERNAME` | [Additional configuration](https://go-acme.github.io/lego/dns/selectelv2) |
|
||||
@@ -432,6 +445,7 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Shellrent](https://www.shellrent.com) | `shellrent` | `SHELLRENT_USERNAME`, `SHELLRENT_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/shellrent) |
|
||||
| [Simply.com](https://www.simply.com/en/domains/) | `simply` | `SIMPLY_ACCOUNT_NAME`, `SIMPLY_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/simply) |
|
||||
| [Sonic](https://www.sonic.com/) | `sonic` | `SONIC_USER_ID`, `SONIC_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/sonic) |
|
||||
| [Spaceship](https://spaceship.com) | `spaceship` | `SPACESHIP_API_KEY`, `SPACESHIP_API_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/spaceship) |
|
||||
| [Stackpath](https://www.stackpath.com/) | `stackpath` | `STACKPATH_CLIENT_ID`, `STACKPATH_CLIENT_SECRET`, `STACKPATH_STACK_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/stackpath) |
|
||||
| [Technitium](https://technitium.com) | `technitium` | `TECHNITIUM_SERVER_BASE_URL`, `TECHNITIUM_API_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/technitium) |
|
||||
| [Tencent Cloud DNS](https://cloud.tencent.com/product/cns) | `tencentcloud` | `TENCENTCLOUD_SECRET_ID`, `TENCENTCLOUD_SECRET_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/tencentcloud) |
|
||||
@@ -451,10 +465,12 @@ For complete details, refer to your provider's _Additional configuration_ link.
|
||||
| [Webnames](https://www.webnames.ru/) | `webnames` | `WEBNAMES_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/webnames) |
|
||||
| [Websupport](https://websupport.sk) | `websupport` | `WEBSUPPORT_API_KEY`, `WEBSUPPORT_SECRET` | [Additional configuration](https://go-acme.github.io/lego/dns/websupport) |
|
||||
| [WEDOS](https://www.wedos.com) | `wedos` | `WEDOS_USERNAME`, `WEDOS_WAPI_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/wedos) |
|
||||
| [West.cn/西部数码](https://www.west.cn) | `westcn` | `WESTCN_USERNAME`, `WESTCN_PASSWORD` | [Additional configuration](https://go-acme.github.io/lego/dns/westcn) |
|
||||
| [Yandex 360](https://360.yandex.ru) | `yandex360` | `YANDEX360_OAUTH_TOKEN`, `YANDEX360_ORG_ID` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex360) |
|
||||
| [Yandex Cloud](https://cloud.yandex.com/en/) | `yandexcloud` | `YANDEX_CLOUD_FOLDER_ID`, `YANDEX_CLOUD_IAM_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandexcloud) |
|
||||
| [Yandex](https://yandex.com) | `yandex` | `YANDEX_PDD_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/yandex) |
|
||||
| [Zone.ee](https://www.zone.ee) | `zoneee` | `ZONEEE_API_USER`, `ZONEEE_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneee) |
|
||||
| [ZoneEdit](https://www.zoneedit.com) | `zoneedit` | `ZONEEDIT_USER`, `ZONEEDIT_AUTH_TOKEN` | [Additional configuration](https://go-acme.github.io/lego/dns/zoneedit) |
|
||||
| [Zonomi](https://zonomi.com) | `zonomi` | `ZONOMI_API_KEY` | [Additional configuration](https://go-acme.github.io/lego/dns/zonomi) |
|
||||
| External Program | `exec` | `EXEC_PATH` | [Additional configuration](https://go-acme.github.io/lego/dns/exec) |
|
||||
| HTTP request | `httpreq` | `HTTPREQ_ENDPOINT`, `HTTPREQ_MODE`, `HTTPREQ_USERNAME`, `HTTPREQ_PASSWORD` [^1] | [Additional configuration](https://go-acme.github.io/lego/dns/httpreq) |
|
||||
|
||||
@@ -242,7 +242,7 @@ The TLS options allow one to configure some parameters of the TLS connection.
|
||||
|
||||
!!! important "TLSOption in Kubernetes"
|
||||
|
||||
When using the [TLSOption resource](../../routing/providers/kubernetes-crd#kind-tlsoption) in Kubernetes, one might setup a default set of options that,
|
||||
When using the [TLSOption resource](../../routing/providers/kubernetes-crd/#kind-tlsoption) in Kubernetes, one might setup a default set of options that,
|
||||
if not explicitly overwritten, should apply to all ingresses.
|
||||
To achieve that, you'll have to create a TLSOption resource with the name `default`.
|
||||
There may exist only one TLSOption with the name `default` (across all namespaces) - otherwise they will be dropped.
|
||||
@@ -392,11 +392,11 @@ spec:
|
||||
|
||||
### Curve Preferences
|
||||
|
||||
This option allows to set the preferred elliptic curves in a specific order.
|
||||
This option allows to set the enabled elliptic curves for key exchange.
|
||||
|
||||
The names of the curves defined by [`crypto`](https://godoc.org/crypto/tls#CurveID) (e.g. `CurveP521`) and the [RFC defined names](https://tools.ietf.org/html/rfc8446#section-4.2.7) (e. g. `secp521r1`) can be used.
|
||||
|
||||
See [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
See [CurvePreferences](https://godoc.org/crypto/tls#Config.CurvePreferences) and [CurveID](https://godoc.org/crypto/tls#CurveID) for more information.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
# Dynamic configuration
|
||||
|
||||
@@ -21,7 +21,7 @@ The BasicAuth middleware grants access to services to authorized users only.
|
||||
# To create user:password pair, it's possible to use this command:
|
||||
# echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
|
||||
#
|
||||
# Also note that dollar signs should NOT be doubled when they not evaluated (e.g. Ansible docker_container module).
|
||||
# Also note that dollar signs should NOT be doubled when they are not being evaluated (e.g. Ansible docker_container module).
|
||||
labels:
|
||||
- "traefik.http.middlewares.test-auth.basicauth.users=test:$$apr1$$H6uskkkW$$IgXLP6ewTrSuBkTrqE8wj/,test2:$$apr1$$d9hr9HBB$$4HxwgUir3HP4EsggP/QNo0"
|
||||
```
|
||||
|
||||
@@ -331,3 +331,7 @@ The retry expression is defined as a logical combination of the functions below
|
||||
- `Attempts()` number of attempts (the first one counts)
|
||||
- `ResponseCode()` response code of the service
|
||||
- `IsNetworkError()` whether the response code is related to networking error
|
||||
|
||||
### Content-Length
|
||||
|
||||
See [Best Practices: Content‑Length](../../security/content-length.md)
|
||||
|
||||
@@ -12,8 +12,11 @@ Retrying until it Succeeds
|
||||
TODO: add schema
|
||||
-->
|
||||
|
||||
The Retry middleware reissues requests a given number of times to a backend server if that server does not reply.
|
||||
As soon as the server answers, the middleware stops retrying, regardless of the response status.
|
||||
The Retry middleware reissues requests a given number of times when it cannot contact the backend service.
|
||||
This applies at the transport level (TCP).
|
||||
If the service does not respond to the initial connection attempt, the middleware retries.
|
||||
However, once the service responds, regardless of the HTTP status code, the middleware considers it operational and stops retrying.
|
||||
This means that the retry mechanism does not handle HTTP errors; it only retries when there is no response at the TCP level.
|
||||
The Retry middleware has an optional configuration to enable an exponential backoff.
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -656,3 +656,81 @@ Please check out the [entrypoint forwarded headers connection option configurati
|
||||
|
||||
In `v2.11.14`, the `X-Forwarded-Prefix` header is now handled like the other `X-Forwarded-*` headers: Traefik removes it when it's sent from an untrusted source.
|
||||
Please refer to the Forwarded headers [documentation](../routing/entrypoints.md#forwarded-headers) for more details.
|
||||
|
||||
## v2.11.24
|
||||
|
||||
### Request Path Sanitization
|
||||
|
||||
Since `v2.11.24`, the incoming request path is now cleaned before being used to match the router rules and sent to the backends.
|
||||
Any `/../`, `/./` or duplicate slash segments in the request path is interpreted and/or collapsed.
|
||||
|
||||
If you want to disable this behavior, you can set the [`sanitizePath` option](../routing/entrypoints.md#sanitizepath) to `false` in the entryPoint HTTP configuration.
|
||||
This can be useful when dealing with legacy clients that are not url-encoding data in the request path.
|
||||
For example, as base64 uses the “/” character internally,
|
||||
if it's not url encoded,
|
||||
it can lead to unsafe routing when the `sanitizePath` option is set to `false`.
|
||||
|
||||
!!! warning "Security"
|
||||
|
||||
Setting the `sanitizePath` option to `false` is not safe.
|
||||
Ensure every request is properly url encoded instead.
|
||||
|
||||
## v2.11.25
|
||||
|
||||
### Request Path Normalization
|
||||
|
||||
Since `v2.11.25`, the request path is now normalized by decoding unreserved characters in the request path,
|
||||
and also uppercasing the percent-encoded characters.
|
||||
This follows [RFC 3986 percent-encoding normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.2),
|
||||
and [RFC 3986 case normalization](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1).
|
||||
|
||||
The normalization happens before the request path is sanitized,
|
||||
and cannot be disabled.
|
||||
This notably helps with encoded dots characters (which are unreserved characters) to be sanitized properly.
|
||||
|
||||
### Routing Path
|
||||
|
||||
Since `v2.11.25`, the reserved characters [(as per RFC 3986)](https://datatracker.ietf.org/doc/html/rfc3986#section-2.2) are kept encoded in the request path when matching the router rules.
|
||||
Those characters, when decoded, change the meaning of the request path for routing purposes,
|
||||
and Traefik now keeps them encoded to avoid any ambiguity.
|
||||
|
||||
### Request Path Matching Examples
|
||||
|
||||
| Request Path | Router Rule | Traefik v2.11.24 | Traefik v2.11.25 |
|
||||
|-------------------|------------------------|------------------|------------------|
|
||||
| `/foo%2Fbar` | PathPrefix(`/foo/bar`) | Match | No match |
|
||||
| `/foo/../bar` | PathPrefix(`/foo`) | No match | No match |
|
||||
| `/foo/../bar` | PathPrefix(`/bar`) | Match | Match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/foo`) | Match | No match |
|
||||
| `/foo/%2E%2E/bar` | PathPrefix(`/bar`) | No match | Match |
|
||||
|
||||
## v2.11.28
|
||||
|
||||
### MultiPath TCP
|
||||
|
||||
Since `v2.11.28`, the MultiPath TCP support introduced with `v2.11.26` has been removed.
|
||||
It appears that enabling MPTCP on some platforms can cause Traefik to stop with the following error logs message:
|
||||
|
||||
- `set tcp X.X.X.X:X->X.X.X.X:X: setsockopt: operation not supported`
|
||||
|
||||
However, it can be re-enabled by setting the `multipathtcp` variable in the GODEBUG environment variable, see the related [go documentation](https://go.dev/doc/godebug#go-124).
|
||||
|
||||
## v2.11.32
|
||||
|
||||
## Encoded Characters in Request Path
|
||||
|
||||
Since `v2.11.32`, for security reasons Traefik now rejects requests with a path containing a specific set of encoded characters by default.
|
||||
When such a request is received, Traefik responds with a `400 Bad Request` status code.
|
||||
Here is the list of the encoded characters that are rejected by default, along with the corresponding configuration option to allow them:
|
||||
|
||||
| Encoded Character | Character | Config option to allow the encoded character |
|
||||
|-------------------|-------------------------|--------------------------------------------------------------------------------------|
|
||||
| `%2f` or `%2F` | `/` (slash) | `entryPoints.<name>`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSlash` |
|
||||
| `%5c` or `%5C` | `\` (backslash) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedBackSlash` |
|
||||
| `%00` | `NULL` (null character) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedNullCharacter` |
|
||||
| `%3b` or `%3B` | `;` (semicolon) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedSemicolon` |
|
||||
| `%25` | `%` (percent) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedPercent` |
|
||||
| `%3f` or `%3F` | `?` (question mark) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedQuestionMark` |
|
||||
| `%23` | `#` (hash) | `entryPoints.<name>.`<br/>`.http.encodedCharacters`<br/>`.allowEncodedHash` |
|
||||
|
||||
Please check out the entrypoint [encodedCharacters option](../routing/entrypoints.md#encoded-characters) documentation for more details.
|
||||
|
||||
@@ -236,9 +236,7 @@ accessLog:
|
||||
| `OriginDuration` | The time taken (in nanoseconds) by the origin server ('upstream') to return its response. |
|
||||
| `OriginContentSize` | The content length specified by the origin server, or 0 if unspecified. |
|
||||
| `OriginStatus` | The HTTP status code returned by the origin server. If the request was handled by this Traefik instance (e.g. with a redirect), then this value will be absent (0). |
|
||||
| `OriginStatusLine` | `OriginStatus` + Status code explanation |
|
||||
| `DownstreamStatus` | The HTTP status code returned to the client. |
|
||||
| `DownstreamStatusLine` | `DownstreamStatus` + Status code explanation |
|
||||
| `DownstreamContentSize` | The number of bytes in the response entity returned to the client. This is in addition to the "Content-Length" header, which may be present in the origin response. |
|
||||
| `RequestCount` | The number of requests received since the Traefik instance started. |
|
||||
| `GzipRatio` | The response body compression ratio achieved. |
|
||||
|
||||
@@ -46,7 +46,7 @@ And then define a routing configuration on Traefik itself with the
|
||||
|
||||
--8<-- "content/operations/include-api-examples.md"
|
||||
|
||||
??? warning "The router's [rule](../../routing/routers#rule) must catch requests for the URI path `/api`"
|
||||
??? warning "The router's [rule](../../routing/routers/#rule) must catch requests for the URI path `/api`"
|
||||
Using an "Host" rule is recommended, by catching all the incoming traffic on this host domain to the API.
|
||||
However, you can also use "path prefix" rule or any combination or rules.
|
||||
|
||||
|
||||
@@ -301,7 +301,8 @@ _Optional_
|
||||
If `region` is not provided, it is resolved from the EC2 metadata endpoint for EC2 tasks.
|
||||
In a FARGATE context it is resolved from the `AWS_REGION` environment variable.
|
||||
|
||||
If `accessKeyID` and `secretAccessKey` are not provided, credentials are resolved in the following order:
|
||||
If `accessKeyID` and `secretAccessKey` are not provided, credentials are resolved in the order specified by the
|
||||
[default credential chain of AWS SDK for Go V2](https://docs.aws.amazon.com/sdk-for-go/v2/developer-guide/configure-gosdk.html#specifying-credentials):
|
||||
|
||||
- Using the environment variables `AWS_ACCESS_KEY_ID`, `AWS_SECRET_ACCESS_KEY`, and `AWS_SESSION_TOKEN`.
|
||||
- Using shared credentials, determined by `AWS_PROFILE` and `AWS_SHARED_CREDENTIALS_FILE`, defaults to `default` and `~/.aws/credentials`.
|
||||
|
||||
@@ -10,6 +10,12 @@ A Story of KV store & Containers
|
||||
|
||||
Store your configuration in Redis and let Traefik do the rest!
|
||||
|
||||
!!! tip "Dynamic configuration updates"
|
||||
|
||||
Dynamic configuration updates require Redis [keyspace notifications](https://redis.io/docs/latest/develop/use/keyspace-notifications) to be enabled.
|
||||
Cloud-managed Redis services (e.g., GCP Memorystore, AWS ElastiCache) may disable this by default due to CPU performance issues.
|
||||
For more information, see the [Redis](https://redis.io/docs/latest/develop/use/keyspace-notifications/) documentation or refer to your cloud provider's documentation for specific configuration steps.
|
||||
|
||||
## Routing Configuration
|
||||
|
||||
See the dedicated section in [routing](../routing/providers/kv.md).
|
||||
|
||||
@@ -1478,7 +1478,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -1497,7 +1497,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -1886,7 +1886,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
@@ -3908,7 +3908,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -3927,7 +3927,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -4316,7 +4316,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
CODE GENERATED AUTOMATICALLY
|
||||
THIS FILE MUST NOT BE EDITED BY HAND
|
||||
-->
|
||||
|
||||
| Key (Path) | Value |
|
||||
|------------|-------|
|
||||
| `traefik/http/middlewares/Middleware01/addPrefix/prefix` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware02/basicAuth/headerField` | `foobar` |
|
||||
| `traefik/http/middlewares/Middleware02/basicAuth/realm` | `foobar` |
|
||||
|
||||
@@ -8,6 +8,4 @@ description: "Read the technical documentation to learn the Traefik Dynamic Conf
|
||||
Dynamic configuration with KV stores.
|
||||
{: .subtitle }
|
||||
|
||||
| Key (Path) | Value |
|
||||
|----------------------------------------------------------------------------------------------|-------------|
|
||||
--8<-- "content/reference/dynamic-configuration/kv-ref.md"
|
||||
|
||||
@@ -863,7 +863,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -882,7 +882,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
|
||||
@@ -78,7 +78,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -863,7 +863,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -882,7 +882,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
|
||||
@@ -78,7 +78,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
@@ -123,6 +123,30 @@ Trust only forwarded headers from selected IPs.
|
||||
`--entrypoints.<name>.http`:
|
||||
HTTP configuration.
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters`:
|
||||
Defines which encoded characters are allowed in the request path.
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodedbackslash`:
|
||||
Defines whether requests with encoded back slash characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodedhash`:
|
||||
Defines whether requests with encoded hash characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodednullcharacter`:
|
||||
Defines whether requests with encoded null characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodedpercent`:
|
||||
Defines whether requests with encoded percent characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodedquestionmark`:
|
||||
Defines whether requests with encoded question mark characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodedsemicolon`:
|
||||
Defines whether requests with encoded semicolon characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodedcharacters.allowencodedslash`:
|
||||
Defines whether requests with encoded slash characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`--entrypoints.<name>.http.encodequerysemicolons`:
|
||||
Defines whether request query semicolons should be URLEncoded. (Default: ```false```)
|
||||
|
||||
@@ -141,6 +165,9 @@ Scheme used for the redirection. (Default: ```https```)
|
||||
`--entrypoints.<name>.http.redirections.entrypoint.to`:
|
||||
Targeted entry point of the redirection.
|
||||
|
||||
`--entrypoints.<name>.http.sanitizepath`:
|
||||
Defines whether to enable request path sanitization (removal of /./, /../ and multiple slash sequences). (Default: ```true```)
|
||||
|
||||
`--entrypoints.<name>.http.tls`:
|
||||
Default TLS configuration for the routers linked to the entry point. (Default: ```false```)
|
||||
|
||||
|
||||
@@ -132,6 +132,30 @@ HTTP/3 configuration. (Default: ```false```)
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP3_ADVERTISEDPORT`:
|
||||
UDP port to advertise, on which HTTP/3 is available. (Default: ```0```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS`:
|
||||
Defines which encoded characters are allowed in the request path.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDBACKSLASH`:
|
||||
Defines whether requests with encoded back slash characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDHASH`:
|
||||
Defines whether requests with encoded hash characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDNULLCHARACTER`:
|
||||
Defines whether requests with encoded null characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDPERCENT`:
|
||||
Defines whether requests with encoded percent characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDQUESTIONMARK`:
|
||||
Defines whether requests with encoded question mark characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDSEMICOLON`:
|
||||
Defines whether requests with encoded semicolon characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEDCHARACTERS_ALLOWENCODEDSLASH`:
|
||||
Defines whether requests with encoded slash characters in the path are allowed. (Default: ```false```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_ENCODEQUERYSEMICOLONS`:
|
||||
Defines whether request query semicolons should be URLEncoded. (Default: ```false```)
|
||||
|
||||
@@ -150,6 +174,9 @@ Scheme used for the redirection. (Default: ```https```)
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_REDIRECTIONS_ENTRYPOINT_TO`:
|
||||
Targeted entry point of the redirection.
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_SANITIZEPATH`:
|
||||
Defines whether to enable request path sanitization (removal of /./, /../ and multiple slash sequences). (Default: ```true```)
|
||||
|
||||
`TRAEFIK_ENTRYPOINTS_<NAME>_HTTP_TLS`:
|
||||
Default TLS configuration for the routers linked to the entry point. (Default: ```false```)
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
[entryPoints.EntryPoint0.http]
|
||||
middlewares = ["foobar", "foobar"]
|
||||
encodeQuerySemicolons = true
|
||||
sanitizePath = true
|
||||
[entryPoints.EntryPoint0.http.redirections]
|
||||
[entryPoints.EntryPoint0.http.redirections.entryPoint]
|
||||
to = "foobar"
|
||||
@@ -54,6 +55,14 @@
|
||||
[[entryPoints.EntryPoint0.http.tls.domains]]
|
||||
main = "foobar"
|
||||
sans = ["foobar", "foobar"]
|
||||
[entryPoints.EntryPoint0.http.encodedCharacters]
|
||||
allowEncodedSlash = true
|
||||
allowEncodedBackSlash = true
|
||||
allowEncodedNullCharacter = true
|
||||
allowEncodedSemicolon = true
|
||||
allowEncodedPercent = true
|
||||
allowEncodedQuestionMark = true
|
||||
allowEncodedHash = true
|
||||
[entryPoints.EntryPoint0.http2]
|
||||
maxConcurrentStreams = 42
|
||||
[entryPoints.EntryPoint0.http3]
|
||||
|
||||
@@ -62,7 +62,16 @@ entryPoints:
|
||||
sans:
|
||||
- foobar
|
||||
- foobar
|
||||
encodedCharacters:
|
||||
allowEncodedSlash: true
|
||||
allowEncodedBackSlash: true
|
||||
allowEncodedNullCharacter: true
|
||||
allowEncodedSemicolon: true
|
||||
allowEncodedPercent: true
|
||||
allowEncodedQuestionMark: true
|
||||
allowEncodedHash: true
|
||||
encodeQuerySemicolons: true
|
||||
sanitizePath: true
|
||||
http2:
|
||||
maxConcurrentStreams: 42
|
||||
http3:
|
||||
|
||||
@@ -127,6 +127,14 @@ They can be defined by using a file (YAML or TOML) or CLI arguments.
|
||||
trustedIPs:
|
||||
- "127.0.0.1"
|
||||
- "192.168.0.1"
|
||||
encodedCharacters:
|
||||
allowEncodedSlash: true
|
||||
allowEncodedBackSlash: true
|
||||
allowEncodedNullCharacter: true
|
||||
allowEncodedSemicolon: true
|
||||
allowEncodedPercent: true
|
||||
allowEncodedQuestionMark: true
|
||||
allowEncodedHash: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
@@ -152,6 +160,14 @@ They can be defined by using a file (YAML or TOML) or CLI arguments.
|
||||
[entryPoints.name.forwardedHeaders]
|
||||
insecure = true
|
||||
trustedIPs = ["127.0.0.1", "192.168.0.1"]
|
||||
[entryPoints.name.encodedCharacters]
|
||||
allowEncodedSlash = true
|
||||
allowEncodedBackSlash = true
|
||||
allowEncodedNullCharacter = true
|
||||
allowEncodedSemicolon = true
|
||||
allowEncodedPercent = true
|
||||
allowEncodedQuestionMark = true
|
||||
allowEncodedHash = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
@@ -168,6 +184,13 @@ They can be defined by using a file (YAML or TOML) or CLI arguments.
|
||||
--entryPoints.name.proxyProtocol.trustedIPs=127.0.0.1,192.168.0.1
|
||||
--entryPoints.name.forwardedHeaders.insecure=true
|
||||
--entryPoints.name.forwardedHeaders.trustedIPs=127.0.0.1,192.168.0.1
|
||||
--entryPoints.name.encodedCharacters.allowEncodedSlash=true
|
||||
--entryPoints.name.encodedCharacters.allowEncodedBackSlash=true
|
||||
--entryPoints.name.encodedCharacters.allowEncodedNullCharacter=true
|
||||
--entryPoints.name.encodedCharacters.allowEncodedSemicolon=true
|
||||
--entryPoints.name.encodedCharacters.allowEncodedPercent=true
|
||||
--entryPoints.name.encodedCharacters.allowEncodedQuestionMark=true
|
||||
--entryPoints.name.encodedCharacters.allowEncodedHash=true
|
||||
```
|
||||
|
||||
### Address
|
||||
@@ -254,8 +277,7 @@ entryPoints:
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.foo]
|
||||
[entryPoints.foo.allowACMEByPass]
|
||||
allowACMEByPass = true
|
||||
allowACMEByPass = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
@@ -456,6 +478,232 @@ You can configure Traefik to trust the forwarded headers information (`X-Forward
|
||||
--entryPoints.web.forwardedHeaders.connection=foobar
|
||||
```
|
||||
|
||||
### Encoded Characters
|
||||
|
||||
You can configure Traefik to control the handling of encoded characters in request paths for security purposes.
|
||||
By default, Traefik rejects requests containing certain encoded characters that could be used in path traversal or other security attacks.
|
||||
|
||||
!!! warning "Security Considerations"
|
||||
|
||||
Allowing certain encoded characters may expose your application to security vulnerabilities.
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedSlash`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded slash characters (`%2F` or `%2f`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedSlash: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedSlash = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedSlash=true
|
||||
```
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedBackSlash`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded back slash characters (`%5C` or `%5c`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedBackSlash: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedBackSlash = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedBackSlash=true
|
||||
```
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedNullCharacter`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded null characters (`%00`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedNullCharacter: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedNullCharacter = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedNullCharacter=true
|
||||
```
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedSemicolon`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded semicolon characters (`%3B` or `%3b`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedSemicolon: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedSemicolon = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedSemicolon=true
|
||||
```
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedPercent`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded percent characters (`%25`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedPercent: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedPercent = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedPercent=true
|
||||
```
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedQuestionMark`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded question mark characters (`%3F` or `%3f`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedQuestionMark: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedQuestionMark = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedQuestionMark=true
|
||||
```
|
||||
|
||||
??? info "`encodedCharacters.allowEncodedHash`"
|
||||
|
||||
_Optional, Default=false_
|
||||
|
||||
Controls whether requests with encoded hash characters (`%23`) in the path are allowed.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
## Static configuration
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
encodedCharacters:
|
||||
allowEncodedHash: true
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
## Static configuration
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":80"
|
||||
|
||||
[entryPoints.web.encodedCharacters]
|
||||
allowEncodedHash = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
## Static configuration
|
||||
--entryPoints.web.address=:80
|
||||
--entryPoints.web.encodedCharacters.allowEncodedHash=true
|
||||
```
|
||||
|
||||
### Transport
|
||||
|
||||
#### `respondingTimeouts`
|
||||
@@ -995,6 +1243,56 @@ entryPoints:
|
||||
| false | foo=bar&baz=bar;foo | foo=bar&baz=bar&foo |
|
||||
| true | foo=bar&baz=bar;foo | foo=bar&baz=bar%3Bfoo |
|
||||
|
||||
### SanitizePath
|
||||
|
||||
_Optional, Default=true_
|
||||
|
||||
The `sanitizePath` option defines whether to enable the request path sanitization.
|
||||
When disabled, the incoming request path is passed to the backend as is.
|
||||
This can be useful when dealing with legacy clients that are not url-encoding data in the request path.
|
||||
For example, as base64 uses the “/” character internally,
|
||||
if it's not url encoded,
|
||||
it can lead to unsafe routing when the `sanitizePath` option is set to `false`.
|
||||
|
||||
!!! warning "Security"
|
||||
|
||||
Setting the sanitizePath option to false is not safe.
|
||||
Ensure every request is properly url encoded instead.
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
entryPoints:
|
||||
websecure:
|
||||
address: ':443'
|
||||
http:
|
||||
sanitizePath: false
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.websecure]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.websecure.http]
|
||||
sanitizePath = false
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.sanitizePath=false
|
||||
```
|
||||
|
||||
#### Examples
|
||||
|
||||
| SanitizePath | Request Path | Resulting Request Path |
|
||||
|--------------|-----------------|------------------------|
|
||||
| false | /./foo/bar | /./foo/bar |
|
||||
| true | /./foo/bar | /foo/bar |
|
||||
| false | /foo/../bar | /foo/../bar |
|
||||
| true | /foo/../bar | /bar |
|
||||
| false | /foo/bar// | /foo/bar// |
|
||||
| true | /foo/bar// | /foo/bar/ |
|
||||
| false | /./foo/../bar// | /./foo/../bar// |
|
||||
| true | /./foo/../bar// | /bar/ |
|
||||
|
||||
### Middlewares
|
||||
|
||||
The list of middlewares that are prepended by default to the list of middlewares of each router associated to the named entry point.
|
||||
|
||||
@@ -10,8 +10,8 @@ What's Happening to the Requests?
|
||||
|
||||
Let's zoom in on Traefik's architecture and talk about the components that enable the routes to be created.
|
||||
|
||||
First, when you start Traefik, you define [entrypoints](../entrypoints) (in their most basic forms, they are port numbers).
|
||||
Then, connected to these entrypoints, [routers](../routers) analyze the incoming requests to see if they match a set of [rules](../routers#rule).
|
||||
First, when you start Traefik, you define [entrypoints](../entrypoints/) (in their most basic forms, they are port numbers).
|
||||
Then, connected to these entrypoints, [routers](../routers/) analyze the incoming requests to see if they match a set of [rules](../routers/#rule).
|
||||
If they do, the router might transform the request using pieces of [middleware](../middlewares/overview.md) before forwarding them to your [services](./services/index.md).
|
||||
|
||||

|
||||
@@ -325,6 +325,11 @@ serversTransport:
|
||||
--serversTransport.maxIdleConnsPerHost=7
|
||||
```
|
||||
|
||||
!!! info "Disable connection reuse"
|
||||
|
||||
The default value of `maxIdleConnsPerHost` is 2, and the zero value is the fallback to the default (2).
|
||||
If you want to disable connection reuse, set `maxIdleConnsPerHost` to -1.
|
||||
|
||||
### `forwardingTimeouts`
|
||||
|
||||
`forwardingTimeouts` is about a number of timeouts relevant to when forwarding requests to the backend servers.
|
||||
|
||||
@@ -1644,7 +1644,7 @@ or referencing TLS options in the [`IngressRoute`](#kind-ingressroute) / [`Ingre
|
||||
| [2] | `minVersion` | Defines the [minimum TLS version](../../https/tls.md#minimum-tls-version) that is acceptable. |
|
||||
| [3] | `maxVersion` | Defines the [maximum TLS version](../../https/tls.md#maximum-tls-version) that is acceptable. |
|
||||
| [4] | `cipherSuites` | list of supported [cipher suites](../../https/tls.md#cipher-suites) for TLS versions up to TLS 1.2. |
|
||||
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake, in preference order. |
|
||||
| [5] | `curvePreferences` | List of the [elliptic curves references](../../https/tls.md#curve-preferences) that will be used in an ECDHE handshake. |
|
||||
| [6] | `clientAuth` | determines the server's policy for TLS [Client Authentication](../../https/tls.md#client-authentication-mtls). |
|
||||
| [7] | `clientAuth.secretNames` | list of names of the referenced Kubernetes [Secrets](https://kubernetes.io/docs/concepts/configuration/secret/) (in TLSOption namespace). The secret must contain a certificate under either a `tls.ca` or a `ca.crt` key. |
|
||||
| [8] | `clientAuth.clientAuthType` | defines the client authentication type to apply. The available values are: `NoClientCert`, `RequestClientCert`, `VerifyClientCertIfGiven` and `RequireAndVerifyClientCert`. |
|
||||
|
||||
@@ -907,7 +907,7 @@ TLS certificates can be managed in Secrets objects.
|
||||
whether the LB's children are directly the pods IPs or if the only child is the Kubernetes Service clusterIP.
|
||||
|
||||
One alternative is to use an `ExternalName` service to forward requests to the Kubernetes service through DNS.
|
||||
To do so, one must [allow external name services](https://doc.traefik.io/traefik/providers/kubernetes-ingress/#allowexternalnameservices "Link to docs about allowing external name services").
|
||||
To do so, one must [allow external name services](../../../providers/kubernetes-ingress/#allowexternalnameservices "Link to docs about allowing external name services").
|
||||
|
||||
Traefik automatically requests endpoint information based on the service provided in the ingress spec.
|
||||
Although Traefik will connect directly to the endpoints (pods),
|
||||
|
||||
27
docs/content/security/content-length.md
Normal file
27
docs/content/security/content-length.md
Normal file
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: "Content-Length"
|
||||
description: "Enforce strict Content‑Length validation in Traefik by streaming or full buffering to prevent truncated or over‑long requests and responses. Read the technical documentation."
|
||||
---
|
||||
|
||||
Traefik acts as a streaming proxy. By default, it checks each chunk of data against the `Content-Length` header as it passes it on to the backend or client.
|
||||
This live check blocks truncated or over‑long streams without holding the entire message.
|
||||
|
||||
If you need Traefik to read and verify the full body before any data moves on, add the [buffering middleware](../middlewares/http/buffering.md):
|
||||
|
||||
```yaml
|
||||
http:
|
||||
middlewares:
|
||||
buffer-and-validate:
|
||||
buffering: {}
|
||||
```
|
||||
|
||||
With buffering enabled, Traefik will:
|
||||
|
||||
- Read the entire request or response into memory.
|
||||
- Compare the actual byte count to the `Content-Length` header.
|
||||
- Reject the message if the counts do not match.
|
||||
|
||||
!!! warning
|
||||
|
||||
Buffering adds overhead. Every request and response is held in full before forwarding, which can increase memory use and latency.
|
||||
Use it when strict content validation is critical to your security posture.
|
||||
129
docs/content/security/request-path.md
Normal file
129
docs/content/security/request-path.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
title: "Request Path Security"
|
||||
description: "Learn how Traefik processes and secures request paths through sanitization and encoded character filtering to protect against path traversal and injection attacks."
|
||||
---
|
||||
|
||||
# Request Path
|
||||
|
||||
Protecting Against Path-Based Attacks Through Sanitization and Filtering
|
||||
{: .subtitle }
|
||||
|
||||
Traefik implements multiple layers of security when processing incoming request paths.
|
||||
This includes path sanitization to normalize potentially dangerous sequences and encoded character filtering to prevent attack vectors that use URL encoding.
|
||||
Understanding how Traefik handles request paths is crucial for maintaining a secure routing infrastructure.
|
||||
|
||||
## How Traefik Processes Request Paths
|
||||
|
||||
When Traefik receives an HTTP request, it processes the request path through several security-focused stages:
|
||||
|
||||
### 1. Encoded Character Filtering
|
||||
|
||||
Traefik inspects the path for potentially dangerous encoded characters and rejects requests containing them unless explicitly allowed.
|
||||
|
||||
Here is the list of the encoded characters that are rejected by default:
|
||||
|
||||
| Encoded Character | Character |
|
||||
|-------------------|-------------------------|
|
||||
| `%2f` or `%2F` | `/` (slash) |
|
||||
| `%5c` or `%5C` | `\` (backslash) |
|
||||
| `%00` | `NULL` (null character) |
|
||||
| `%3b` or `%3B` | `;` (semicolon) |
|
||||
| `%25` | `%` (percent) |
|
||||
| `%3f` or `%3F` | `?` (question mark) |
|
||||
| `%23` | `#` (hash) |
|
||||
|
||||
### 2. Path Normalization
|
||||
|
||||
Traefik normalizes the request path by decoding the unreserved percent-encoded characters,
|
||||
as they are equivalent to their non-encoded form (according to [rfc3986#section-2.3](https://datatracker.ietf.org/doc/html/rfc3986#section-2.3)),
|
||||
and capitalizing the percent-encoded characters (according to [rfc3986#section-6.2.2.1](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.1)).
|
||||
|
||||
### 3. Path Sanitization
|
||||
|
||||
Traefik sanitizes request paths to prevent common attack vectors,
|
||||
by removing the `..`, `.` and duplicate slash segments from the URL (according to [rfc3986#section-6.2.2.3](https://datatracker.ietf.org/doc/html/rfc3986#section-6.2.2.3)).
|
||||
|
||||
## Path Security Configuration
|
||||
|
||||
Traefik provides two main mechanisms for path security that work together to protect your applications.
|
||||
|
||||
### Path Sanitization
|
||||
|
||||
Path sanitization is enabled by default and helps prevent directory traversal attacks by normalizing request paths.
|
||||
Configure it in the [EntryPoints](../routing/entrypoints.md#sanitizepath) HTTP section:
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
entryPoints:
|
||||
websecure:
|
||||
address: ":443"
|
||||
http:
|
||||
sanitizePath: true # Default: true (recommended)
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.websecure]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.websecure.http]
|
||||
sanitizePath = true
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.http.sanitizePath=true
|
||||
```
|
||||
|
||||
**Sanitization behavior:**
|
||||
|
||||
- `./foo/bar` → `/foo/bar` (removes relative current directory)
|
||||
- `/foo/../bar` → `/bar` (resolves parent directory traversal)
|
||||
- `/foo/bar//` → `/foo/bar/` (removes duplicate slashes)
|
||||
- `/./foo/../bar//` → `/bar/` (combines all normalizations)
|
||||
|
||||
### Encoded Character Filtering
|
||||
|
||||
Encoded character filtering provides an additional security layer by rejecting potentially dangerous URL-encoded characters.
|
||||
Configure it in the [EntryPoints](../routing/entrypoints.md#encoded-characters) HTTP section.
|
||||
|
||||
This filtering occurs before path sanitization and catches attack attempts that use encoding to bypass other security controls.
|
||||
|
||||
All encoded character filtering is enabled by default (`false` means encoded characters are rejected), providing maximum security:
|
||||
|
||||
```yaml tab="File (YAML)"
|
||||
entryPoints:
|
||||
websecure:
|
||||
address: ":443"
|
||||
encodedCharacters:
|
||||
allowEncodedSlash: false # %2F - Default: false (RECOMMENDED)
|
||||
allowEncodedBackSlash: false # %5C - Default: false (RECOMMENDED)
|
||||
allowEncodedNullCharacter: false # %00 - Default: false (RECOMMENDED)
|
||||
allowEncodedSemicolon: false # %3B - Default: false (RECOMMENDED)
|
||||
allowEncodedPercent: false # %25 - Default: false (RECOMMENDED)
|
||||
allowEncodedQuestionMark: false # %3F - Default: false (RECOMMENDED)
|
||||
allowEncodedHash: false # %23 - Default: false (RECOMMENDED)
|
||||
```
|
||||
|
||||
```toml tab="File (TOML)"
|
||||
[entryPoints.websecure]
|
||||
address = ":443"
|
||||
|
||||
[entryPoints.websecure.encodedCharacters]
|
||||
allowEncodedSlash = false
|
||||
allowEncodedBackSlash = false
|
||||
allowEncodedNullCharacter = false
|
||||
allowEncodedSemicolon = false
|
||||
allowEncodedPercent = false
|
||||
allowEncodedQuestionMark = false
|
||||
allowEncodedHash = false
|
||||
```
|
||||
|
||||
```bash tab="CLI"
|
||||
--entryPoints.websecure.address=:443
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedSlash=false
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedBackSlash=false
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedNullCharacter=false
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedSemicolon=false
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedPercent=false
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedQuestionMark=false
|
||||
--entryPoints.websecure.encodedCharacters.allowEncodedHash=false
|
||||
```
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: "TLS Certificates in Multi‑Tenant Kubernetes"
|
||||
description: "Isolate TLS certificates in multi‑tenant clusters by keeping Secrets and routes in the same namespace and disabling cross‑namespace look‑ups in Traefik. Read the technical guidelines."
|
||||
---
|
||||
|
||||
# TLS Certificates in Multi‑Tenant Kubernetes
|
||||
|
||||
In a shared cluster, different teams can create `Ingress` or `IngressRoute` objects that Traefik consumes.
|
||||
|
||||
Traefik does not support multi-tenancy when using the Kubernetes `Ingress` or `IngressRoute` specifications due to the way TLS certificate management is handled.
|
||||
|
||||
At the core of this limitation is the TLS Store, which holds all the TLS certificates used by Traefik.
|
||||
As this Store is global in Traefik, it is shared across all namespaces, meaning any `Ingress` or `IngressRoute` in the cluster can potentially reference or affect TLS configurations intended for other tenants.
|
||||
|
||||
This lack of isolation poses a risk in multi-tenant environments where different teams or applications require strict boundaries between resources, especially around sensitive data like TLS certificates.
|
||||
|
||||
In contrast, the [Kubernetes Gateway API](../providers/kubernetes-gateway.md) provides better primitives for secure multi-tenancy.
|
||||
Specifically, the `Listener` resource in the Gateway API allows administrators to explicitly define which Route resources (e.g., `HTTPRoute`) are permitted to bind to which domain names or ports.
|
||||
This capability enforces stricter ownership and isolation, making it a safer choice for multi-tenant use cases.
|
||||
|
||||
## Recommended setup
|
||||
|
||||
When strict boundaries are required between resources and teams, we recommend using one Traefik instance per tenant.
|
||||
|
||||
In Kubernetes one way to isolate a tenant is to restrict it to a namespace.
|
||||
In that case, the namespace options from the Kubernetes [CRD](../providers/kubernetes-crd.md#namespaces) and [Ingress](../providers/kubernetes-ingress.md#namespaces) providers can be leveraged.
|
||||
|
||||
!!! tip "Dedicate one Traefik instance per tenant using the Helm Chart"
|
||||
|
||||
```yaml
|
||||
providers:
|
||||
kubernetesCRD:
|
||||
namespaces:
|
||||
- tenant
|
||||
kubernetesIngress:
|
||||
namespaces:
|
||||
- tenant
|
||||
```
|
||||
@@ -31,7 +31,7 @@ Our starting point is the docker-compose configuration file, to start the k3s cl
|
||||
You can start it with:
|
||||
|
||||
```bash
|
||||
docker-compose -f k3s.yml up
|
||||
docker compose -f k3s.yml up
|
||||
```
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -6,7 +6,7 @@ description: "Learn how to create a certificate with the Let's Encrypt DNS chall
|
||||
# Docker-compose with Let's Encrypt: DNS Challenge
|
||||
|
||||
This guide aims to demonstrate how to create a certificate with the Let's Encrypt DNS challenge to use https on a simple service exposed with Traefik.
|
||||
Please also read the [basic example](../basic-example) for details on how to expose such a service.
|
||||
Please also read the [basic example](../basic-example/) for details on how to expose such a service.
|
||||
|
||||
## Prerequisite
|
||||
|
||||
@@ -46,7 +46,7 @@ For the DNS challenge, you'll need:
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
|
||||
- Run `docker-compose up -d` within the folder where you created the previous file.
|
||||
- Run `docker compose up -d` within the folder where you created the previous file.
|
||||
- Wait a bit and visit `https://your_own_domain` to confirm everything went fine.
|
||||
|
||||
!!! Note
|
||||
|
||||
@@ -32,7 +32,7 @@ For the HTTP challenge you will need:
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
|
||||
- Run `docker-compose up -d` within the folder where you created the previous file.
|
||||
- Run `docker compose up -d` within the folder where you created the previous file.
|
||||
- Wait a bit and visit `https://your_own_domain` to confirm everything went fine.
|
||||
|
||||
!!! Note
|
||||
@@ -55,7 +55,7 @@ ports:
|
||||
- "443:443"
|
||||
```
|
||||
|
||||
- We configure the HTTPS Let's Encrypt challenge:
|
||||
- We configure the HTTP Let's Encrypt challenge:
|
||||
|
||||
```yaml
|
||||
command:
|
||||
|
||||
@@ -32,7 +32,7 @@ For the TLS challenge you will need:
|
||||
#- "--certificatesresolvers.myresolver.acme.caserver=https://acme-staging-v02.api.letsencrypt.org/directory"
|
||||
```
|
||||
|
||||
- Run `docker-compose up -d` within the folder where you created the previous file.
|
||||
- Run `docker compose up -d` within the folder where you created the previous file.
|
||||
- Wait a bit and visit `https://your_own_domain` to confirm everything went fine.
|
||||
|
||||
!!! Note
|
||||
|
||||
@@ -46,7 +46,7 @@ Create a `docker-compose.yml` file with the following content:
|
||||
|
||||
Replace `whoami.localhost` by your **own domain** within the `traefik.http.routers.whoami.rule` label of the `whoami` service.
|
||||
|
||||
Now run `docker-compose up -d` within the folder where you created the previous file.
|
||||
Now run `docker compose up -d` within the folder where you created the previous file.
|
||||
This will start Docker Compose in background mode.
|
||||
|
||||
!!! info "This can take a moment"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM alpine:3.21
|
||||
FROM alpine:3.22
|
||||
|
||||
ENV PATH="${PATH}:/venv/bin"
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ theme:
|
||||
prev: 'Previous'
|
||||
next: 'Next'
|
||||
|
||||
copyright: 'Traefik Labs • Copyright © 2016-2024'
|
||||
copyright: 'Traefik Labs • Copyright © 2016-2025'
|
||||
|
||||
extra_javascript:
|
||||
- assets/js/hljs/highlight.pack.js # Download from https://highlightjs.org/download/ and enable YAML, TOML and Dockerfile
|
||||
@@ -165,6 +165,11 @@ nav:
|
||||
- 'Instana': 'observability/tracing/instana.md'
|
||||
- 'Haystack': 'observability/tracing/haystack.md'
|
||||
- 'Elastic': 'observability/tracing/elastic.md'
|
||||
- 'OpenTelemetry': 'observability/tracing/opentelemetry.md'
|
||||
- 'Security':
|
||||
- 'Request Path': 'security/request-path.md'
|
||||
- 'Content-Length': 'security/content-length.md'
|
||||
- 'TLS in Multi-Tenant Kubernetes': 'security/tls-certs-in-multi-tenant-kubernetes.md'
|
||||
- 'User Guides':
|
||||
- 'Kubernetes and Let''s Encrypt': 'user-guides/crd-acme/index.md'
|
||||
- 'gRPC Examples': 'user-guides/grpc.md'
|
||||
|
||||
385
go.mod
385
go.mod
@@ -1,29 +1,35 @@
|
||||
module github.com/traefik/traefik/v2
|
||||
|
||||
go 1.23.0
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.4.0
|
||||
github.com/BurntSushi/toml v1.5.0
|
||||
github.com/ExpediaDotCom/haystack-client-go v0.0.0-20190315171017-e7edbdf53a61 // No tag on the repo.
|
||||
github.com/Masterminds/sprig/v3 v3.2.3
|
||||
github.com/abbot/go-http-auth v0.0.0-00010101000000-000000000000
|
||||
github.com/aws/aws-sdk-go v1.44.327
|
||||
github.com/aws/aws-sdk-go-v2 v1.36.6
|
||||
github.com/aws/aws-sdk-go-v2/config v1.29.18
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.71
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.203.1
|
||||
github.com/aws/aws-sdk-go-v2/service/ecs v1.53.15
|
||||
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.13
|
||||
github.com/aws/smithy-go v1.22.4
|
||||
github.com/cenkalti/backoff/v4 v4.3.0
|
||||
github.com/containous/alice v0.0.0-20181107144136-d83ebdd94cbd // No tag on the repo.
|
||||
github.com/coreos/go-systemd/v22 v22.5.0
|
||||
github.com/docker/cli v27.1.1+incompatible
|
||||
github.com/docker/docker v27.1.1+incompatible
|
||||
github.com/docker/cli v28.3.3+incompatible
|
||||
github.com/docker/docker v28.3.3+incompatible
|
||||
github.com/docker/go-connections v0.5.0
|
||||
github.com/fatih/structs v1.1.0
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
github.com/fsnotify/fsnotify v1.9.0
|
||||
github.com/gambol99/go-marathon v0.0.0-20180614232016-99a156b96fb2 // No tag on the repo.
|
||||
github.com/go-acme/lego/v4 v4.20.4
|
||||
github.com/go-acme/lego/v4 v4.25.2
|
||||
github.com/go-kit/kit v0.13.0
|
||||
github.com/go-kit/log v0.2.1
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-github/v28 v28.1.1
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/hashicorp/consul/api v1.26.1
|
||||
github.com/hashicorp/go-hclog v1.6.3
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
@@ -32,178 +38,192 @@ require (
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.7.0
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab // No tag on the repo.
|
||||
github.com/instana/go-sensor v1.38.3
|
||||
github.com/klauspost/compress v1.17.11-0.20241004063537-dbd6c381492a // Required to have the content-type fix: https://github.com/klauspost/compress/pull/1013
|
||||
github.com/klauspost/compress v1.18.0
|
||||
github.com/kvtools/consul v1.0.2
|
||||
github.com/kvtools/etcdv3 v1.0.2
|
||||
github.com/kvtools/redis v1.1.0
|
||||
github.com/kvtools/valkeyrie v1.0.0
|
||||
github.com/kvtools/zookeeper v1.0.2
|
||||
github.com/mailgun/ttlmap v0.0.0-20170619185759-c1c17f74874f // No tag on the repo.
|
||||
github.com/miekg/dns v1.1.62
|
||||
github.com/miekg/dns v1.1.67
|
||||
github.com/mitchellh/copystructure v1.2.0
|
||||
github.com/mitchellh/hashstructure v1.0.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c
|
||||
github.com/opentracing/opentracing-go v1.2.1-0.20220228012449-10b1cf09e00b // No tag on the repo.
|
||||
github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5
|
||||
github.com/openzipkin/zipkin-go v0.2.5
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pires/go-proxyproto v0.6.1
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // No tag on the repo.
|
||||
github.com/prometheus/client_golang v1.19.1
|
||||
github.com/prometheus/client_model v0.5.0
|
||||
github.com/quic-go/quic-go v0.48.2
|
||||
github.com/prometheus/client_golang v1.22.0
|
||||
github.com/prometheus/client_model v0.6.1
|
||||
github.com/quic-go/quic-go v0.57.1
|
||||
github.com/rancher/go-rancher-metadata v0.0.0-20200311180630-7f4c936a06ac // No tag on the repo.
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/stretchr/testify v1.11.1
|
||||
github.com/stvp/go-udp-testing v0.0.0-20191102171040-06b61409b154 // No tag on the repo.
|
||||
github.com/testcontainers/testcontainers-go v0.32.0
|
||||
github.com/traefik/paerser v0.2.1
|
||||
github.com/traefik/paerser v0.2.2
|
||||
github.com/traefik/yaegi v0.16.1
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible
|
||||
github.com/unrolled/render v1.0.2
|
||||
github.com/unrolled/secure v1.0.9
|
||||
github.com/vulcand/oxy/v2 v2.0.0
|
||||
github.com/vulcand/oxy/v2 v2.0.3
|
||||
github.com/vulcand/predicate v1.2.0
|
||||
go.elastic.co/apm/module/apmot/v2 v2.4.8
|
||||
go.elastic.co/apm/v2 v2.4.8
|
||||
golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // No tag on the repo.
|
||||
golang.org/x/mod v0.21.0
|
||||
golang.org/x/net v0.30.0
|
||||
golang.org/x/text v0.21.0
|
||||
golang.org/x/time v0.7.0
|
||||
golang.org/x/tools v0.25.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.56.1
|
||||
golang.org/x/mod v0.29.0
|
||||
golang.org/x/net v0.47.0
|
||||
golang.org/x/text v0.31.0
|
||||
golang.org/x/time v0.12.0
|
||||
golang.org/x/tools v0.38.0
|
||||
google.golang.org/grpc v1.73.0
|
||||
gopkg.in/DataDog/dd-trace-go.v1 v1.74.6
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
k8s.io/api v0.26.3
|
||||
k8s.io/api v0.32.3
|
||||
k8s.io/apiextensions-apiserver v0.26.3
|
||||
k8s.io/apimachinery v0.26.3
|
||||
k8s.io/client-go v0.26.3
|
||||
k8s.io/utils v0.0.0-20230313181309-38a27ef9d749 // No tag on the repo.
|
||||
k8s.io/apimachinery v0.32.3
|
||||
k8s.io/client-go v0.32.3
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 // No tag on the repo.
|
||||
mvdan.cc/xurls/v2 v2.5.0
|
||||
sigs.k8s.io/gateway-api v0.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go/auth v0.10.0 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.5 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.5.2 // indirect
|
||||
dario.cat/mergo v1.0.0 // indirect
|
||||
cloud.google.com/go/auth v0.16.2 // indirect
|
||||
cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.7.0 // indirect
|
||||
dario.cat/mergo v1.0.1 // indirect
|
||||
github.com/AdamSLevy/jsonrpc2/v14 v14.1.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.10.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.1 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/dns/armdns v1.2.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/privatedns/armprivatedns v1.3.0 // indirect
|
||||
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.9.0 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c // indirect
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.29 // indirect
|
||||
github.com/Azure/go-autorest/autorest v0.11.30 // indirect
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.22 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/auth v0.5.13 // indirect
|
||||
github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.1 // indirect
|
||||
github.com/Azure/go-autorest/logger v0.2.1 // indirect
|
||||
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect
|
||||
github.com/DataDog/appsec-internal-go v1.0.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.48.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.48.0-devel.0.20230725154044-2549ba9058df // indirect
|
||||
github.com/DataDog/datadog-go/v5 v5.3.0 // indirect
|
||||
github.com/DataDog/go-libddwaf v1.5.0 // indirect
|
||||
github.com/DataDog/go-tuf v1.0.2-0.5.2 // indirect
|
||||
github.com/DataDog/sketches-go v1.4.2 // indirect
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 // indirect
|
||||
github.com/DataDog/appsec-internal-go v1.13.0 // indirect
|
||||
github.com/DataDog/datadog-agent/comp/core/tagger/origindetection v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/obfuscate v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/proto v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/remoteconfig/state v0.69.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/trace v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/util/log v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/util/scrubber v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-agent/pkg/version v0.67.0 // indirect
|
||||
github.com/DataDog/datadog-go/v5 v5.6.0 // indirect
|
||||
github.com/DataDog/dd-trace-go/v2 v2.2.3 // indirect
|
||||
github.com/DataDog/go-libddwaf/v4 v4.3.2 // indirect
|
||||
github.com/DataDog/go-runtime-metrics-internal v0.0.4-0.20250721125240-fdf1ef85b633 // indirect
|
||||
github.com/DataDog/go-sqllexer v0.1.6 // indirect
|
||||
github.com/DataDog/go-tuf v1.1.0-0.5.2 // indirect
|
||||
github.com/DataDog/opentelemetry-mapping-go/pkg/otlp/attributes v0.27.0 // indirect
|
||||
github.com/DataDog/sketches-go v1.4.7 // indirect
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect
|
||||
github.com/Masterminds/goutils v1.1.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.2.1 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.3.1 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/Microsoft/hcsshim v0.11.7 // indirect
|
||||
github.com/Microsoft/hcsshim v0.13.0 // indirect
|
||||
github.com/OpenDNS/vegadns2client v0.0.0-20180418235048-a3fa4a771d87 // indirect
|
||||
github.com/VividCortex/gohistogram v1.0.0 // indirect
|
||||
github.com/akamai/AkamaiOPEN-edgegrid-golang v1.2.2 // indirect
|
||||
github.com/aliyun/alibaba-cloud-sdk-go v1.63.47 // indirect
|
||||
github.com/alibabacloud-go/alibabacloud-gateway-spi v0.0.5 // indirect
|
||||
github.com/alibabacloud-go/darabonba-openapi/v2 v2.1.8 // indirect
|
||||
github.com/alibabacloud-go/debug v1.0.1 // indirect
|
||||
github.com/alibabacloud-go/endpoint-util v1.1.0 // indirect
|
||||
github.com/alibabacloud-go/openapi-util v0.1.1 // indirect
|
||||
github.com/alibabacloud-go/tea v1.3.9 // indirect
|
||||
github.com/alibabacloud-go/tea-utils/v2 v2.0.7 // indirect
|
||||
github.com/aliyun/credentials-go v1.4.6 // indirect
|
||||
github.com/armon/go-metrics v0.4.1 // indirect
|
||||
github.com/armon/go-radix v1.0.1-0.20221118154546-54df44f2176c // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.32.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.28.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.17.42 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.42.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.46.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.24.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.32.3 // indirect
|
||||
github.com/aws/smithy-go v1.22.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.33 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.37 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.37 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.18 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.43.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.53.1 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect
|
||||
github.com/aziontech/azionapi-go-sdk v0.142.0 // indirect
|
||||
github.com/baidubce/bce-sdk-go v0.9.235 // indirect
|
||||
github.com/benbjohnson/clock v1.3.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/civo/civogo v0.3.11 // indirect
|
||||
github.com/cloudflare/cloudflare-go v0.108.0 // indirect
|
||||
github.com/containerd/containerd v1.7.20 // indirect
|
||||
github.com/cihub/seelog v0.0.0-20170130134532-f561c5e57575 // indirect
|
||||
github.com/clbanning/mxj/v2 v2.7.0 // indirect
|
||||
github.com/containerd/containerd v1.7.23 // indirect
|
||||
github.com/containerd/errdefs v1.0.0 // indirect
|
||||
github.com/containerd/errdefs/pkg v0.3.0 // indirect
|
||||
github.com/containerd/log v0.1.0 // indirect
|
||||
github.com/containerd/platforms v0.2.1 // indirect
|
||||
github.com/containerd/platforms v1.0.0-rc.1 // indirect
|
||||
github.com/coreos/go-semver v0.3.0 // indirect
|
||||
github.com/cpu/goacmedns v0.1.1 // indirect
|
||||
github.com/cpuguy83/dockercfg v0.3.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deepmap/oapi-codegen v1.9.1 // indirect
|
||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||
github.com/dimchansky/utfbom v1.1.1 // indirect
|
||||
github.com/distribution/reference v0.6.0 // indirect
|
||||
github.com/dnsimple/dnsimple-go v1.7.0 // indirect
|
||||
github.com/dnsimple/dnsimple-go/v4 v4.0.0 // indirect
|
||||
github.com/docker/go-units v0.5.0 // indirect
|
||||
github.com/donovanhide/eventsource v0.0.0-20170630084216-b8f31a59085e // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/ebitengine/purego v0.5.0-alpha.1 // indirect
|
||||
github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 // indirect
|
||||
github.com/ebitengine/purego v0.8.3 // indirect
|
||||
github.com/elastic/go-sysinfo v1.7.1 // indirect
|
||||
github.com/elastic/go-windows v1.0.0 // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
|
||||
github.com/evanphx/json-patch v4.12.0+incompatible // indirect
|
||||
github.com/exoscale/egoscale/v3 v3.1.7 // indirect
|
||||
github.com/exoscale/egoscale/v3 v3.1.24 // indirect
|
||||
github.com/fatih/color v1.16.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-acme/alidns-20150109/v4 v4.5.10 // indirect
|
||||
github.com/go-acme/tencentclouddnspod v1.0.1208 // indirect
|
||||
github.com/go-errors/errors v1.0.1 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.5.1 // indirect
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.2.6 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.5 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.0 // indirect
|
||||
github.com/go-openapi/swag v0.19.14 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.16.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.13.1 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.23.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.16.5 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/go-zookeeper/zk v1.0.3 // indirect
|
||||
github.com/goccy/go-json v0.10.3 // indirect
|
||||
github.com/gofrs/flock v0.12.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.1 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/google/gnostic v0.5.7-v3refs // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 // indirect
|
||||
github.com/golang-jwt/jwt/v5 v5.2.2 // indirect
|
||||
github.com/google/gnostic-models v0.6.8 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/go-querystring v1.1.0 // indirect
|
||||
github.com/google/gofuzz v1.2.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20240910150728-a0b0bb1d4134 // indirect
|
||||
github.com/google/s2a-go v0.1.8 // indirect
|
||||
github.com/google/s2a-go v0.1.9 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.4 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.13.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.6 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // indirect
|
||||
github.com/gophercloud/gophercloud v1.14.1 // indirect
|
||||
github.com/gophercloud/utils v0.0.0-20231010081019-80377eca5d56 // indirect
|
||||
github.com/gravitational/trace v1.1.16-0.20220114165159-14a9a7dd6aaf // indirect
|
||||
@@ -211,19 +231,18 @@ require (
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.7 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.8 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-uuid v1.0.3 // indirect
|
||||
github.com/hashicorp/golang-lru v1.0.2 // indirect
|
||||
github.com/hashicorp/hcl v1.0.1-vault-5 // indirect
|
||||
github.com/hashicorp/serf v0.10.1 // indirect
|
||||
github.com/huandu/xstrings v1.5.0 // indirect
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.120 // indirect
|
||||
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.159 // indirect
|
||||
github.com/iij/doapi v0.0.0-20190504054126-0bbf12d6d7df // indirect
|
||||
github.com/imdario/mergo v0.3.16 // indirect
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect
|
||||
github.com/infobloxopen/infoblox-go-client v1.1.1 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/infobloxopen/infoblox-go-client/v2 v2.10.0 // indirect
|
||||
github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 // indirect
|
||||
github.com/jonboulle/clockwork v0.4.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
@@ -233,148 +252,162 @@ require (
|
||||
github.com/kylelemons/godebug v1.1.0 // indirect
|
||||
github.com/labbsr0x/bindman-dns-webhook v1.0.2 // indirect
|
||||
github.com/labbsr0x/goh v1.0.1 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/linode/linodego v1.42.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/linode/linodego v1.53.0 // indirect
|
||||
github.com/liquidweb/liquidweb-cli v0.6.9 // indirect
|
||||
github.com/liquidweb/liquidweb-go v1.6.4 // indirect
|
||||
github.com/looplab/fsm v0.1.0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
|
||||
github.com/lufia/plan9stats v0.0.0-20250317134145-8bc96cf8fc35 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailgun/minheap v0.0.0-20170619185613-3dbe6c6bf55f // indirect
|
||||
github.com/mailgun/multibuf v0.1.2 // indirect
|
||||
github.com/mailgun/timetools v0.0.0-20141028012446-7e6055773c51 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-colorable v0.1.14 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.2 // indirect
|
||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||
github.com/moby/go-archive v0.1.0 // indirect
|
||||
github.com/moby/patternmatcher v0.6.0 // indirect
|
||||
github.com/moby/sys/sequential v0.5.0 // indirect
|
||||
github.com/moby/sys/user v0.2.0 // indirect
|
||||
github.com/moby/term v0.5.0 // indirect
|
||||
github.com/moby/sys/atomicwriter v0.1.0 // indirect
|
||||
github.com/moby/sys/sequential v0.6.0 // indirect
|
||||
github.com/moby/sys/user v0.4.0 // indirect
|
||||
github.com/moby/sys/userns v0.1.0 // indirect
|
||||
github.com/moby/term v0.5.2 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/morikuni/aec v1.0.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
|
||||
github.com/namedotcom/go/v4 v4.0.2 // indirect
|
||||
github.com/nrdcg/auroradns v1.1.0 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20240207213615-dde5bf4577a3 // indirect
|
||||
github.com/nrdcg/desec v0.8.0 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20250327222614-988a091fc7ea // indirect
|
||||
github.com/nrdcg/desec v0.11.0 // indirect
|
||||
github.com/nrdcg/dnspod-go v0.4.0 // indirect
|
||||
github.com/nrdcg/freemyip v0.2.0 // indirect
|
||||
github.com/nrdcg/goinwx v0.10.0 // indirect
|
||||
github.com/nrdcg/freemyip v0.3.0 // indirect
|
||||
github.com/nrdcg/goacmedns v0.2.0 // indirect
|
||||
github.com/nrdcg/goinwx v0.11.0 // indirect
|
||||
github.com/nrdcg/mailinabox v0.2.0 // indirect
|
||||
github.com/nrdcg/namesilo v0.2.1 // indirect
|
||||
github.com/nrdcg/nodion v0.1.0 // indirect
|
||||
github.com/nrdcg/oci-go-sdk/common/v1065 v1065.95.2 // indirect
|
||||
github.com/nrdcg/oci-go-sdk/dns/v1065 v1065.95.2 // indirect
|
||||
github.com/nrdcg/porkbun v0.4.0 // indirect
|
||||
github.com/nzdjb/go-metaname v1.0.0 // indirect
|
||||
github.com/onsi/ginkgo v1.16.5 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.20.2 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect
|
||||
github.com/oracle/oci-go-sdk/v65 v65.77.1 // indirect
|
||||
github.com/outcaste-io/ristretto v0.2.3 // indirect
|
||||
github.com/ovh/go-ovh v1.6.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
|
||||
github.com/philhofer/fwd v1.1.2 // indirect
|
||||
github.com/ovh/go-ovh v1.9.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/peterhellberg/link v1.2.0 // indirect
|
||||
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
|
||||
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
|
||||
github.com/pquerna/otp v1.4.0 // indirect
|
||||
github.com/prometheus/common v0.48.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/redis/go-redis/v9 v9.6.1 // indirect
|
||||
github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
|
||||
github.com/pquerna/otp v1.5.0 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/redis/go-redis/v9 v9.8.0 // indirect
|
||||
github.com/regfish/regfish-dnsapi-go v0.1.1 // indirect
|
||||
github.com/sacloud/api-client-go v0.2.10 // indirect
|
||||
github.com/sacloud/go-http v0.1.8 // indirect
|
||||
github.com/sacloud/iaas-api-go v1.12.0 // indirect
|
||||
github.com/sacloud/packages-go v0.0.10 // indirect
|
||||
github.com/sacloud/api-client-go v0.3.2 // indirect
|
||||
github.com/sacloud/go-http v0.1.9 // indirect
|
||||
github.com/sacloud/iaas-api-go v1.16.1 // indirect
|
||||
github.com/sacloud/packages-go v0.0.11 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.30 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.7.0 // indirect
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.34 // indirect
|
||||
github.com/secure-systems-lab/go-securesystemslib v0.9.0 // indirect
|
||||
github.com/segmentio/fasthash v1.0.3 // indirect
|
||||
github.com/selectel/domains-go v1.1.0 // indirect
|
||||
github.com/selectel/go-selvpcclient/v3 v3.1.1 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.23.12 // indirect
|
||||
github.com/selectel/go-selvpcclient/v4 v4.1.0 // indirect
|
||||
github.com/shirou/gopsutil/v3 v3.24.4 // indirect
|
||||
github.com/shirou/gopsutil/v4 v4.25.3 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/shopspring/decimal v1.4.0 // indirect
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
||||
github.com/softlayer/softlayer-go v1.1.7 // indirect
|
||||
github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e // indirect
|
||||
github.com/sony/gobreaker v0.5.0 // indirect
|
||||
github.com/sony/gobreaker v1.0.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.7.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/spf13/pflag v1.0.6 // indirect
|
||||
github.com/spf13/viper v1.18.2 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1034 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/dnspod v1.0.1034 // indirect
|
||||
github.com/tinylib/msgp v1.1.8 // indirect
|
||||
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.1210 // indirect
|
||||
github.com/tinylib/msgp v1.2.5 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.12 // indirect
|
||||
github.com/tklauser/numcpus v0.6.1 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
github.com/transip/gotransip/v6 v6.26.0 // indirect
|
||||
github.com/ultradns/ultradns-go-sdk v1.8.0-20241010134910-243eeec // indirect
|
||||
github.com/vinyldns/go-vinyldns v0.9.16 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.183 // indirect
|
||||
github.com/vultr/govultr/v3 v3.9.1 // indirect
|
||||
github.com/yandex-cloud/go-genproto v0.0.0-20241101135610-76a0cfc1a773 // indirect
|
||||
github.com/yandex-cloud/go-sdk v0.0.0-20241101143304-947cf519f6bd // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.3 // indirect
|
||||
github.com/volcengine/volc-sdk-golang v1.0.216 // indirect
|
||||
github.com/vultr/govultr/v3 v3.21.1 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/yandex-cloud/go-genproto v0.14.0 // indirect
|
||||
github.com/yandex-cloud/go-sdk/services/dns v0.0.3 // indirect
|
||||
github.com/yandex-cloud/go-sdk/v2 v2.0.8 // indirect
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.elastic.co/apm/module/apmhttp/v2 v2.4.8 // indirect
|
||||
go.elastic.co/fastjson v1.1.0 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.10 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.10 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.10 // indirect
|
||||
go.mongodb.org/mongo-driver v1.12.1 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 // indirect
|
||||
go.opentelemetry.io/otel v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.29.0 // indirect
|
||||
go.mongodb.org/mongo-driver v1.13.1 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/collector/component v1.31.0 // indirect
|
||||
go.opentelemetry.io/collector/featuregate v1.31.0 // indirect
|
||||
go.opentelemetry.io/collector/internal/telemetry v0.125.0 // indirect
|
||||
go.opentelemetry.io/collector/pdata v1.31.0 // indirect
|
||||
go.opentelemetry.io/collector/semconv v0.125.0 // indirect
|
||||
go.opentelemetry.io/contrib/bridges/otelzap v0.10.0 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
|
||||
go.opentelemetry.io/otel v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/log v0.11.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.36.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/goleak v1.3.0 // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
go.uber.org/multierr v1.9.0 // indirect
|
||||
go.uber.org/ratelimit v0.3.0 // indirect
|
||||
go.uber.org/zap v1.21.0 // indirect
|
||||
go4.org/intern v0.0.0-20230525184215-6c62f75575cb // indirect
|
||||
go4.org/unsafe/assume-no-moving-gc v0.0.0-20230525183740-e7c30c78aeb2 // indirect
|
||||
golang.org/x/crypto v0.31.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.204.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20241021214115-324edc3d5d38 // indirect
|
||||
google.golang.org/protobuf v1.35.1 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/ratelimit v0.3.1 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
golang.org/x/crypto v0.45.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250408133849-7e4ce0ab07d0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
golang.org/x/sync v0.18.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/term v0.37.0 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect
|
||||
google.golang.org/api v0.242.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250707201910-8d1bb00bc6a7 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.12.2 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.14.4 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
howett.net/plist v0.0.0-20181124034731-591f970eefbb // indirect
|
||||
inet.af/netaddr v0.0.0-20230525184311-b8eac61e914a // indirect
|
||||
k8s.io/klog/v2 v2.90.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
|
||||
sigs.k8s.io/yaml v1.3.0 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect
|
||||
sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.4.2 // indirect
|
||||
sigs.k8s.io/yaml v1.4.0 // indirect
|
||||
)
|
||||
|
||||
// Containous forks
|
||||
replace (
|
||||
github.com/abbot/go-http-auth => github.com/containous/go-http-auth v0.4.1-0.20200324110947-a37a7636d23e
|
||||
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20220627093034-b2dd784e613f
|
||||
github.com/gorilla/mux => github.com/containous/mux v0.0.0-20250523120546-41b6ec3aed59
|
||||
github.com/mailgun/minheap => github.com/containous/minheap v0.0.0-20190809180810-6e71eb837595
|
||||
)
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
"github.com/traefik/traefik/v2/pkg/provider/acme"
|
||||
"github.com/traefik/traefik/v2/pkg/testhelpers"
|
||||
"github.com/traefik/traefik/v2/pkg/types"
|
||||
"k8s.io/utils/strings/slices"
|
||||
)
|
||||
|
||||
// ACME test suites.
|
||||
@@ -35,9 +36,9 @@ func TestAcmeSuite(t *testing.T) {
|
||||
}
|
||||
|
||||
type subCases struct {
|
||||
host string
|
||||
expectedCommonName string
|
||||
expectedAlgorithm x509.PublicKeyAlgorithm
|
||||
host string
|
||||
expectedDomain string
|
||||
expectedAlgorithm x509.PublicKeyAlgorithm
|
||||
}
|
||||
|
||||
type acmeTestCase struct {
|
||||
@@ -142,9 +143,9 @@ func (s *AcmeSuite) TestHTTP01Domains() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_domains.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Domains: []types.Domain{{
|
||||
@@ -165,9 +166,9 @@ func (s *AcmeSuite) TestHTTP01StoreDomains() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_store_domains.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Domain: types.Domain{
|
||||
@@ -188,9 +189,9 @@ func (s *AcmeSuite) TestHTTP01DomainsInSAN() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_domains.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: "acme.wtf",
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: "acme.wtf",
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Domains: []types.Domain{{
|
||||
@@ -212,9 +213,9 @@ func (s *AcmeSuite) TestHTTP01OnHostRule() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_base.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -233,14 +234,14 @@ func (s *AcmeSuite) TestMultipleResolver() {
|
||||
traefikConfFilePath: "fixtures/acme/acme_multiple_resolvers.toml",
|
||||
subCases: []subCases{
|
||||
{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
},
|
||||
{
|
||||
host: "tchouk.acme.wtf",
|
||||
expectedCommonName: "tchouk.acme.wtf",
|
||||
expectedAlgorithm: x509.ECDSA,
|
||||
host: "tchouk.acme.wtf",
|
||||
expectedDomain: "tchouk.acme.wtf",
|
||||
expectedAlgorithm: x509.ECDSA,
|
||||
},
|
||||
},
|
||||
template: templateModel{
|
||||
@@ -263,9 +264,9 @@ func (s *AcmeSuite) TestHTTP01OnHostRuleECDSA() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_base.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.ECDSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.ECDSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -284,9 +285,9 @@ func (s *AcmeSuite) TestHTTP01OnHostRuleInvalidAlgo() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_base.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -301,13 +302,14 @@ func (s *AcmeSuite) TestHTTP01OnHostRuleInvalidAlgo() {
|
||||
s.retrieveAcmeCertificate(testCase)
|
||||
}
|
||||
|
||||
// TODO: check why this test do not use the ACME cert resolver.
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleDefaultDynamicCertificatesWithWildcard() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -321,13 +323,14 @@ func (s *AcmeSuite) TestHTTP01OnHostRuleDefaultDynamicCertificatesWithWildcard()
|
||||
s.retrieveAcmeCertificate(testCase)
|
||||
}
|
||||
|
||||
// TODO: check why this test do not use the ACME cert resolver.
|
||||
func (s *AcmeSuite) TestHTTP01OnHostRuleDynamicCertificatesWithWildcard() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tls_dynamic.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: wildcardDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -345,9 +348,9 @@ func (s *AcmeSuite) TestTLSALPN01OnHostRuleTCP() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_tcp.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -365,9 +368,9 @@ func (s *AcmeSuite) TestTLSALPN01OnHostRule() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_base.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Acme: map[string]static.CertificateResolver{
|
||||
@@ -385,9 +388,9 @@ func (s *AcmeSuite) TestTLSALPN01Domains() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_domains.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: acmeDomain,
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Domains: []types.Domain{{
|
||||
@@ -408,9 +411,9 @@ func (s *AcmeSuite) TestTLSALPN01DomainsInSAN() {
|
||||
testCase := acmeTestCase{
|
||||
traefikConfFilePath: "fixtures/acme/acme_domains.toml",
|
||||
subCases: []subCases{{
|
||||
host: acmeDomain,
|
||||
expectedCommonName: "acme.wtf",
|
||||
expectedAlgorithm: x509.RSA,
|
||||
host: acmeDomain,
|
||||
expectedDomain: "acme.wtf",
|
||||
expectedAlgorithm: x509.RSA,
|
||||
}},
|
||||
template: templateModel{
|
||||
Domains: []types.Domain{{
|
||||
@@ -502,27 +505,38 @@ func (s *AcmeSuite) retrieveAcmeCertificate(testCase acmeTestCase) {
|
||||
req.Header.Set("Host", sub.host)
|
||||
req.Header.Set("Accept", "*/*")
|
||||
|
||||
var resp *http.Response
|
||||
var (
|
||||
gotStatusCode int
|
||||
gotDomains []string
|
||||
gotPublicKeyAlgorithm x509.PublicKeyAlgorithm
|
||||
)
|
||||
|
||||
// Retry to send a Request which uses the LE generated certificate
|
||||
err := try.Do(60*time.Second, func() error {
|
||||
resp, err = client.Do(req)
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cn := resp.TLS.PeerCertificates[0].Subject.CommonName
|
||||
if cn != sub.expectedCommonName {
|
||||
return fmt.Errorf("domain %s found instead of %s", cn, sub.expectedCommonName)
|
||||
gotStatusCode = resp.StatusCode
|
||||
gotPublicKeyAlgorithm = resp.TLS.PeerCertificates[0].PublicKeyAlgorithm
|
||||
|
||||
// Here we are collecting the common name as it is used in wildcard tests.
|
||||
gotDomains = append(gotDomains, resp.TLS.PeerCertificates[0].Subject.CommonName)
|
||||
gotDomains = append(gotDomains, resp.TLS.PeerCertificates[0].DNSNames...)
|
||||
|
||||
if !slices.Contains(gotDomains, sub.expectedDomain) {
|
||||
return fmt.Errorf("domain name %s not found in domain names: %v", sub.expectedDomain, gotDomains)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusOK, resp.StatusCode)
|
||||
assert.Equal(s.T(), http.StatusOK, gotStatusCode)
|
||||
|
||||
// Check Domain into response certificate
|
||||
assert.Equal(s.T(), sub.expectedCommonName, resp.TLS.PeerCertificates[0].Subject.CommonName)
|
||||
assert.Equal(s.T(), sub.expectedAlgorithm, resp.TLS.PeerCertificates[0].PublicKeyAlgorithm)
|
||||
assert.Contains(s.T(), gotDomains, sub.expectedDomain)
|
||||
assert.Equal(s.T(), sub.expectedAlgorithm, gotPublicKeyAlgorithm)
|
||||
}
|
||||
}
|
||||
|
||||
28
integration/fixtures/https/max_concurrent_stream.toml
Normal file
28
integration/fixtures/https/max_concurrent_stream.toml
Normal file
@@ -0,0 +1,28 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[serversTransport]
|
||||
insecureSkipVerify=true
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
[entryPoints.web.http2]
|
||||
maxConcurrentStreams = 42
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
## dynamic configuration ##
|
||||
|
||||
[tls.stores]
|
||||
[tls.stores.default.defaultCertificate]
|
||||
certFile = "resources/tls/local.cert"
|
||||
keyFile = "resources/tls/local.key"
|
||||
@@ -9,24 +9,24 @@
|
||||
# Use certificate in net/internal/testcert.go
|
||||
rootCAs = [ """
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDOTCCAiGgAwIBAgIQSRJrEpBGFc7tNb1fb5pKFzANBgkqhkiG9w0BAQsFADAS
|
||||
MIIDSDCCAjCgAwIBAgIQEP/md970HysdBTpuzDOf0DANBgkqhkiG9w0BAQsFADAS
|
||||
MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
|
||||
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEA6Gba5tHV1dAKouAaXO3/ebDUU4rvwCUg/CNaJ2PT5xLD4N1Vcb8r
|
||||
bFSW2HXKq+MPfVdwIKR/1DczEoAGf/JWQTW7EgzlXrCd3rlajEX2D73faWJekD0U
|
||||
aUgz5vtrTXZ90BQL7WvRICd7FlEZ6FPOcPlumiyNmzUqtwGhO+9ad1W5BqJaRI6P
|
||||
YfouNkwR6Na4TzSj5BrqUfP0FwDizKSJ0XXmh8g8G9mtwxOSN3Ru1QFc61Xyeluk
|
||||
POGKBV/q6RBNklTNe0gI8usUMlYyoC7ytppNMW7X2vodAelSu25jgx2anj9fDVZu
|
||||
h7AXF5+4nJS4AAt0n1lNY7nGSsdZas8PbQIDAQABo4GIMIGFMA4GA1UdDwEB/wQE
|
||||
MIIBCgKCAQEAxcl69ROJdxjN+MJZnbFrYxyQooADCsJ6VDkuMyNQIix/Hk15Nk/u
|
||||
FyBX1Me++aEpGmY3RIY4fUvELqT/srvAHsTXwVVSttMcY8pcAFmXSqo3x4MuUTG/
|
||||
jCX3Vftj0r3EM5M8ImY1rzA/jqTTLJg00rD+DmuDABcqQvoXw/RV8w1yTRi5BPoH
|
||||
DFD/AWTt/YgMvk1l2Yq/xI8VbMUIpjBoGXxWsSevQ5i2s1mk9/yZzu0Ysp1tTlzD
|
||||
qOPa4ysFjBitdXiwfxjxtv5nXqOCP5rheKO0sWLk0fetMp1OV5JSJMAJw6c2ZMkl
|
||||
U2WMqAEpRjdE/vHfIuNg+yGaRRqI07NZRQIDAQABo4GXMIGUMA4GA1UdDwEB/wQE
|
||||
AwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBStsdjh3/JCXXYlQryOrL4Sh7BW5TAuBgNVHREEJzAlggtleGFtcGxlLmNv
|
||||
bYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAxWGI
|
||||
5NhpF3nwwy/4yB4i/CwwSpLrWUa70NyhvprUBC50PxiXav1TeDzwzLx/o5HyNwsv
|
||||
cxv3HdkLW59i/0SlJSrNnWdfZ19oTcS+6PtLoVyISgtyN6DpkKpdG1cOkW3Cy2P2
|
||||
+tK/tKHRP1Y/Ra0RiDpOAmqn0gCOFGz8+lqDIor/T7MTpibL3IxqWfPrvfVRHL3B
|
||||
grw/ZQTTIVjjh4JBSW3WyWgNo/ikC1lrVxzl4iPUGptxT36Cr7Zk2Bsg0XqwbOvK
|
||||
5d+NTDREkSnUbie4GeutujmX3Dsx88UiV6UY/4lHJa6I5leHUNOHahRbpbWeOfs/
|
||||
WkBKOclmOV2xlTVuPw==
|
||||
DgQWBBQR5QIzmacmw78ZI1C4MXw7Q0wJ1jA9BgNVHREENjA0ggtleGFtcGxlLmNv
|
||||
bYINKi5leGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG
|
||||
9w0BAQsFAAOCAQEACrRNgiioUDzxQftd0fwOa6iRRcPampZRDtuaF68yNHoNWbOu
|
||||
LUwc05eOWxRq3iABGSk2xg+FXM3DDeW4HhAhCFptq7jbVZ+4Jj6HeJG9mYRatAxR
|
||||
Y/dEpa0D0EHhDxxVg6UzKOXB355n0IetGE/aWvyTV9SiDs6QsaC57Q9qq1/mitx5
|
||||
2GFBoapol9L5FxCc77bztzK8CpLujkBi25Vk6GAFbl27opLfpyxkM+rX/T6MXCPO
|
||||
6/YBacNZ7ff1/57Etg4i5mNA6ubCpuc4Gi9oYqCNNohftr2lkJr7REdDR6OW0lsL
|
||||
rF7r4gUnKeC7mYIH1zypY7laskopiLFAfe96Kg==
|
||||
-----END CERTIFICATE-----
|
||||
"""]
|
||||
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDOTCCAiGgAwIBAgIQSRJrEpBGFc7tNb1fb5pKFzANBgkqhkiG9w0BAQsFADAS
|
||||
MIIDSDCCAjCgAwIBAgIQEP/md970HysdBTpuzDOf0DANBgkqhkiG9w0BAQsFADAS
|
||||
MRAwDgYDVQQKEwdBY21lIENvMCAXDTcwMDEwMTAwMDAwMFoYDzIwODQwMTI5MTYw
|
||||
MDAwWjASMRAwDgYDVQQKEwdBY21lIENvMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
|
||||
MIIBCgKCAQEA6Gba5tHV1dAKouAaXO3/ebDUU4rvwCUg/CNaJ2PT5xLD4N1Vcb8r
|
||||
bFSW2HXKq+MPfVdwIKR/1DczEoAGf/JWQTW7EgzlXrCd3rlajEX2D73faWJekD0U
|
||||
aUgz5vtrTXZ90BQL7WvRICd7FlEZ6FPOcPlumiyNmzUqtwGhO+9ad1W5BqJaRI6P
|
||||
YfouNkwR6Na4TzSj5BrqUfP0FwDizKSJ0XXmh8g8G9mtwxOSN3Ru1QFc61Xyeluk
|
||||
POGKBV/q6RBNklTNe0gI8usUMlYyoC7ytppNMW7X2vodAelSu25jgx2anj9fDVZu
|
||||
h7AXF5+4nJS4AAt0n1lNY7nGSsdZas8PbQIDAQABo4GIMIGFMA4GA1UdDwEB/wQE
|
||||
MIIBCgKCAQEAxcl69ROJdxjN+MJZnbFrYxyQooADCsJ6VDkuMyNQIix/Hk15Nk/u
|
||||
FyBX1Me++aEpGmY3RIY4fUvELqT/srvAHsTXwVVSttMcY8pcAFmXSqo3x4MuUTG/
|
||||
jCX3Vftj0r3EM5M8ImY1rzA/jqTTLJg00rD+DmuDABcqQvoXw/RV8w1yTRi5BPoH
|
||||
DFD/AWTt/YgMvk1l2Yq/xI8VbMUIpjBoGXxWsSevQ5i2s1mk9/yZzu0Ysp1tTlzD
|
||||
qOPa4ysFjBitdXiwfxjxtv5nXqOCP5rheKO0sWLk0fetMp1OV5JSJMAJw6c2ZMkl
|
||||
U2WMqAEpRjdE/vHfIuNg+yGaRRqI07NZRQIDAQABo4GXMIGUMA4GA1UdDwEB/wQE
|
||||
AwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud
|
||||
DgQWBBStsdjh3/JCXXYlQryOrL4Sh7BW5TAuBgNVHREEJzAlggtleGFtcGxlLmNv
|
||||
bYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG9w0BAQsFAAOCAQEAxWGI
|
||||
5NhpF3nwwy/4yB4i/CwwSpLrWUa70NyhvprUBC50PxiXav1TeDzwzLx/o5HyNwsv
|
||||
cxv3HdkLW59i/0SlJSrNnWdfZ19oTcS+6PtLoVyISgtyN6DpkKpdG1cOkW3Cy2P2
|
||||
+tK/tKHRP1Y/Ra0RiDpOAmqn0gCOFGz8+lqDIor/T7MTpibL3IxqWfPrvfVRHL3B
|
||||
grw/ZQTTIVjjh4JBSW3WyWgNo/ikC1lrVxzl4iPUGptxT36Cr7Zk2Bsg0XqwbOvK
|
||||
5d+NTDREkSnUbie4GeutujmX3Dsx88UiV6UY/4lHJa6I5leHUNOHahRbpbWeOfs/
|
||||
WkBKOclmOV2xlTVuPw==
|
||||
DgQWBBQR5QIzmacmw78ZI1C4MXw7Q0wJ1jA9BgNVHREENjA0ggtleGFtcGxlLmNv
|
||||
bYINKi5leGFtcGxlLmNvbYcEfwAAAYcQAAAAAAAAAAAAAAAAAAAAATANBgkqhkiG
|
||||
9w0BAQsFAAOCAQEACrRNgiioUDzxQftd0fwOa6iRRcPampZRDtuaF68yNHoNWbOu
|
||||
LUwc05eOWxRq3iABGSk2xg+FXM3DDeW4HhAhCFptq7jbVZ+4Jj6HeJG9mYRatAxR
|
||||
Y/dEpa0D0EHhDxxVg6UzKOXB355n0IetGE/aWvyTV9SiDs6QsaC57Q9qq1/mitx5
|
||||
2GFBoapol9L5FxCc77bztzK8CpLujkBi25Vk6GAFbl27opLfpyxkM+rX/T6MXCPO
|
||||
6/YBacNZ7ff1/57Etg4i5mNA6ubCpuc4Gi9oYqCNNohftr2lkJr7REdDR6OW0lsL
|
||||
rF7r4gUnKeC7mYIH1zypY7laskopiLFAfe96Kg==
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -1478,7 +1478,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -1497,7 +1497,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -1886,7 +1886,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
@@ -3908,7 +3908,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
regex:
|
||||
description: Regex defines the regex used to match and capture
|
||||
@@ -3927,7 +3927,7 @@ spec:
|
||||
properties:
|
||||
permanent:
|
||||
description: Permanent defines whether the redirection is permanent
|
||||
(301).
|
||||
(308).
|
||||
type: boolean
|
||||
port:
|
||||
description: Port defines the port of the new URL.
|
||||
@@ -4316,7 +4316,7 @@ spec:
|
||||
type: object
|
||||
curvePreferences:
|
||||
description: |-
|
||||
CurvePreferences defines the preferred elliptic curves in a specific order.
|
||||
CurvePreferences defines the preferred elliptic curves.
|
||||
More info: https://doc.traefik.io/traefik/v2.11/https/tls/#curve-preferences
|
||||
items:
|
||||
type: string
|
||||
|
||||
41
integration/fixtures/simple_clean_path.toml
Normal file
41
integration/fixtures/simple_clean_path.toml
Normal file
@@ -0,0 +1,41 @@
|
||||
[global]
|
||||
checkNewVersion = false
|
||||
sendAnonymousUsage = false
|
||||
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
[entryPoints.web2]
|
||||
address = ":8001"
|
||||
[entryPoints.web2.http]
|
||||
sanitizePath = false
|
||||
|
||||
[log]
|
||||
level = "DEBUG"
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
[providers.file]
|
||||
filename = "{{ .SelfFilename }}"
|
||||
|
||||
# dynamic configuration
|
||||
[http.routers]
|
||||
[http.routers.without]
|
||||
rule = "PathPrefix(`/without`)"
|
||||
service = "whoami"
|
||||
|
||||
[http.routers.with]
|
||||
rule = "PathPrefix(`/with`)"
|
||||
middlewares = ["test-redirectscheme"]
|
||||
service = "whoami"
|
||||
|
||||
[http.middlewares]
|
||||
[http.middlewares.test-redirectscheme.redirectScheme]
|
||||
scheme = "https"
|
||||
permanent = false
|
||||
|
||||
[http.services]
|
||||
[http.services.whoami.loadBalancer]
|
||||
[[http.services.whoami.loadBalancer.servers]]
|
||||
url = "{{ .Server1 }}"
|
||||
@@ -8,6 +8,8 @@
|
||||
[entryPoints]
|
||||
[entryPoints.web]
|
||||
address = ":8000"
|
||||
[entryPoints.web.http.encodedCharacters]
|
||||
allowEncodedSlash = true
|
||||
|
||||
[api]
|
||||
insecure = true
|
||||
|
||||
@@ -3,6 +3,7 @@ package integration
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
@@ -18,6 +19,7 @@ import (
|
||||
"github.com/traefik/traefik/v2/integration/try"
|
||||
"github.com/traefik/traefik/v2/pkg/config/dynamic"
|
||||
traefiktls "github.com/traefik/traefik/v2/pkg/tls"
|
||||
"golang.org/x/net/http2"
|
||||
)
|
||||
|
||||
// HTTPSSuite tests suite.
|
||||
@@ -937,11 +939,6 @@ func (s *HTTPSSuite) TestEntryPointHttpsRedirectAndPathModification() {
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api/",
|
||||
},
|
||||
{
|
||||
desc: "Stripped URL with double trailing slash redirect",
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api//",
|
||||
},
|
||||
{
|
||||
desc: "Stripped URL with path redirect",
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
@@ -952,21 +949,11 @@ func (s *HTTPSSuite) TestEntryPointHttpsRedirectAndPathModification() {
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api/bacon/",
|
||||
},
|
||||
{
|
||||
desc: "Stripped URL with path and double trailing slash redirect",
|
||||
hosts: []string{"example.com", "example2.com", "foo.com", "foo2.com", "bar.com", "bar2.com"},
|
||||
path: "/api/bacon//",
|
||||
},
|
||||
{
|
||||
desc: "Root Path with redirect",
|
||||
hosts: []string{"test.com", "test2.com", "pow.com", "pow2.com"},
|
||||
path: "/",
|
||||
},
|
||||
{
|
||||
desc: "Root Path with double trailing slash redirect",
|
||||
hosts: []string{"test.com", "test2.com", "pow.com", "pow2.com"},
|
||||
path: "//",
|
||||
},
|
||||
{
|
||||
desc: "Path modify with redirect",
|
||||
hosts: []string{"test.com", "test2.com", "pow.com", "pow2.com"},
|
||||
@@ -1188,3 +1175,38 @@ func (s *HTTPSSuite) TestWithInvalidTLSOption() {
|
||||
assert.Nil(s.T(), conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestMaxConcurrentStream() {
|
||||
file := s.adaptFile("fixtures/https/max_concurrent_stream.toml", struct{}{})
|
||||
|
||||
s.traefikCmd(withConfigFile(file), "--log.level=DEBUG", "--accesslog")
|
||||
|
||||
// Wait for traefik.
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", time.Second, try.BodyContains("api@internal"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// Add client self-signed cert.
|
||||
roots := x509.NewCertPool()
|
||||
certContent, err := os.ReadFile("./resources/tls/local.cert")
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
roots.AppendCertsFromPEM(certContent)
|
||||
|
||||
// Open a connection to inspect SettingsFrame.
|
||||
conn, err := tls.Dial("tcp", "127.0.0.1:8000", &tls.Config{
|
||||
RootCAs: roots,
|
||||
NextProtos: []string{"h2"},
|
||||
})
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
framer := http2.NewFramer(nil, conn)
|
||||
frame, err := framer.ReadFrame()
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
fr, ok := frame.(*http2.SettingsFrame)
|
||||
require.True(s.T(), ok)
|
||||
|
||||
maxConcurrentStream, ok := fr.Value(http2.SettingMaxConcurrentStreams)
|
||||
assert.True(s.T(), ok)
|
||||
assert.Equal(s.T(), uint32(42), maxConcurrentStream)
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ func (s *BaseSuite) displayTraefikLogFile(path string) {
|
||||
// fmt.Printf("%s: Traefik logs: \n", c.TestName())
|
||||
fmt.Print("Traefik logs: \n")
|
||||
if errRead == nil {
|
||||
fmt.Println(content)
|
||||
fmt.Println(string(content))
|
||||
} else {
|
||||
fmt.Println(errRead)
|
||||
}
|
||||
|
||||
@@ -92,6 +92,9 @@ func (s *RedisSentinelSuite) setupSentinelConfiguration(ports []string) {
|
||||
require.NoError(s.T(), err)
|
||||
defer tmpFile.Close()
|
||||
|
||||
err = tmpFile.Chmod(0o666)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
model := structs.Map(templateValue)
|
||||
model["SelfFilename"] = tmpFile.Name()
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
version: "3.8"
|
||||
services:
|
||||
pebble:
|
||||
image: letsencrypt/pebble:v2.3.1
|
||||
image: ghcr.io/letsencrypt/pebble:2.8.0
|
||||
command:
|
||||
- pebble
|
||||
- --dnsserver
|
||||
- host.docker.internal:5053
|
||||
environment:
|
||||
|
||||
@@ -1385,3 +1385,100 @@ func (s *SimpleSuite) TestDenyFragment() {
|
||||
require.NoError(s.T(), err)
|
||||
assert.Equal(s.T(), http.StatusBadRequest, resp.StatusCode)
|
||||
}
|
||||
|
||||
func (s *SimpleSuite) TestSanitizePath() {
|
||||
s.createComposeProject("base")
|
||||
|
||||
s.composeUp()
|
||||
defer s.composeDown()
|
||||
|
||||
whoami1URL := "http://" + net.JoinHostPort(s.getComposeServiceIP("whoami1"), "80")
|
||||
|
||||
file := s.adaptFile("fixtures/simple_clean_path.toml", struct {
|
||||
Server1 string
|
||||
}{whoami1URL})
|
||||
|
||||
s.traefikCmd(withConfigFile(file))
|
||||
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 1*time.Second, try.BodyContains("PathPrefix(`/with`)"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
testCases := []struct {
|
||||
desc string
|
||||
request string
|
||||
target string
|
||||
body string
|
||||
expected int
|
||||
}{
|
||||
{
|
||||
desc: "Explicit call to the route with a middleware",
|
||||
request: "GET /with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Explicit call to the route without a middleware",
|
||||
request: "GET /without HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusOK,
|
||||
body: "GET /without HTTP/1.1",
|
||||
},
|
||||
{
|
||||
desc: "Implicit call to the route with a middleware",
|
||||
request: "GET /without/../with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Implicit encoded dot dots call to the route with a middleware",
|
||||
request: "GET /without/%2E%2E/with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Implicit with encoded unreserved character call to the route with a middleware",
|
||||
request: "GET /%77ith HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8000",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Explicit call to the route with a middleware, and disable path sanitization",
|
||||
request: "GET /with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8001",
|
||||
expected: http.StatusFound,
|
||||
},
|
||||
{
|
||||
desc: "Explicit call to the route without a middleware, and disable path sanitization",
|
||||
request: "GET /without HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8001",
|
||||
expected: http.StatusOK,
|
||||
body: "GET /without HTTP/1.1",
|
||||
},
|
||||
{
|
||||
desc: "Implicit call to the route with a middleware, and disable path sanitization",
|
||||
request: "GET /without/../with HTTP/1.1\r\nHost: other.localhost\r\n\r\n",
|
||||
target: "127.0.0.1:8001",
|
||||
// The whoami is redirecting to /with, but the path is not sanitized.
|
||||
expected: http.StatusMovedPermanently,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testCases {
|
||||
conn, err := net.Dial("tcp", test.target)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
_, err = conn.Write([]byte(test.request))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
resp, err := http.ReadResponse(bufio.NewReader(conn), nil)
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
assert.Equalf(s.T(), test.expected, resp.StatusCode, "%s failed with %d instead of %d", test.desc, resp.StatusCode, test.expected)
|
||||
|
||||
if test.body != "" {
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
require.NoError(s.T(), err)
|
||||
assert.Contains(s.T(), string(body), test.body)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,7 +278,7 @@ func (s *TCPSuite) TestWRR() {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
|
||||
assert.EqualValues(s.T(), map[string]int{"whoami-b": 3, "whoami-ab": 1}, call)
|
||||
assert.Equal(s.T(), map[string]int{"whoami-b": 3, "whoami-ab": 1}, call)
|
||||
}
|
||||
|
||||
func welcome(addr string) (string, error) {
|
||||
|
||||
@@ -96,7 +96,7 @@ func (s *UDPSuite) TestWRR() {
|
||||
call["unknown"]++
|
||||
}
|
||||
}
|
||||
assert.EqualValues(s.T(), map[string]int{"whoami-a": 3, "whoami-b": 2, "whoami-c": 3}, call)
|
||||
assert.Equal(s.T(), map[string]int{"whoami-a": 3, "whoami-b": 2, "whoami-c": 3}, call)
|
||||
close(stop)
|
||||
}()
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"github.com/traefik/traefik/v2/integration/try"
|
||||
"golang.org/x/net/http2"
|
||||
"golang.org/x/net/websocket"
|
||||
)
|
||||
|
||||
@@ -451,6 +452,44 @@ func (s *WebsocketSuite) TestSSLhttp2() {
|
||||
assert.Equal(s.T(), "OK", string(msg))
|
||||
}
|
||||
|
||||
func (s *WebsocketSuite) TestSettingEnableConnectProtocol() {
|
||||
file := s.adaptFile("fixtures/websocket/config_https.toml", struct {
|
||||
WebsocketServer string
|
||||
}{
|
||||
WebsocketServer: "http://127.0.0.1",
|
||||
})
|
||||
|
||||
s.traefikCmd(withConfigFile(file), "--log.level=DEBUG", "--accesslog")
|
||||
|
||||
// Wait for traefik.
|
||||
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("127.0.0.1"))
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
// Add client self-signed cert.
|
||||
roots := x509.NewCertPool()
|
||||
certContent, err := os.ReadFile("./resources/tls/local.cert")
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
roots.AppendCertsFromPEM(certContent)
|
||||
|
||||
// Open a connection to inspect SettingsFrame.
|
||||
conn, err := tls.Dial("tcp", "127.0.0.1:8000", &tls.Config{
|
||||
RootCAs: roots,
|
||||
NextProtos: []string{"h2"},
|
||||
})
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
framer := http2.NewFramer(nil, conn)
|
||||
frame, err := framer.ReadFrame()
|
||||
require.NoError(s.T(), err)
|
||||
|
||||
fr, ok := frame.(*http2.SettingsFrame)
|
||||
require.True(s.T(), ok)
|
||||
|
||||
_, ok = fr.Value(http2.SettingEnableConnectProtocol)
|
||||
assert.False(s.T(), ok)
|
||||
}
|
||||
|
||||
func (s *WebsocketSuite) TestHeaderAreForwarded() {
|
||||
upgrader := gorillawebsocket.Upgrader{} // use default options
|
||||
|
||||
|
||||
@@ -349,6 +349,11 @@ func genKVDynConfDoc(outputFile string) {
|
||||
CODE GENERATED AUTOMATICALLY
|
||||
THIS FILE MUST NOT BE EDITED BY HAND
|
||||
-->
|
||||
`)
|
||||
|
||||
_, _ = fmt.Fprintf(file, `
|
||||
| Key (Path) | Value |
|
||||
|------------|-------|
|
||||
`)
|
||||
|
||||
for _, k := range keys {
|
||||
|
||||
66
internal/testsci/genmatrix.go
Normal file
66
internal/testsci/genmatrix.go
Normal file
@@ -0,0 +1,66 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/traefik/traefik/v2/pkg/log"
|
||||
"golang.org/x/tools/go/packages"
|
||||
)
|
||||
|
||||
const groupCount = 12
|
||||
|
||||
type group struct {
|
||||
Group string `json:"group"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
logger := log.WithoutContext()
|
||||
|
||||
cfg := &packages.Config{
|
||||
Mode: packages.NeedName,
|
||||
Dir: ".",
|
||||
}
|
||||
|
||||
pkgs, err := packages.Load(cfg, "./cmd/...", "./pkg/...")
|
||||
if err != nil {
|
||||
logger.Fatalf("Loading packages: %v", err)
|
||||
}
|
||||
|
||||
var packageNames []string
|
||||
for _, pkg := range pkgs {
|
||||
if pkg.PkgPath != "" {
|
||||
packageNames = append(packageNames, pkg.PkgPath)
|
||||
}
|
||||
}
|
||||
|
||||
total := len(packageNames)
|
||||
perGroup := (total + groupCount - 1) / groupCount
|
||||
|
||||
fmt.Fprintf(os.Stderr, "Total packages: %d\n", total)
|
||||
fmt.Fprintf(os.Stderr, "Packages per group: %d\n", perGroup)
|
||||
|
||||
var matrix []group
|
||||
for i := range groupCount {
|
||||
start := i * perGroup
|
||||
end := start + perGroup
|
||||
if start >= total {
|
||||
break
|
||||
}
|
||||
if end > total {
|
||||
end = total
|
||||
}
|
||||
g := strings.Join(packageNames[start:end], " ")
|
||||
matrix = append(matrix, group{Group: g})
|
||||
}
|
||||
|
||||
jsonBytes, err := json.Marshal(matrix)
|
||||
if err != nil {
|
||||
logger.Fatalf("Failed to marshal matrix: %v", err)
|
||||
}
|
||||
|
||||
// Output for GitHub Actions
|
||||
fmt.Printf("matrix=%s\n", string(jsonBytes))
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
@@ -926,8 +925,8 @@ func TestHandler_HTTP(t *testing.T) {
|
||||
rtConf := &test.conf
|
||||
// To lazily initialize the Statuses.
|
||||
rtConf.PopulateUsedBy()
|
||||
rtConf.GetRoutersByEntryPoints(context.Background(), []string{"web"}, false)
|
||||
rtConf.GetRoutersByEntryPoints(context.Background(), []string{"web"}, true)
|
||||
rtConf.GetRoutersByEntryPoints(t.Context(), []string{"web"}, false)
|
||||
rtConf.GetRoutersByEntryPoints(t.Context(), []string{"web"}, true)
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -797,7 +796,7 @@ func TestHandler_TCP(t *testing.T) {
|
||||
rtConf := &test.conf
|
||||
// To lazily initialize the Statuses.
|
||||
rtConf.PopulateUsedBy()
|
||||
rtConf.GetTCPRoutersByEntryPoints(context.Background(), []string{"web"})
|
||||
rtConf.GetTCPRoutersByEntryPoints(t.Context(), []string{"web"})
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -536,7 +535,7 @@ func TestHandler_UDP(t *testing.T) {
|
||||
rtConf := &test.conf
|
||||
// To lazily initialize the Statuses.
|
||||
rtConf.PopulateUsedBy()
|
||||
rtConf.GetUDPRoutersByEntryPoints(context.Background(), []string{"web"})
|
||||
rtConf.GetUDPRoutersByEntryPoints(t.Context(), []string{"web"})
|
||||
|
||||
handler := New(static.Configuration{API: &static.API{}, Global: &static.Global{}}, rtConf)
|
||||
server := httptest.NewServer(handler.createRouter())
|
||||
|
||||
6
pkg/api/testdata/entrypoint-bar.json
vendored
6
pkg/api/testdata/entrypoint-bar.json
vendored
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"address": ":81",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "bar"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{
|
||||
"address": ":81",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "foo / bar"
|
||||
}
|
||||
|
||||
22
pkg/api/testdata/entrypoints-many-lastpage.json
vendored
22
pkg/api/testdata/entrypoints-many-lastpage.json
vendored
@@ -1,27 +1,37 @@
|
||||
[
|
||||
{
|
||||
"address": ":14",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "ep14"
|
||||
},
|
||||
{
|
||||
"address": ":15",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "ep15"
|
||||
},
|
||||
{
|
||||
"address": ":16",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "ep16"
|
||||
},
|
||||
{
|
||||
"address": ":17",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "ep17"
|
||||
},
|
||||
{
|
||||
"address": ":18",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "ep18"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
6
pkg/api/testdata/entrypoints-page2.json
vendored
6
pkg/api/testdata/entrypoints-page2.json
vendored
@@ -1,7 +1,9 @@
|
||||
[
|
||||
{
|
||||
"address": ":82",
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "web2"
|
||||
}
|
||||
]
|
||||
]
|
||||
|
||||
8
pkg/api/testdata/entrypoints.json
vendored
8
pkg/api/testdata/entrypoints.json
vendored
@@ -8,7 +8,9 @@
|
||||
"192.168.1.4"
|
||||
]
|
||||
},
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "web",
|
||||
"proxyProtocol": {
|
||||
"insecure": true,
|
||||
@@ -38,7 +40,9 @@
|
||||
"192.168.1.40"
|
||||
]
|
||||
},
|
||||
"http": {},
|
||||
"http": {
|
||||
"encodedCharacters": {}
|
||||
},
|
||||
"name": "websecure",
|
||||
"proxyProtocol": {
|
||||
"insecure": true,
|
||||
|
||||
@@ -489,7 +489,7 @@ type RedirectRegex struct {
|
||||
Regex string `json:"regex,omitempty" toml:"regex,omitempty" yaml:"regex,omitempty"`
|
||||
// Replacement defines how to modify the URL to have the new target URL.
|
||||
Replacement string `json:"replacement,omitempty" toml:"replacement,omitempty" yaml:"replacement,omitempty"`
|
||||
// Permanent defines whether the redirection is permanent (301).
|
||||
// Permanent defines whether the redirection is permanent (308).
|
||||
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
@@ -503,7 +503,7 @@ type RedirectScheme struct {
|
||||
Scheme string `json:"scheme,omitempty" toml:"scheme,omitempty" yaml:"scheme,omitempty" export:"true"`
|
||||
// Port defines the port of the new URL.
|
||||
Port string `json:"port,omitempty" toml:"port,omitempty" yaml:"port,omitempty" export:"true"`
|
||||
// Permanent defines whether the redirection is permanent (301).
|
||||
// Permanent defines whether the redirection is permanent (308).
|
||||
Permanent bool `json:"permanent,omitempty" toml:"permanent,omitempty" yaml:"permanent,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
/*
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2024 Traefik Labs
|
||||
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -211,7 +210,7 @@ func TestGetRoutersByEntryPoints(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runtimeConfig := NewConfig(test.conf)
|
||||
actual := runtimeConfig.GetRoutersByEntryPoints(context.Background(), test.entryPoints, false)
|
||||
actual := runtimeConfig.GetRoutersByEntryPoints(t.Context(), test.entryPoints, false)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -211,7 +210,7 @@ func TestGetTCPRoutersByEntryPoints(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runtimeConfig := NewConfig(test.conf)
|
||||
actual := runtimeConfig.GetTCPRoutersByEntryPoints(context.Background(), test.entryPoints)
|
||||
actual := runtimeConfig.GetTCPRoutersByEntryPoints(t.Context(), test.entryPoints)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -192,7 +191,7 @@ func TestGetUDPRoutersByEntryPoints(t *testing.T) {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
runtimeConfig := NewConfig(test.conf)
|
||||
actual := runtimeConfig.GetUDPRoutersByEntryPoints(context.Background(), test.entryPoints)
|
||||
actual := runtimeConfig.GetUDPRoutersByEntryPoints(t.Context(), test.entryPoints)
|
||||
assert.Equal(t, test.expected, actual)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -52,16 +52,69 @@ func (ep *EntryPoint) SetDefaults() {
|
||||
ep.ForwardedHeaders = &ForwardedHeaders{}
|
||||
ep.UDP = &UDPConfig{}
|
||||
ep.UDP.SetDefaults()
|
||||
ep.HTTP.SetDefaults()
|
||||
ep.HTTP2 = &HTTP2Config{}
|
||||
ep.HTTP2.SetDefaults()
|
||||
}
|
||||
|
||||
// HTTPConfig is the HTTP configuration of an entry point.
|
||||
type HTTPConfig struct {
|
||||
Redirections *Redirections `description:"Set of redirection" json:"redirections,omitempty" toml:"redirections,omitempty" yaml:"redirections,omitempty" export:"true"`
|
||||
Middlewares []string `description:"Default middlewares for the routers linked to the entry point." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
|
||||
TLS *TLSConfig `description:"Default TLS configuration for the routers linked to the entry point." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||
EncodeQuerySemicolons bool `description:"Defines whether request query semicolons should be URLEncoded." json:"encodeQuerySemicolons,omitempty" toml:"encodeQuerySemicolons,omitempty" yaml:"encodeQuerySemicolons,omitempty"`
|
||||
Redirections *Redirections `description:"Set of redirection" json:"redirections,omitempty" toml:"redirections,omitempty" yaml:"redirections,omitempty" export:"true"`
|
||||
Middlewares []string `description:"Default middlewares for the routers linked to the entry point." json:"middlewares,omitempty" toml:"middlewares,omitempty" yaml:"middlewares,omitempty" export:"true"`
|
||||
TLS *TLSConfig `description:"Default TLS configuration for the routers linked to the entry point." json:"tls,omitempty" toml:"tls,omitempty" yaml:"tls,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
|
||||
EncodedCharacters EncodedCharacters `description:"Defines which encoded characters are allowed in the request path." json:"encodedCharacters,omitempty" toml:"encodedCharacters,omitempty" yaml:"encodedCharacters,omitempty" export:"true"`
|
||||
EncodeQuerySemicolons bool `description:"Defines whether request query semicolons should be URLEncoded." json:"encodeQuerySemicolons,omitempty" toml:"encodeQuerySemicolons,omitempty" yaml:"encodeQuerySemicolons,omitempty" export:"true"`
|
||||
SanitizePath *bool `description:"Defines whether to enable request path sanitization (removal of /./, /../ and multiple slash sequences)." json:"sanitizePath,omitempty" toml:"sanitizePath,omitempty" yaml:"sanitizePath,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// SetDefaults sets the default values.
|
||||
func (h *HTTPConfig) SetDefaults() {
|
||||
sanitizePath := true
|
||||
h.SanitizePath = &sanitizePath
|
||||
}
|
||||
|
||||
// EncodedCharacters configures which encoded characters are allowed in the request path.
|
||||
type EncodedCharacters struct {
|
||||
AllowEncodedSlash bool `description:"Defines whether requests with encoded slash characters in the path are allowed." json:"allowEncodedSlash,omitempty" toml:"allowEncodedSlash,omitempty" yaml:"allowEncodedSlash,omitempty" export:"true"`
|
||||
AllowEncodedBackSlash bool `description:"Defines whether requests with encoded back slash characters in the path are allowed." json:"allowEncodedBackSlash,omitempty" toml:"allowEncodedBackSlash,omitempty" yaml:"allowEncodedBackSlash,omitempty" export:"true"`
|
||||
AllowEncodedNullCharacter bool `description:"Defines whether requests with encoded null characters in the path are allowed." json:"allowEncodedNullCharacter,omitempty" toml:"allowEncodedNullCharacter,omitempty" yaml:"allowEncodedNullCharacter,omitempty" export:"true"`
|
||||
AllowEncodedSemicolon bool `description:"Defines whether requests with encoded semicolon characters in the path are allowed." json:"allowEncodedSemicolon,omitempty" toml:"allowEncodedSemicolon,omitempty" yaml:"allowEncodedSemicolon,omitempty" export:"true"`
|
||||
AllowEncodedPercent bool `description:"Defines whether requests with encoded percent characters in the path are allowed." json:"allowEncodedPercent,omitempty" toml:"allowEncodedPercent,omitempty" yaml:"allowEncodedPercent,omitempty" export:"true"`
|
||||
AllowEncodedQuestionMark bool `description:"Defines whether requests with encoded question mark characters in the path are allowed." json:"allowEncodedQuestionMark,omitempty" toml:"allowEncodedQuestionMark,omitempty" yaml:"allowEncodedQuestionMark,omitempty" export:"true"`
|
||||
AllowEncodedHash bool `description:"Defines whether requests with encoded hash characters in the path are allowed." json:"allowEncodedHash,omitempty" toml:"allowEncodedHash,omitempty" yaml:"allowEncodedHash,omitempty" export:"true"`
|
||||
}
|
||||
|
||||
// Map returns a map of unallowed encoded characters.
|
||||
func (h *EncodedCharacters) Map() map[string]struct{} {
|
||||
characters := make(map[string]struct{})
|
||||
|
||||
if !h.AllowEncodedSlash {
|
||||
characters["%2F"] = struct{}{}
|
||||
characters["%2f"] = struct{}{}
|
||||
}
|
||||
if !h.AllowEncodedBackSlash {
|
||||
characters["%5C"] = struct{}{}
|
||||
characters["%5c"] = struct{}{}
|
||||
}
|
||||
if !h.AllowEncodedNullCharacter {
|
||||
characters["%00"] = struct{}{}
|
||||
}
|
||||
if !h.AllowEncodedSemicolon {
|
||||
characters["%3B"] = struct{}{}
|
||||
characters["%3b"] = struct{}{}
|
||||
}
|
||||
if !h.AllowEncodedPercent {
|
||||
characters["%25"] = struct{}{}
|
||||
}
|
||||
if !h.AllowEncodedQuestionMark {
|
||||
characters["%3F"] = struct{}{}
|
||||
characters["%3f"] = struct{}{}
|
||||
}
|
||||
if !h.AllowEncodedHash {
|
||||
characters["%23"] = struct{}{}
|
||||
}
|
||||
|
||||
return characters
|
||||
}
|
||||
|
||||
// HTTP2Config is the HTTP2 configuration of an entry point.
|
||||
|
||||
@@ -65,3 +65,161 @@ func TestEntryPointProtocol(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncodedCharactersMap(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
config EncodedCharacters
|
||||
expected map[string]struct{}
|
||||
}{
|
||||
{
|
||||
name: "Handles empty configuration",
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%00": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%25": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Exclude encoded slash when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedSlash: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%00": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%25": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Exclude encoded backslash when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedBackSlash: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%00": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%25": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
name: "Exclude encoded null character when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedNullCharacter: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%25": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Exclude encoded semicolon when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedSemicolon: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%00": {},
|
||||
"%25": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Exclude encoded percent when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedPercent: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%00": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Exclude encoded question mark when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedQuestionMark: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%00": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%25": {},
|
||||
"%23": {},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Exclude encoded hash when allowed",
|
||||
config: EncodedCharacters{
|
||||
AllowEncodedHash: true,
|
||||
},
|
||||
expected: map[string]struct{}{
|
||||
"%2F": {},
|
||||
"%2f": {},
|
||||
"%5C": {},
|
||||
"%5c": {},
|
||||
"%00": {},
|
||||
"%3B": {},
|
||||
"%3b": {},
|
||||
"%25": {},
|
||||
"%3F": {},
|
||||
"%3f": {},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
result := test.config.Map()
|
||||
require.Equal(t, test.expected, result)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -273,6 +273,25 @@ func (c *Configuration) SetEffectiveConfiguration() {
|
||||
c.Providers.KubernetesGateway.EntryPoints = entryPoints
|
||||
}
|
||||
|
||||
for _, resolver := range c.CertificatesResolvers {
|
||||
if resolver.ACME == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if resolver.ACME.DNSChallenge == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
switch resolver.ACME.DNSChallenge.Provider {
|
||||
case "googledomains", "cloudxns", "brandit":
|
||||
log.WithoutContext().Warnf("%s DNS provider is deprecated.", resolver.ACME.DNSChallenge.Provider)
|
||||
case "dnspod":
|
||||
log.WithoutContext().Warnf("%s provider is deprecated, please use 'tencentcloud' provider instead.", resolver.ACME.DNSChallenge.Provider)
|
||||
case "azure":
|
||||
log.WithoutContext().Warnf("%s provider is deprecated, please use 'azuredns' provider instead.", resolver.ACME.DNSChallenge.Provider)
|
||||
}
|
||||
}
|
||||
|
||||
c.initACMEProvider()
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ func TestSetBackendsConfiguration(t *testing.T) {
|
||||
|
||||
// The context is passed to the health check and canonically canceled by
|
||||
// the test server once all expected requests have been received.
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
ts := newTestServer(cancel, test.healthSequence)
|
||||
defer ts.Close()
|
||||
@@ -568,7 +568,7 @@ func TestNotFollowingRedirects(t *testing.T) {
|
||||
}))
|
||||
defer redirectTestServer.Close()
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
ctx, cancel := context.WithCancel(t.Context())
|
||||
defer cancel()
|
||||
|
||||
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
|
||||
|
||||
@@ -2,7 +2,6 @@ package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@@ -42,7 +41,7 @@ func TestLog(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
SetOutput(&buffer)
|
||||
|
||||
ctx := context.Background()
|
||||
ctx := t.Context()
|
||||
|
||||
for key, value := range test.fields {
|
||||
ctx = With(ctx, Str(key, value))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -17,7 +16,7 @@ func TestDatadog(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
datadogRegistry := RegisterDatadog(t.Context(), &types.Datadog{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
defer StopDatadog()
|
||||
|
||||
if !datadogRegistry.IsEpEnabled() || !datadogRegistry.IsRouterEnabled() || !datadogRegistry.IsSvcEnabled() {
|
||||
@@ -35,7 +34,7 @@ func TestDatadogWithPrefix(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
datadogRegistry := RegisterDatadog(context.Background(), &types.Datadog{Prefix: "testPrefix", Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
datadogRegistry := RegisterDatadog(t.Context(), &types.Datadog{Prefix: "testPrefix", Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
|
||||
testDatadogRegistry(t, "testPrefix", datadogRegistry)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -27,7 +26,7 @@ func TestInfluxDB2(t *testing.T) {
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
influxDB2Registry := RegisterInfluxDB2(context.Background(),
|
||||
influxDB2Registry := RegisterInfluxDB2(t.Context(),
|
||||
&types.InfluxDB2{
|
||||
Address: ts.URL,
|
||||
Token: "test-token",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -23,7 +22,7 @@ func TestInfluxDB(t *testing.T) {
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
influxDBClient = nil
|
||||
influxDBRegistry := RegisterInfluxDB(context.Background(),
|
||||
influxDBRegistry := RegisterInfluxDB(t.Context(),
|
||||
&types.InfluxDB{
|
||||
Address: ":8089",
|
||||
PushInterval: ptypes.Duration(time.Second),
|
||||
@@ -147,7 +146,7 @@ func TestInfluxDBHTTP(t *testing.T) {
|
||||
defer ts.Close()
|
||||
|
||||
influxDBClient = nil
|
||||
influxDBRegistry := RegisterInfluxDB(context.Background(),
|
||||
influxDBRegistry := RegisterInfluxDB(t.Context(),
|
||||
&types.InfluxDB{
|
||||
Address: ts.URL,
|
||||
Protocol: "http",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
@@ -70,7 +69,7 @@ func TestRegisterPromState(t *testing.T) {
|
||||
if test.initPromState {
|
||||
initStandardRegistry(prom)
|
||||
}
|
||||
if registerPromState(context.Background()) {
|
||||
if registerPromState(t.Context()) {
|
||||
actualNbRegistries++
|
||||
}
|
||||
if test.unregisterPromState {
|
||||
@@ -91,7 +90,7 @@ func TestPrometheus(t *testing.T) {
|
||||
promRegistry = prometheus.NewRegistry()
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{
|
||||
AddEntryPointsLabels: true,
|
||||
AddRoutersLabels: true,
|
||||
AddServicesLabels: true,
|
||||
@@ -443,7 +442,7 @@ func TestPrometheusMetricRemoval(t *testing.T) {
|
||||
promRegistry = prometheus.NewRegistry()
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true, AddRoutersLabels: true})
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true, AddRoutersLabels: true})
|
||||
defer promRegistry.Unregister(promState)
|
||||
|
||||
conf1 := dynamic.Configuration{
|
||||
@@ -534,7 +533,7 @@ func TestPrometheusMetricRemoveEndpointForRecoveredService(t *testing.T) {
|
||||
promRegistry = prometheus.NewRegistry()
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddServicesLabels: true})
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{AddServicesLabels: true})
|
||||
defer promRegistry.Unregister(promState)
|
||||
|
||||
conf1 := dynamic.Configuration{
|
||||
@@ -573,7 +572,7 @@ func TestPrometheusMetricRemoveEndpointForRecoveredService(t *testing.T) {
|
||||
func TestPrometheusRemovedMetricsReset(t *testing.T) {
|
||||
t.Cleanup(promState.reset)
|
||||
|
||||
prometheusRegistry := RegisterPrometheus(context.Background(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true})
|
||||
prometheusRegistry := RegisterPrometheus(t.Context(), &types.Prometheus{AddEntryPointsLabels: true, AddServicesLabels: true})
|
||||
defer promRegistry.Unregister(promState)
|
||||
|
||||
conf1 := dynamic.Configuration{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"testing"
|
||||
@@ -21,7 +20,7 @@ func TestStatsD(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
statsdRegistry := RegisterStatsd(t.Context(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true})
|
||||
|
||||
testRegistry(t, defaultMetricsPrefix, statsdRegistry)
|
||||
}
|
||||
@@ -35,7 +34,7 @@ func TestStatsDWithPrefix(t *testing.T) {
|
||||
// This is needed to make sure that UDP Listener listens for data a bit longer, otherwise it will quit after a millisecond
|
||||
udp.Timeout = 5 * time.Second
|
||||
|
||||
statsdRegistry := RegisterStatsd(context.Background(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true, Prefix: "testPrefix"})
|
||||
statsdRegistry := RegisterStatsd(t.Context(), &types.Statsd{Address: ":18125", PushInterval: ptypes.Duration(time.Second), AddEntryPointsLabels: true, AddRoutersLabels: true, AddServicesLabels: true, Prefix: "testPrefix"})
|
||||
|
||||
testRegistry(t, "testPrefix", statsdRegistry)
|
||||
}
|
||||
|
||||
@@ -364,9 +364,10 @@ func (h *Handler) logTheRoundTrip(logDataTable *LogData) {
|
||||
func (h *Handler) redactHeaders(headers http.Header, fields logrus.Fields, prefix string) {
|
||||
for k := range headers {
|
||||
v := h.config.Fields.KeepHeader(k)
|
||||
if v == types.AccessLogKeep {
|
||||
switch v {
|
||||
case types.AccessLogKeep:
|
||||
fields[prefix+k] = strings.Join(headers.Values(k), ",")
|
||||
} else if v == types.AccessLogRedact {
|
||||
case types.AccessLogRedact:
|
||||
fields[prefix+k] = "REDACTED"
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user