1
0
mirror of https://github.com/containous/traefik.git synced 2026-01-13 08:32:50 +03:00

Compare commits

...

37 Commits

Author SHA1 Message Date
Dave
93f7cb1082 Added CertificateTimeout ACME configuration option. 2026-01-12 16:58:05 +01:00
mmatur
df50421b53 Merge current v3.6 into master 2026-01-09 20:45:30 +01:00
mmatur
dc04dc1940 Merge current v2.11 into v3.6 2026-01-09 19:41:31 +01:00
Romain
26f4a669b8 Prevent Ingress Nginx provider http router to attach to an entrypoint with TLS
Co-authored-by: Gina A. <70909035+gndz07@users.noreply.github.com>
2026-01-09 17:38:05 +01:00
Michel Loiseleur
e8067f4e01 Refactor CI on documentation 2026-01-09 17:24:04 +01:00
LBF38
1881434ac6 Fix use-regex nginx annotation
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2026-01-09 17:18:05 +01:00
Anurag Ekkati
862488569d Fix code copy button positioning 2026-01-09 16:56:04 +01:00
Michael
2b710f05b3 Fix Kubernetes reference yml file 2026-01-09 10:12:04 +01:00
Andreas Schildbach
c7487c4a69 Replace hardcoded references to LetsEncrypt in log messages 2026-01-09 09:36:04 +01:00
NEwa
12d792cdef Add the option to define custom cipher suites for backend serversTransport 2026-01-08 18:22:04 +01:00
LBF38
e9f3089e90 Add timeout to ACME-TLS/1 challenge handshake
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2026-01-08 16:16:05 +01:00
DBouraoui
7e703742cb Update swarm.md traefik version 2026-01-08 15:24:04 +01:00
LBF38
4de6d6b902 Validate X-Forwarded-Prefix value for dashboard redirect
Co-authored-by: Kevin Pollet <pollet.kevin@gmail.com>
2026-01-08 14:26:04 +01:00
Gina A.
1778ff3bac Bring back security section on API & Dashboard documentation page 2026-01-08 10:24:04 +01:00
Ed Salkeld
7e1654ae27 Fix typo in kubernetes.md 2026-01-07 14:10:04 +01:00
Gina A.
5d00096f82 Fix panic for empty defaultBackend and defaultBackend without resources 2026-01-07 09:38:05 +01:00
Nicolas Mengin
be27044099 Fix ingress-nginx annotations documenation 2026-01-06 17:46:04 +01:00
Sheddy
dbebe5fa3e Add product comparison matrix and features page 2026-01-06 16:46:05 +01:00
Christian Schärf
413b7c8cca Fix link description in Traefik Proxy documentation 2026-01-05 16:14:04 +01:00
Ludovic Fernandez
3b6949c18c fix(acme): add missing renew options 2026-01-05 14:50:05 +01:00
Jesper Noordsij
66bf4632e2 Remove unused empty code-gen-docker.sh script 2026-01-05 14:34:05 +01:00
Michael
1de72c715d Fix flaky tests on hrw 2026-01-02 10:56:04 +01:00
mmatur
f7280439e6 Merge current v3.6' into master 2026-01-02 10:35:20 +01:00
mmatur
cabcf19303 Merge current v2.11 into v3.6 2026-01-02 10:05:07 +01:00
Michael
47d7094dfb Welcome 2026 2026-01-02 09:58:04 +01:00
mmatur
0e360966a0 Merge current v3.6 into master 2025-12-29 16:43:41 +01:00
Gina A.
6af404b9da Add dashboard name configuration 2025-12-23 15:58:04 +01:00
kevinpollet
50c254a522 Merge branch v3.6 into master 2025-12-23 14:45:38 +01:00
luo jiyin
a16c2326b3 Optimize GitHub Actions workflows 2025-12-22 15:30:05 +01:00
Nándor Kollár
b4abd8dc2c Support NGINX custom-headers annotation 2025-12-22 10:44:08 +01:00
blasko03
f71b941995 Support NGINX whitelist-source-range annotation 2025-12-22 09:52:04 +01:00
Landry Benguigui
78e2dab155 feat: add global option to disable X-Forwarded-For appending 2025-12-19 11:18:04 +01:00
Nándor Kollár
704f69272c Support Nginx upstream-vhost annotation 2025-12-17 16:42:04 +01:00
Gina A.
4854dee208 Details pages UI improvement 2025-12-16 16:30:05 +01:00
mmatur
34b91218f4 Merge v3.6 into master 2025-12-01 16:28:00 +01:00
Gina A.
8bdcd72042 Web UI dashboard improvements 2025-11-21 09:00:05 +01:00
kevinpollet
2ad42cd0ec Merge branch v3.6 into master 2025-11-07 16:47:21 +01:00
250 changed files with 5514 additions and 3153 deletions

View File

@@ -20,6 +20,7 @@ jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
matrix:
@@ -51,12 +52,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
env:
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
with:
@@ -64,7 +65,7 @@ jobs:
check-latest: true
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: webui.tar.gz

63
.github/workflows/check_doc.yaml vendored Normal file
View File

@@ -0,0 +1,63 @@
name: Check Documentation
on:
pull_request:
branches:
- '*'
paths:
- '.github/workflows/check_doc.yaml'
- 'docs/**'
jobs:
docs:
name: lint, build and verify
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Install markdownlint
run: |
npm install --global markdownlint@0.29.0 markdownlint-cli@0.35.0
- name: Lint
run: ./docs/scripts/lint.sh docs
- name: Setup python
uses: actions/setup-python@v6
with:
python-version: '3.12'
cache: 'pip'
cache-dependency-path: "./docs/requirements.txt"
- name: Build documentation
working-directory: ./docs
run: |
pip install -r requirements.txt
mkdocs build --strict
- name: Setup ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
- name: Install html-proofer
run: |
gem install nokogiri --version 1.18.6 --no-document -- --use-system-libraries
gem install html-proofer --version 5.0.10 --no-document -- --use-system-libraries
env:
NOKOGIRI_USE_SYSTEM_LIBRARIES: "true"
# Comes from https://github.com/gjtorikian/html-proofer?tab=readme-ov-file#caching-with-continuous-integration
- name: Cache HTMLProofer
uses: actions/cache@v4
with:
path: tmp/.htmlproofer
key: ${{ runner.os }}-htmlproofer
- name: Verify
run: ./docs/scripts/verify.sh docs/site

View File

@@ -1,25 +0,0 @@
name: Check Documentation
on:
pull_request:
branches:
- '*'
jobs:
docs:
name: Check, verify and build documentation
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Check documentation
run: make docs-pull-images docs
env:
# These variables are not passed to workflows that are triggered by a pull request from a fork.
DOCS_VERIFY_SKIP: ${{ vars.DOCS_VERIFY_SKIP }}
DOCS_LINT_SKIP: ${{ vars.DOCS_LINT_SKIP }}

View File

@@ -12,6 +12,7 @@ jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
actions: read
contents: read
@@ -28,10 +29,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
uses: actions/checkout@v6
- name: setup go
uses: actions/setup-go@v5
uses: actions/setup-go@v6
if: ${{ matrix.language == 'go' }}
with:
go-version-file: 'go.mod'

View File

@@ -16,11 +16,12 @@ jobs:
docs:
name: Doc Process
runs-on: ubuntu-latest
timeout-minutes: 15
if: github.repository == 'traefik/traefik'
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0

View File

@@ -20,15 +20,16 @@ jobs:
if: github.repository == 'traefik/traefik'
name: Build experimental image on branch
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
env:
ImageOS: ${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.goarm }}
with:
@@ -54,7 +55,7 @@ jobs:
uses: docker/setup-buildx-action@v3
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: webui.tar.gz

View File

@@ -21,6 +21,7 @@ jobs:
build:
if: github.ref_type == 'tag' && github.repository == 'traefik/traefik'
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
matrix:
@@ -30,12 +31,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
env:
# Ensure cache consistency on Linux, see https://github.com/actions/setup-go/pull/383
ImageOS: ${{ matrix.os }}
@@ -44,7 +45,7 @@ jobs:
check-latest: true
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: webui.tar.gz
@@ -83,18 +84,19 @@ jobs:
release:
if: github.ref_type == 'tag' && github.repository == 'traefik/traefik'
runs-on: ubuntu-latest
timeout-minutes: 45
needs:
- build
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Artifact webui
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: webui.tar.gz
@@ -111,7 +113,7 @@ jobs:
echo "${TRAEFIKER_RSA}" | base64 --decode > ~/.ssh/traefiker_rsa
- name: Download All Artifacts
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
path: dist/
pattern: "*-binaries"
@@ -133,4 +135,3 @@ jobs:
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

View File

@@ -8,13 +8,14 @@ on:
jobs:
sync:
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
packages: write
contents: read
if: github.repository == 'traefik/traefik'
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- uses: imjasonh/setup-crane@v0.4

View File

@@ -7,10 +7,11 @@ jobs:
build-webui:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
@@ -18,7 +19,7 @@ jobs:
run: corepack enable
- name: Setup node
uses: actions/setup-node@v4
uses: actions/setup-node@v6
with:
node-version-file: webui/.nvmrc
cache: yarn
@@ -41,7 +42,7 @@ jobs:
tar czvf webui.tar.gz ./webui/static/
- name: Artifact webui
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@v6
with:
name: webui.tar.gz
path: webui.tar.gz

View File

@@ -19,15 +19,16 @@ jobs:
test-gateway-api-conformance:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}

View File

@@ -17,15 +17,16 @@ jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@@ -53,6 +54,7 @@ jobs:
test-integration:
runs-on: ubuntu-latest
timeout-minutes: 90
needs:
- build
strategy:
@@ -63,18 +65,18 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
- name: Download traefik binary
uses: actions/download-artifact@v4
uses: actions/download-artifact@v7
with:
name: traefik
path: ./dist/linux/amd64/

View File

@@ -19,15 +19,16 @@ jobs:
test-knative-conformance:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}

View File

@@ -16,16 +16,17 @@ jobs:
generate-packages:
name: List Go Packages
runs-on: ubuntu-latest
timeout-minutes: 15
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@@ -39,6 +40,7 @@ jobs:
test-unit:
runs-on: ubuntu-latest
timeout-minutes: 15
needs: generate-packages
strategy:
matrix:
@@ -46,12 +48,12 @@ jobs:
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@@ -62,10 +64,11 @@ jobs:
test-ui-unit:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0

View File

@@ -8,21 +8,22 @@ on:
env:
GO_VERSION: '1.24'
GOLANGCI_LINT_VERSION: v2.0.2
MISSPELL_VERSION: v0.6.0
MISSPELL_VERSION: v0.7.0
jobs:
lint:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@@ -34,15 +35,16 @@ jobs:
validate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true
@@ -55,15 +57,16 @@ jobs:
validate-generate:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Check out code
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Set up Go ${{ env.GO_VERSION }}
uses: actions/setup-go@v5
uses: actions/setup-go@v6
with:
go-version: ${{ env.GO_VERSION }}
check-latest: true

View File

@@ -231,6 +231,7 @@ func setupServer(staticConfiguration *static.Configuration) (*server.Server, err
if staticConfiguration.API != nil {
version.DisableDashboardAd = staticConfiguration.API.DisableDashboardAd
version.DashboardName = staticConfiguration.API.DashboardName
}
// Plugins

View File

@@ -34,6 +34,7 @@ RUN apk --no-cache --no-progress add \
COPY ./scripts/verify.sh /verify.sh
COPY ./scripts/lint.sh /lint.sh
COPY ./scripts/lint-yaml.sh /lint-yaml.sh
WORKDIR /app
VOLUME ["/tmp","/app"]

View File

@@ -0,0 +1,18 @@
/* Fix positioning of the built-in clipboard button for code blocks.
* In this theme, the button can end up positioned relative to <body>,
* so anchor it to the code block container instead.
*/
.md-typeset pre.highlight {
position: relative;
}
.md-typeset pre.highlight > button.md-clipboard {
position: absolute;
top: .25rem;
right: .25rem;
z-index: 10;
opacity: 1;
visibility: visible;
}

View File

@@ -0,0 +1,148 @@
---
title: "Traefik Product Features Comparison"
description: "Compare features across Traefik Proxy, Traefik Hub API Gateway (including AI Gateway capabilities), and Traefik Hub API Management to choose the right solution for your needs."
---
# Traefik Product Features Comparison
The Traefik ecosystem offers multiple products designed to meet different requirements, from basic reverse proxy functionality to comprehensive API management and AI gateway capabilities. This comparison matrix helps you understand the features available in each product and choose the right solution for your use case.
## Product Overview
- **Traefik Proxy** is the open-source application proxy that serves as the foundation for all Traefik products. It provides essential reverse proxy, load balancing, and service discovery capabilities.
- **[Traefik Hub API Gateway](https://traefik.io/solutions/api-gateway/)** builds on Traefik Proxy with enterprise-grade security, distributed features, and advanced access control for cloud-native API gateway scenarios. It includes **AI Gateway capabilities** that transform any AI endpoint into a managed API.
- **[Traefik Hub API Management](https://traefik.io/solutions/api-management/)** adds comprehensive API lifecycle management, developer portals, and organizational features for teams managing multiple APIs across environments.
- **[Traefik AI Gateway](https://traefik.io/solutions/ai-gateway/)** transforms any AI endpoint into a managed API with unified access to multiple LLMs, centralized credential management, semantic caching, local inferencing, and comprehensive AI governance features.
- **[Traefik MCP Gateway](https://traefik.io/solutions/mcp-gateway/)** provides secure, governed access to Model Context Protocol (MCP) servers for AI agents with task-based access control (TBAC), session-smart routing, and comprehensive audit capabilities for enterprise AI workflows.
## Features Matrix
| Feature | Traefik Proxy | Traefik Hub API Gateway | Traefik Hub API Management |
|---------|---------------|------------------------|---------------------------|
| **Core Networking** | | | |
| Services Auto-Discovery | ✓ | ✓ | ✓ |
| Graceful Configuration Reload | ✓ | ✓ | ✓ |
| Websockets, HTTP/2, HTTP/3, TCP, UDP, GRPC | ✓ | ✓ | ✓ |
| Real-time Logs, Access Logs, Metrics & Distributed Tracing | ✓ | ✓ | ✓ |
| Canary Deployments | ✓ | ✓ | ✓ |
| Let's Encrypt | ✓ | ✓ | ✓ |
| **Plugin Ecosystem** | | | |
| [Plugin Support](https://plugins.traefik.io/plugins) ([Go](https://github.com/traefik/yaegi), [WASM](https://webassembly.org/)) | ✓ | ✓ | ✓ |
| **Deployment & Operations** | | | |
| Hybrid cloud, multi-cloud & on-prem compatible | ✓ | ✓ | ✓ |
| Per-cluster dashboard | ✓ | ✓ | ✓ |
| GitOps-native declarative configuration | ✓ | ✓ | ✓ |
| **Authentication & Authorization** | | | |
| JWT Authentication | ✗ | ✓ | ✓ |
| OAuth 2.0 Token Introspection Authentication | ✗ | ✓ | ✓ |
| OAuth 2.0 Client Credentials Authentication | ✗ | ✓ | ✓ |
| OpenID Connect Authentication | ✗ | ✓ | ✓ |
| Lightweight Directory Access Protocol (LDAP) | ✗ | ✓ | ✓ |
| API Key Authentication | ✗ | ✓ | ✓ |
| **Security & Policy** | | | |
| Open Policy Agent | ✗ | ✓ | ✓ |
| Native Coraza Web Application Firewall (WAF) | ✗ | ✓ | ✓ |
| HashiCorp Vault Integration | ✗ | ✓ | ✓ |
| **Distributed Features** | | | |
| Distributed Let's Encrypt | ✗ | ✓ | ✓ |
| Distributed Rate Limit | ✗ | ✓ | ✓ |
| HTTP Caching | ✗ | ✓ | ✓ |
| **Compliance** | | | |
| FIPS 140-2 Compliance (Linux & Windows) | ✗ | ✓ | ✓ |
| **AI Gateway Capabilities** | | | |
| Unified Multi-LLM API Access | ✗ | ✓ | ✓ |
| Centralized AI Credential Management | ✗ | ✓ | ✓ |
| AI Provider Flexibility (OpenAI, Anthropic, Azure OpenAI, AWS Bedrock, etc.) | ✗ | ✓ | ✓ |
| Semantic Caching for AI Responses | ✗ | ✓ | ✓ |
| Content Guard & PII Protection | ✗ | ✓ | ✓ |
| AI-specific Observability & OpenTelemetry Integration | ✗ | ✓ | ✓ |
| Support for Local/Self-hosted LLMs & Inference (Ollama, Mistral, etc.) | ✗ | ✓ | ✓ |
| **MCP Gateway Capabilities** | | | |
| Task-Based Access Control (TBAC) for AI Agents | ✗ | ✓ | ✓ |
| MCP Servers Governance | ✗ | ✓ | ✓ |
| Session-Smart Load Balancing for Agent Workflows | ✗ | ✓ | ✓ |
| OAuth 2.1 / 2.0 Resource Server for MCP | ✗ | ✓ | ✓ |
| Fine-grained Policy Enforcement for AI Tools | ✗ | ✓ | ✓ |
| Audit-ready Observability for Agent Interactions | ✗ | ✓ | ✓ |
| **API Management** | | | |
| Flexible API grouping and versioning | ✗ | ✗ | ✓ |
| API Developer Portal | ✗ | ✗ | ✓ |
| OpenAPI Specifications Support | ✗ | ✗ | ✓ |
| Multi-cluster dashboard | ✗ | ✗ | ✓ |
| Built-in identity provider (or use your own) | ✗ | ✗ | ✓ |
| Configuration linter & change impact analysis | ✗ | ✗ | ✓ |
| Pre-built Grafana dashboards | ✗ | ✗ | ✓ |
| Event correlation for quick incident mitigation | ✗ | ✗ | ✓ |
| Traffic debugger | ✗ | ✓ | ✓ |
| **Support** | | | |
| Built-In Commercial Support | Add-on | ✓ | ✓ |
## Choosing the Right Product
### Start with Traefik Proxy
Traefik Proxy is the ideal starting point for organizations looking for a reliable, open-source application proxy with essential networking capabilities. Deploy it as your default ingress tier if you need:
- Basic reverse proxy and load balancing
- Service discovery for containerized applications
- Simple TLS termination and Let's Encrypt integration
- Cost-effective solution with community support (can upgrade to Traefik Hub for more features)
### Upgrade to Traefik Hub API Gateway
Traefik Hub API Gateway layers enterprise security, distributed coordination, and AI Gateway capabilities on top of Traefik Proxy. Upgrade to it when you need:
- Enterprise security requirements (JWT, OIDC, LDAP)
- Distributed deployments across multiple clusters
- Advanced rate limiting and caching
- WAF and policy enforcement
- AI Gateway capabilities
- Commercial support
### Consider Traefik AI Gateway
Traefik AI Gateway unifies hosted and self-hosted LLM access under centralized control and observability. Consider it if you have:
- Multi-LLM applications requiring unified API access
- Organizations using multiple AI providers (OpenAI, Anthropic, Azure OpenAI, AWS Bedrock, etc.)
- Local/self-hosted LLM deployments (Ollama, Mistral)
- Centralized AI credential and security management
- Cost optimization through semantic caching
- PII protection and content filtering for AI interactions
- Comprehensive AI observability and compliance requirements
### Choose Traefik MCP Gateway
Traefik MCP Gateway governs how AI agents interact with Model Context Protocol servers through task-aware policies and session-smart routing. Choose it if you need:
- AI agent deployments requiring secure access to MCP servers
- Task-based access control (TBAC) for AI workflows
- Governance of Model Context Protocol interactions
- Session-smart routing for long-running agent conversations
- OAuth 2.1 / 2.0 compliant MCP server protection
- Audit-ready observability for AI agent activities
- Fine-grained policy enforcement for AI tools and resources
### Choose Traefik Hub API Management
Traefik Hub API Management extends the gateway foundation with API lifecycle tooling, developer experience features, and governance workflows. Choose it when you have:
- Multiple APIs requiring centralized management
- Developer teams needing self-service portals
- Complex API versioning and lifecycle requirements
- Multi-cluster environments requiring unified dashboards
- Compliance and governance needs
## Migration Path
The Traefik ecosystem is designed for seamless upgrades. You can start with Traefik Proxy and add capabilities as your requirements grow:
1. **Traefik Proxy****Hub API Gateway**: Add enterprise security, distributed features, and AI Gateway capabilities
2. **Hub API Gateway****Hub API Management**: Add comprehensive API management and governance features
3. **MCP Gateway**: Specialized solution for AI agent governance and Model Context Protocol management
All products share the same core configuration concepts, making migration straightforward while preserving your existing configurations and operational knowledge.

View File

@@ -11,6 +11,8 @@ Traefik is an [open-source](https://github.com/traefik/traefik) Application Prox
If you start with Traefik for service discovery and routing, you can seamlessly add [API management](https://traefik.io/solutions/api-management/), [API gateway](https://traefik.io/solutions/api-gateway/), [AI gateway](https://traefik.io/solutions/ai-gateway/), and [API mocking](https://traefik.io/solutions/api-mocking/) capabilities as needed.
For a detailed comparison of all Traefik products and their capabilities, see our [Product Features Comparison](./features/).
With 3.3 billion downloads and over 55k stars on GitHub, Traefik is used globally across hybrid cloud, multi-cloud, on prem, and bare metal environments running Kubernetes, Docker Swarm, AWS, [the list goes on](https://doc.traefik.io/traefik/reference/install-configuration/providers/overview/).
Heres how it works—Traefik receives requests on behalf of your system, identifies which components are responsible for handling them, and routes them securely. It automatically discovers the right configuration for your services by inspecting your infrastructure to identify relevant information and which service serves which request.

View File

@@ -378,6 +378,9 @@
serverName = "foobar"
insecureSkipVerify = true
rootCAs = ["foobar", "foobar"]
cipherSuites = ["foobar", "foobar"]
minVersion = "foobar"
maxVersion = "foobar"
maxIdleConnsPerHost = 42
disableHTTP2 = true
peerCertURI = "foobar"
@@ -402,6 +405,9 @@
serverName = "foobar"
insecureSkipVerify = true
rootCAs = ["foobar", "foobar"]
cipherSuites = ["foobar", "foobar"]
minVersion = "foobar"
maxVersion = "foobar"
maxIdleConnsPerHost = 42
disableHTTP2 = true
peerCertURI = "foobar"

View File

@@ -437,6 +437,11 @@ http:
keyFile: foobar
- certFile: foobar
keyFile: foobar
cipherSuites:
- foobar
- foobar
minVersion: foobar
maxVersion: foobar
maxIdleConnsPerHost: 42
forwardingTimeouts:
dialTimeout: 42s
@@ -462,6 +467,11 @@ http:
keyFile: foobar
- certFile: foobar
keyFile: foobar
cipherSuites:
- foobar
- foobar
minVersion: foobar
maxVersion: foobar
maxIdleConnsPerHost: 42
forwardingTimeouts:
dialTimeout: 42s

View File

@@ -1,4 +1,3 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
@@ -2281,6 +2280,12 @@ spec:
items:
type: string
type: array
cipherSuites:
description: CipherSuites defines the cipher suites to use when contacting
backend servers.
items:
type: string
type: array
disableHTTP2:
description: DisableHTTP2 disables HTTP/2 for connections with backend
servers.
@@ -2341,6 +2346,14 @@ spec:
to keep per-host.
minimum: -1
type: integer
maxVersion:
description: MaxVersion defines the maximum TLS version to use when
contacting backend servers.
type: string
minVersion:
description: MinVersion defines the minimum TLS version to use when
contacting backend servers.
type: string
peerCertURI:
description: PeerCertURI defines the peer cert URI used to match against
SAN URI during the peer certificate verification.

View File

@@ -1,4 +1,3 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:

View File

@@ -1,4 +1,3 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:

View File

@@ -1,4 +1,3 @@
---
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:

View File

@@ -1,4 +1,3 @@
---
apiVersion: v1
kind: ServiceAccount
metadata:

View File

@@ -1,4 +1,3 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:

View File

@@ -1,4 +1,3 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:

View File

@@ -1,4 +1,3 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:

View File

@@ -237,6 +237,8 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-traefikhttpserversTransportsServersTransport0certificates0keyFile" href="#opt-traefikhttpserversTransportsServersTransport0certificates0keyFile" title="#opt-traefikhttpserversTransportsServersTransport0certificates0keyFile">`traefik/http/serversTransports/ServersTransport0/certificates/0/keyFile`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0certificates1certFile" href="#opt-traefikhttpserversTransportsServersTransport0certificates1certFile" title="#opt-traefikhttpserversTransportsServersTransport0certificates1certFile">`traefik/http/serversTransports/ServersTransport0/certificates/1/certFile`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0certificates1keyFile" href="#opt-traefikhttpserversTransportsServersTransport0certificates1keyFile" title="#opt-traefikhttpserversTransportsServersTransport0certificates1keyFile">`traefik/http/serversTransports/ServersTransport0/certificates/1/keyFile`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0cipherSuites0" href="#opt-traefikhttpserversTransportsServersTransport0cipherSuites0" title="#opt-traefikhttpserversTransportsServersTransport0cipherSuites0">`traefik/http/serversTransports/ServersTransport0/cipherSuites/0`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0cipherSuites1" href="#opt-traefikhttpserversTransportsServersTransport0cipherSuites1" title="#opt-traefikhttpserversTransportsServersTransport0cipherSuites1">`traefik/http/serversTransports/ServersTransport0/cipherSuites/1`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0disableHTTP2" href="#opt-traefikhttpserversTransportsServersTransport0disableHTTP2" title="#opt-traefikhttpserversTransportsServersTransport0disableHTTP2">`traefik/http/serversTransports/ServersTransport0/disableHTTP2`</a> | `true` |
| <a id="opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsdialTimeout" href="#opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsdialTimeout" title="#opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsdialTimeout">`traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/dialTimeout`</a> | `42s` |
| <a id="opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsidleConnTimeout" href="#opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsidleConnTimeout" title="#opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsidleConnTimeout">`traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/idleConnTimeout`</a> | `42s` |
@@ -245,6 +247,8 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsresponseHeaderTimeout" href="#opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsresponseHeaderTimeout" title="#opt-traefikhttpserversTransportsServersTransport0forwardingTimeoutsresponseHeaderTimeout">`traefik/http/serversTransports/ServersTransport0/forwardingTimeouts/responseHeaderTimeout`</a> | `42s` |
| <a id="opt-traefikhttpserversTransportsServersTransport0insecureSkipVerify" href="#opt-traefikhttpserversTransportsServersTransport0insecureSkipVerify" title="#opt-traefikhttpserversTransportsServersTransport0insecureSkipVerify">`traefik/http/serversTransports/ServersTransport0/insecureSkipVerify`</a> | `true` |
| <a id="opt-traefikhttpserversTransportsServersTransport0maxIdleConnsPerHost" href="#opt-traefikhttpserversTransportsServersTransport0maxIdleConnsPerHost" title="#opt-traefikhttpserversTransportsServersTransport0maxIdleConnsPerHost">`traefik/http/serversTransports/ServersTransport0/maxIdleConnsPerHost`</a> | `42` |
| <a id="opt-traefikhttpserversTransportsServersTransport0maxVersion" href="#opt-traefikhttpserversTransportsServersTransport0maxVersion" title="#opt-traefikhttpserversTransportsServersTransport0maxVersion">`traefik/http/serversTransports/ServersTransport0/maxVersion`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0minVersion" href="#opt-traefikhttpserversTransportsServersTransport0minVersion" title="#opt-traefikhttpserversTransportsServersTransport0minVersion">`traefik/http/serversTransports/ServersTransport0/minVersion`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0peerCertURI" href="#opt-traefikhttpserversTransportsServersTransport0peerCertURI" title="#opt-traefikhttpserversTransportsServersTransport0peerCertURI">`traefik/http/serversTransports/ServersTransport0/peerCertURI`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0rootCAs0" href="#opt-traefikhttpserversTransportsServersTransport0rootCAs0" title="#opt-traefikhttpserversTransportsServersTransport0rootCAs0">`traefik/http/serversTransports/ServersTransport0/rootCAs/0`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport0rootCAs1" href="#opt-traefikhttpserversTransportsServersTransport0rootCAs1" title="#opt-traefikhttpserversTransportsServersTransport0rootCAs1">`traefik/http/serversTransports/ServersTransport0/rootCAs/1`</a> | `foobar` |
@@ -256,6 +260,8 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-traefikhttpserversTransportsServersTransport1certificates0keyFile" href="#opt-traefikhttpserversTransportsServersTransport1certificates0keyFile" title="#opt-traefikhttpserversTransportsServersTransport1certificates0keyFile">`traefik/http/serversTransports/ServersTransport1/certificates/0/keyFile`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1certificates1certFile" href="#opt-traefikhttpserversTransportsServersTransport1certificates1certFile" title="#opt-traefikhttpserversTransportsServersTransport1certificates1certFile">`traefik/http/serversTransports/ServersTransport1/certificates/1/certFile`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1certificates1keyFile" href="#opt-traefikhttpserversTransportsServersTransport1certificates1keyFile" title="#opt-traefikhttpserversTransportsServersTransport1certificates1keyFile">`traefik/http/serversTransports/ServersTransport1/certificates/1/keyFile`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1cipherSuites0" href="#opt-traefikhttpserversTransportsServersTransport1cipherSuites0" title="#opt-traefikhttpserversTransportsServersTransport1cipherSuites0">`traefik/http/serversTransports/ServersTransport1/cipherSuites/0`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1cipherSuites1" href="#opt-traefikhttpserversTransportsServersTransport1cipherSuites1" title="#opt-traefikhttpserversTransportsServersTransport1cipherSuites1">`traefik/http/serversTransports/ServersTransport1/cipherSuites/1`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1disableHTTP2" href="#opt-traefikhttpserversTransportsServersTransport1disableHTTP2" title="#opt-traefikhttpserversTransportsServersTransport1disableHTTP2">`traefik/http/serversTransports/ServersTransport1/disableHTTP2`</a> | `true` |
| <a id="opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsdialTimeout" href="#opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsdialTimeout" title="#opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsdialTimeout">`traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/dialTimeout`</a> | `42s` |
| <a id="opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsidleConnTimeout" href="#opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsidleConnTimeout" title="#opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsidleConnTimeout">`traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/idleConnTimeout`</a> | `42s` |
@@ -264,6 +270,8 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsresponseHeaderTimeout" href="#opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsresponseHeaderTimeout" title="#opt-traefikhttpserversTransportsServersTransport1forwardingTimeoutsresponseHeaderTimeout">`traefik/http/serversTransports/ServersTransport1/forwardingTimeouts/responseHeaderTimeout`</a> | `42s` |
| <a id="opt-traefikhttpserversTransportsServersTransport1insecureSkipVerify" href="#opt-traefikhttpserversTransportsServersTransport1insecureSkipVerify" title="#opt-traefikhttpserversTransportsServersTransport1insecureSkipVerify">`traefik/http/serversTransports/ServersTransport1/insecureSkipVerify`</a> | `true` |
| <a id="opt-traefikhttpserversTransportsServersTransport1maxIdleConnsPerHost" href="#opt-traefikhttpserversTransportsServersTransport1maxIdleConnsPerHost" title="#opt-traefikhttpserversTransportsServersTransport1maxIdleConnsPerHost">`traefik/http/serversTransports/ServersTransport1/maxIdleConnsPerHost`</a> | `42` |
| <a id="opt-traefikhttpserversTransportsServersTransport1maxVersion" href="#opt-traefikhttpserversTransportsServersTransport1maxVersion" title="#opt-traefikhttpserversTransportsServersTransport1maxVersion">`traefik/http/serversTransports/ServersTransport1/maxVersion`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1minVersion" href="#opt-traefikhttpserversTransportsServersTransport1minVersion" title="#opt-traefikhttpserversTransportsServersTransport1minVersion">`traefik/http/serversTransports/ServersTransport1/minVersion`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1peerCertURI" href="#opt-traefikhttpserversTransportsServersTransport1peerCertURI" title="#opt-traefikhttpserversTransportsServersTransport1peerCertURI">`traefik/http/serversTransports/ServersTransport1/peerCertURI`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1rootCAs0" href="#opt-traefikhttpserversTransportsServersTransport1rootCAs0" title="#opt-traefikhttpserversTransportsServersTransport1rootCAs0">`traefik/http/serversTransports/ServersTransport1/rootCAs/0`</a> | `foobar` |
| <a id="opt-traefikhttpserversTransportsServersTransport1rootCAs1" href="#opt-traefikhttpserversTransportsServersTransport1rootCAs1" title="#opt-traefikhttpserversTransportsServersTransport1rootCAs1">`traefik/http/serversTransports/ServersTransport1/rootCAs/1`</a> | `foobar` |

View File

@@ -49,6 +49,12 @@ spec:
items:
type: string
type: array
cipherSuites:
description: CipherSuites defines the cipher suites to use when contacting
backend servers.
items:
type: string
type: array
disableHTTP2:
description: DisableHTTP2 disables HTTP/2 for connections with backend
servers.
@@ -109,6 +115,14 @@ spec:
to keep per-host.
minimum: -1
type: integer
maxVersion:
description: MaxVersion defines the maximum TLS version to use when
contacting backend servers.
type: string
minVersion:
description: MinVersion defines the minimum TLS version to use when
contacting backend servers.
type: string
peerCertURI:
description: PeerCertURI defines the peer cert URI used to match against
SAN URI during the peer certificate verification.

View File

@@ -3,13 +3,27 @@ title: "Traefik API & Dashboard Documentation"
description: "Traefik Proxy exposes information through API handlers and showcase them on the Dashboard. Learn about the security, configuration, and endpoints of the APIs and Dashboard. Read the technical documentation."
---
The dashboard is the central place that shows you the current active routes handled by Traefik.
Traefik exposes a number of information through API endpoints, such as the configuration of your routers, services, middlewares, etc.
The dashboard, which is the central place that displays the current active routes handled by Traefik, fetches the data from this API.
<figure>
<img src="../../../assets/img/webui-dashboard.png" alt="Dashboard - Providers" />
<figcaption>The dashboard in action</figcaption>
</figure>
## Security
Enabling the API and the dashboard in production is not recommended, because it will expose all configuration elements,
including sensitive data, for which access should be reserved to administrators.
In production, it should be at least secured by authentication and authorizations.
!!! info
It's recommended to NOT publicly exposing the API's port, keeping it restricted to internal networks
(as in the [principle of least privilege](https://en.wikipedia.org/wiki/Principle_of_least_privilege), applied to networks).
## Configuration Example
Enable the dashboard:
@@ -187,6 +201,7 @@ All the following endpoints must be accessed with a `GET` HTTP request.
| <a id="opt-apientrypoints" href="#opt-apientrypoints" title="#opt-apientrypoints">`/api/entrypoints`</a> | Lists all the entry points information. |
| <a id="opt-apientrypointsname" href="#opt-apientrypointsname" title="#opt-apientrypointsname">`/api/entrypoints/{name}`</a> | Returns the information of the entry point specified by `name`. |
| <a id="opt-apioverview" href="#opt-apioverview" title="#opt-apioverview">`/api/overview`</a> | Returns statistic information about HTTP, TCP and about enabled features and providers. |
| <a id="opt-apisupport-dump" href="#opt-apisupport-dump" title="#opt-apisupport-dump">`/api/support-dump`</a> | Returns an archive that contains the anonymized static configuration and the runtime configuration. |
| <a id="opt-apirawdata" href="#opt-apirawdata" title="#opt-apirawdata">`/api/rawdata`</a> | Returns information about dynamic configurations, errors, status and dependency relations. |
| <a id="opt-apiversion" href="#opt-apiversion" title="#opt-apiversion">`/api/version`</a> | Returns information about Traefik version. |
| <a id="opt-debugvars" href="#opt-debugvars" title="#opt-debugvars">`/debug/vars`</a> | See the [expvar](https://golang.org/pkg/expvar/) Go documentation. |
@@ -203,14 +218,16 @@ All the following endpoints must be accessed with a `GET` HTTP request.
## Dashboard
The dashboard is available at the same location as the API, but by default on the path `/dashboard/`.
The dashboard is available by default on the path `/dashboard/`.
!!! note
- The trailing slash `/` in `/dashboard/` is mandatory. This limitation can be mitigated using the the [RedirectRegex Middleware](../../middlewares/http/redirectregex.md).
- There is also a redirect from the path `/` to `/dashboard/`, but you should not rely on this behavior, as it is subject to change and may complicate routing rules.
- There is also a redirect from the path `/` to `/dashboard/`.
To securely access the dashboard, you need to define a routing configuration within Traefik. This involves setting up a router attached to the service `api@internal`, which allows you to:
As mentioned above in the [Security](#security) section, it is important to secure access to both the dashboard and the API.
You need to define a routing configuration within Traefik.
This involves setting up a router attached to the service `api@internal`, which allows you to:
- Implement security features using [middlewares](../../middlewares/overview.md), such as authentication ([basicAuth](../../middlewares/http/basicauth.md), [digestAuth](../../middlewares/http/digestauth.md),
[forwardAuth](../../middlewares/http/forwardauth.md)) or [allowlisting](../../middlewares/http/ipallowlist.md).

View File

@@ -40,6 +40,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-api" href="#opt-api" title="#opt-api">api</a> | Enable api/dashboard. | false |
| <a id="opt-api-basepath" href="#opt-api-basepath" title="#opt-api-basepath">api.basepath</a> | Defines the base path where the API and Dashboard will be exposed. | / |
| <a id="opt-api-dashboard" href="#opt-api-dashboard" title="#opt-api-dashboard">api.dashboard</a> | Activate dashboard. | true |
| <a id="opt-api-dashboardname" href="#opt-api-dashboardname" title="#opt-api-dashboardname">api.dashboardname</a> | Custom name for the dashboard. | |
| <a id="opt-api-debug" href="#opt-api-debug" title="#opt-api-debug">api.debug</a> | Enable additional endpoints for debugging and profiling. | false |
| <a id="opt-api-disabledashboardad" href="#opt-api-disabledashboardad" title="#opt-api-disabledashboardad">api.disabledashboardad</a> | Disable ad in the dashboard. | false |
| <a id="opt-api-insecure" href="#opt-api-insecure" title="#opt-api-insecure">api.insecure</a> | Activate API directly on the entryPoint named traefik. | false |
@@ -49,6 +50,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-certificatesresolvers-name-acme-caservername" href="#opt-certificatesresolvers-name-acme-caservername" title="#opt-certificatesresolvers-name-acme-caservername">certificatesresolvers._name_.acme.caservername</a> | Specify the CA server name that can be used to authenticate an ACME server with an HTTPS certificate not issued by a CA in the system-wide trusted root list. | |
| <a id="opt-certificatesresolvers-name-acme-casystemcertpool" href="#opt-certificatesresolvers-name-acme-casystemcertpool" title="#opt-certificatesresolvers-name-acme-casystemcertpool">certificatesresolvers._name_.acme.casystemcertpool</a> | Define if the certificates pool must use a copy of the system cert pool. | false |
| <a id="opt-certificatesresolvers-name-acme-certificatesduration" href="#opt-certificatesresolvers-name-acme-certificatesduration" title="#opt-certificatesresolvers-name-acme-certificatesduration">certificatesresolvers._name_.acme.certificatesduration</a> | Certificates' duration in hours. | 2160 |
| <a id="opt-certificatesresolvers-name-acme-certificatetimeout" href="#opt-certificatesresolvers-name-acme-certificatetimeout" title="#opt-certificatesresolvers-name-acme-certificatetimeout">certificatesresolvers._name_.acme.certificatetimeout</a> | Timeout for obtaining the certificate during the finalization request. | 30 |
| <a id="opt-certificatesresolvers-name-acme-clientresponseheadertimeout" href="#opt-certificatesresolvers-name-acme-clientresponseheadertimeout" title="#opt-certificatesresolvers-name-acme-clientresponseheadertimeout">certificatesresolvers._name_.acme.clientresponseheadertimeout</a> | Timeout for receiving the response headers when communicating with the ACME server. | 30 |
| <a id="opt-certificatesresolvers-name-acme-clienttimeout" href="#opt-certificatesresolvers-name-acme-clienttimeout" title="#opt-certificatesresolvers-name-acme-clienttimeout">certificatesresolvers._name_.acme.clienttimeout</a> | Timeout for a complete HTTP transaction with the ACME server. | 120 |
| <a id="opt-certificatesresolvers-name-acme-disablecommonname" href="#opt-certificatesresolvers-name-acme-disablecommonname" title="#opt-certificatesresolvers-name-acme-disablecommonname">certificatesresolvers._name_.acme.disablecommonname</a> | Disable the common name in the CSR. | false |
@@ -83,6 +85,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-entrypoints-name-asdefault" href="#opt-entrypoints-name-asdefault" title="#opt-entrypoints-name-asdefault">entrypoints._name_.asdefault</a> | Adds this EntryPoint to the list of default EntryPoints to be used on routers that don't have any Entrypoint defined. | false |
| <a id="opt-entrypoints-name-forwardedheaders-connection" href="#opt-entrypoints-name-forwardedheaders-connection" title="#opt-entrypoints-name-forwardedheaders-connection">entrypoints._name_.forwardedheaders.connection</a> | List of Connection headers that are allowed to pass through the middleware chain before being removed. | |
| <a id="opt-entrypoints-name-forwardedheaders-insecure" href="#opt-entrypoints-name-forwardedheaders-insecure" title="#opt-entrypoints-name-forwardedheaders-insecure">entrypoints._name_.forwardedheaders.insecure</a> | Trust all forwarded headers. | false |
| <a id="opt-entrypoints-name-forwardedheaders-notappendxforwardedfor" href="#opt-entrypoints-name-forwardedheaders-notappendxforwardedfor" title="#opt-entrypoints-name-forwardedheaders-notappendxforwardedfor">entrypoints._name_.forwardedheaders.notappendxforwardedfor</a> | Disable appending RemoteAddr to X-Forwarded-For header. Defaults to false (appending is enabled). | false |
| <a id="opt-entrypoints-name-forwardedheaders-trustedips" href="#opt-entrypoints-name-forwardedheaders-trustedips" title="#opt-entrypoints-name-forwardedheaders-trustedips">entrypoints._name_.forwardedheaders.trustedips</a> | Trust only forwarded headers from selected IPs. | |
| <a id="opt-entrypoints-name-http" href="#opt-entrypoints-name-http" title="#opt-entrypoints-name-http">entrypoints._name_.http</a> | HTTP configuration. | |
| <a id="opt-entrypoints-name-http-encodedcharacters-allowencodedbackslash" href="#opt-entrypoints-name-http-encodedcharacters-allowencodedbackslash" title="#opt-entrypoints-name-http-encodedcharacters-allowencodedbackslash">entrypoints._name_.http.encodedcharacters.allowencodedbackslash</a> | Defines whether requests with encoded back slash characters in the path are allowed. | false |
@@ -148,6 +151,7 @@ THIS FILE MUST NOT BE EDITED BY HAND
| <a id="opt-experimental-plugins-name-settings-useunsafe" href="#opt-experimental-plugins-name-settings-useunsafe" title="#opt-experimental-plugins-name-settings-useunsafe">experimental.plugins._name_.settings.useunsafe</a> | Allow the plugin to use unsafe and syscall packages. | false |
| <a id="opt-experimental-plugins-name-version" href="#opt-experimental-plugins-name-version" title="#opt-experimental-plugins-name-version">experimental.plugins._name_.version</a> | plugin's version. | |
| <a id="opt-global-checknewversion" href="#opt-global-checknewversion" title="#opt-global-checknewversion">global.checknewversion</a> | Periodically check if a new version has been released. | true |
| <a id="opt-global-notappendxforwardedfor" href="#opt-global-notappendxforwardedfor" title="#opt-global-notappendxforwardedfor">global.notappendxforwardedfor</a> | Disable appending RemoteAddr to X-Forwarded-For header. Defaults to false (appending is enabled). | false |
| <a id="opt-global-sendanonymoususage" href="#opt-global-sendanonymoususage" title="#opt-global-sendanonymoususage">global.sendanonymoususage</a> | Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default. | false |
| <a id="opt-hostresolver" href="#opt-hostresolver" title="#opt-hostresolver">hostresolver</a> | Enable CNAME Flattening. | false |
| <a id="opt-hostresolver-cnameflattening" href="#opt-hostresolver-cnameflattening" title="#opt-hostresolver-cnameflattening">hostresolver.cnameflattening</a> | A flag to enable/disable CNAME flattening | false |

View File

@@ -90,6 +90,7 @@ additionalArguments:
| <a id="opt-asDefault" href="#opt-asDefault" title="#opt-asDefault">`asDefault`</a> | Mark the `entryPoint` to be in the list of default `entryPoints`.<br /> `entryPoints`in this list are used (by default) on HTTP and TCP routers that do not define their own `entryPoints` option.<br /> More information [here](#asdefault). | false | No |
| <a id="opt-forwardedHeaders-trustedIPs" href="#opt-forwardedHeaders-trustedIPs" title="#opt-forwardedHeaders-trustedIPs">`forwardedHeaders.trustedIPs`</a> | Set the IPs or CIDR from where Traefik trusts the forwarded headers information (`X-Forwarded-*`). | - | No |
| <a id="opt-forwardedHeaders-insecure" href="#opt-forwardedHeaders-insecure" title="#opt-forwardedHeaders-insecure">`forwardedHeaders.insecure`</a> | Set the insecure mode to always trust the forwarded headers information (`X-Forwarded-*`).<br />We recommend to use this option only for tests purposes, not in production. | false | No |
| <a id="opt-forwardedHeaders-notAppendXForwardedFor" href="#opt-forwardedHeaders-notAppendXForwardedFor" title="#opt-forwardedHeaders-notAppendXForwardedFor">`forwardedHeaders.`<br />`notAppendXForwardedFor`</a> | When set to `true`, Traefik will not append the client's `RemoteAddr` to the `X-Forwarded-For` header. The existing header is preserved as-is. If no `X-Forwarded-For` header exists, none will be added. | false | No |
| <a id="opt-http-redirections-entryPoint-to" href="#opt-http-redirections-entryPoint-to" title="#opt-http-redirections-entryPoint-to">`http.redirections.`<br />`entryPoint.to`</a> | The target element to enable (permanent) redirecting of all incoming requests on an entry point to another one. <br /> The target element can be an entry point name (ex: `websecure`), or a port (`:443`). | - | Yes |
| <a id="opt-http-redirections-entryPoint-scheme" href="#opt-http-redirections-entryPoint-scheme" title="#opt-http-redirections-entryPoint-scheme">`http.redirections.`<br />`entryPoint.scheme`</a> | The target scheme to use for (permanent) redirection of all incoming requests. | https | No |
| <a id="opt-http-redirections-entryPoint-permanent" href="#opt-http-redirections-entryPoint-permanent" title="#opt-http-redirections-entryPoint-permanent">`http.redirections.`<br />`entryPoint.permanent`</a> | Enable permanent redirecting of all incoming requests on an entry point to another one changing the scheme. <br /> The target element, it can be an entry point name (ex: `websecure`), or a port (`:443`). | false | No |

View File

@@ -420,7 +420,7 @@ You can specify which Docker API Endpoint to use with the directive [`endpoint`]
- [Traefik and Docker: A Discussion with Docker Captain, Bret Fisher](https://blog.traefik.io/traefik-and-docker-a-discussion-with-docker-captain-bret-fisher-7f0b9a54ff88)
- [KubeCon EU 2018 Keynote, Running with Scissors, from Liz Rice](https://www.youtube.com/watch?v=ltrV-Qmh3oY)
- [Don't expose the Docker socket (not even to a container)](https://www.lvh.io/posts/dont-expose-the-docker-socket-not-even-to-a-container/)
- [A thread on Stack Overflow about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623)
- [A thread on Hacker News about sharing the `/var/run/docker.sock` file](https://news.ycombinator.com/item?id=17983623)
- [To DinD or not to DinD](https://blog.loof.fr/2018/01/to-dind-or-not-do-dind.html)
- [Traefik issue GH-4174 about security with Docker socket](https://github.com/traefik/traefik/issues/4174)
- [Inspecting Docker Activity with Socat](https://developers.redhat.com/blog/2015/02/25/inspecting-docker-activity-with-socat/)

View File

@@ -91,6 +91,7 @@ ACME certificate resolvers have the following configuration options:
| <a id="opt-acme-certificatesDuration" href="#opt-acme-certificatesDuration" title="#opt-acme-certificatesDuration">`acme.certificatesDuration`</a> | The certificates' duration in hours, exclusively used to determine renewal dates. | 2160 | No |
| <a id="opt-acme-clientTimeout" href="#opt-acme-clientTimeout" title="#opt-acme-clientTimeout">`acme.clientTimeout`</a> | Timeout for HTTP Client used to communicate with the ACME server. | 2m | No |
| <a id="opt-acme-clientResponseHeaderTimeout" href="#opt-acme-clientResponseHeaderTimeout" title="#opt-acme-clientResponseHeaderTimeout">`acme.clientResponseHeaderTimeout`</a> | Timeout for response headers for HTTP Client used to communicate with the ACME server. | 30s | No |
| <a id="opt-acme-certificateTimeout" href="#opt-acme-certificateTimeout" title="#opt-acme-certificateTimeout">`acme.certificateTimeout`</a> | Timeout for obtaining the certificate during the finalization request. Set this if the ACME server is slow to issue a certificate. | 30s | No |
| <a id="opt-acme-dnsChallenge" href="#opt-acme-dnsChallenge" title="#opt-acme-dnsChallenge">`acme.dnsChallenge`</a> | Enable DNS-01 challenge. More information [here](#dnschallenge). | - | No |
| <a id="opt-acme-dnsChallenge-provider" href="#opt-acme-dnsChallenge-provider" title="#opt-acme-dnsChallenge-provider">`acme.dnsChallenge.provider`</a> | DNS provider to use. | "" | No |
| <a id="opt-acme-dnsChallenge-resolvers" href="#opt-acme-dnsChallenge-resolvers" title="#opt-acme-dnsChallenge-resolvers">`acme.dnsChallenge.resolvers`</a> | DNS servers to resolve the FQDN authority. | [] | No |

View File

@@ -35,6 +35,11 @@ http:
- "spiffe://example.org/id1"
- "spiffe://example.org/id2"
trustDomain: "example.org"
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
minVersion: VersionTLS12
maxVersion: VersionTLS12
```
```toml tab="Structured (TOML)"
@@ -46,6 +51,9 @@ http:
maxIdleConnsPerHost = 100
disableHTTP2 = true
peerCertURI = "spiffe://example.org/peer"
cipherSuites = ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"]
minVersion = "VersionTLS12"
maxVersion = "VersionTLS12"
[http.serversTransports.mytransport.forwardingTimeouts]
dialTimeout = "30s"
@@ -100,6 +108,9 @@ labels:
| <a id="opt-certificates" href="#opt-certificates" title="#opt-certificates">`certificates`</a> | Defines the list of certificates (as file paths, or data bytes) that will be set as client certificates for mTLS. | [] | No |
| <a id="opt-insecureSkipVerify" href="#opt-insecureSkipVerify" title="#opt-insecureSkipVerify">`insecureSkipVerify`</a> | Controls whether the server's certificate chain and host name is verified. | false | No |
| <a id="opt-rootcas" href="#opt-rootcas" title="#opt-rootcas">`rootcas`</a> | Set of root certificate authorities to use when verifying server certificates. (for mTLS connections). | [] | No |
| <a id="opt-cipherSuites" href="#opt-cipherSuites" title="#opt-cipherSuites">`cipherSuites`</a> | Defines the cipher suites to use when contacting backend servers. | [] | No |
| <a id="opt-minVersion" href="#opt-minVersion" title="#opt-minVersion">`minVersion`</a> | Defines the minimum TLS version to use when contacting backend servers. | "" | No |
| <a id="opt-maxVersion" href="#opt-maxVersion" title="#opt-maxVersion">`maxVersion`</a> | Defines the maximum TLS version to use when contacting backend servers. | "" | No |
| <a id="opt-maxIdleConnsPerHost" href="#opt-maxIdleConnsPerHost" title="#opt-maxIdleConnsPerHost">`maxIdleConnsPerHost`</a> | Maximum idle (keep-alive) connections to keep per-host. | 200 | No |
| <a id="opt-disableHTTP2" href="#opt-disableHTTP2" title="#opt-disableHTTP2">`disableHTTP2`</a> | Disables HTTP/2 for connections with servers. | false | No |
| <a id="opt-peerCertURI" href="#opt-peerCertURI" title="#opt-peerCertURI">`peerCertURI`</a> | Defines the URI used to match against SAN URIs during the server's certificate verification. | "" | No |

View File

@@ -67,6 +67,21 @@ spec:
| <a id="opt-serverstransport-forwardingTimeouts-idleConnTimeout" href="#opt-serverstransport-forwardingTimeouts-idleConnTimeout" title="#opt-serverstransport-forwardingTimeouts-idleConnTimeout">`serverstransport.`<br />`forwardingTimeouts.idleConnTimeout`</a> | Maximum amount of time an idle (keep-alive) connection will remain idle before closing itself.<br />Zero means no timeout. | 90s | No |
| <a id="opt-serverstransport-spiffe-ids" href="#opt-serverstransport-spiffe-ids" title="#opt-serverstransport-spiffe-ids">`serverstransport.`<br />`spiffe.ids`</a> | Allow SPIFFE IDs.<br />This takes precedence over the SPIFFE TrustDomain. | | No |
| <a id="opt-serverstransport-spiffe-trustDomain" href="#opt-serverstransport-spiffe-trustDomain" title="#opt-serverstransport-spiffe-trustDomain">`serverstransport.`<br />`spiffe.trustDomain`</a> | Allow SPIFFE trust domain. | "" | No |
| <a id="opt-serverstransport-serverName-2" href="#opt-serverstransport-serverName-2" title="#opt-serverstransport-serverName-2">`serverstransport.`<br />`serverName`</a> | Defines the server name that will be used for SNI. | | No |
| <a id="opt-serverstransport-insecureSkipVerify-2" href="#opt-serverstransport-insecureSkipVerify-2" title="#opt-serverstransport-insecureSkipVerify-2">`serverstransport.`<br />`insecureSkipVerify`</a> | Controls whether the server's certificate chain and host name is verified. | false | No |
| <a id="opt-serverstransport-rootcas-2" href="#opt-serverstransport-rootcas-2" title="#opt-serverstransport-rootcas-2">`serverstransport.`<br />`rootcas`</a> | Set of root certificate authorities to use when verifying server certificates. (for mTLS connections). | | No |
| <a id="opt-serverstransport-certificatesSecrets-2" href="#opt-serverstransport-certificatesSecrets-2" title="#opt-serverstransport-certificatesSecrets-2">`serverstransport.`<br />`certificatesSecrets`</a> | Certificates to present to the server for mTLS. | | No |
| <a id="opt-serverstransport-cipherSuites" href="#opt-serverstransport-cipherSuites" title="#opt-serverstransport-cipherSuites">`serverstransport.`<br />`cipherSuites`</a> | Defines the cipher suites to use when contacting backend servers. | [] | No |
| <a id="opt-serverstransport-minVersion" href="#opt-serverstransport-minVersion" title="#opt-serverstransport-minVersion">`serverstransport.`<br />`minVersion`</a> | Defines the minimum TLS version to use when contacting backend servers. | "" | No |
| <a id="opt-serverstransport-maxVersion" href="#opt-serverstransport-maxVersion" title="#opt-serverstransport-maxVersion">`serverstransport.`<br />`maxVersion`</a> | Defines the maximum TLS version to use when contacting backend servers. | "" | No |
| <a id="opt-serverstransport-maxIdleConnsPerHost-2" href="#opt-serverstransport-maxIdleConnsPerHost-2" title="#opt-serverstransport-maxIdleConnsPerHost-2">`serverstransport.`<br />`maxIdleConnsPerHost`</a> | Maximum idle (keep-alive) connections to keep per-host. | 200 | No |
| <a id="opt-serverstransport-disableHTTP2-2" href="#opt-serverstransport-disableHTTP2-2" title="#opt-serverstransport-disableHTTP2-2">`serverstransport.`<br />`disableHTTP2`</a> | Disables HTTP/2 for connections with servers. | false | No |
| <a id="opt-serverstransport-peerCertURI-2" href="#opt-serverstransport-peerCertURI-2" title="#opt-serverstransport-peerCertURI-2">`serverstransport.`<br />`peerCertURI`</a> | Defines the URI used to match against SAN URIs during the server's certificate verification. | "" | No |
| <a id="opt-serverstransport-forwardingTimeouts-dialTimeout-2" href="#opt-serverstransport-forwardingTimeouts-dialTimeout-2" title="#opt-serverstransport-forwardingTimeouts-dialTimeout-2">`serverstransport.`<br />`forwardingTimeouts.dialTimeout`</a> | Amount of time to wait until a connection to a server can be established.<br />Zero means no timeout. | 30s | No |
| <a id="opt-serverstransport-forwardingTimeouts-responseHeaderTimeout-2" href="#opt-serverstransport-forwardingTimeouts-responseHeaderTimeout-2" title="#opt-serverstransport-forwardingTimeouts-responseHeaderTimeout-2">`serverstransport.`<br />`forwardingTimeouts.responseHeaderTimeout`</a> | Amount of time to wait for a server's response headers after fully writing the request (including its body, if any).<br />Zero means no timeout | 0s | No |
| <a id="opt-serverstransport-forwardingTimeouts-idleConnTimeout-2" href="#opt-serverstransport-forwardingTimeouts-idleConnTimeout-2" title="#opt-serverstransport-forwardingTimeouts-idleConnTimeout-2">`serverstransport.`<br />`forwardingTimeouts.idleConnTimeout`</a> | Maximum amount of time an idle (keep-alive) connection will remain idle before closing itself.<br />Zero means no timeout. | 90s | No |
| <a id="opt-serverstransport-spiffe-ids-2" href="#opt-serverstransport-spiffe-ids-2" title="#opt-serverstransport-spiffe-ids-2">`serverstransport.`<br />`spiffe.ids`</a> | Allow SPIFFE IDs.<br />This takes precedence over the SPIFFE TrustDomain. | | No |
| <a id="opt-serverstransport-spiffe-trustDomain-2" href="#opt-serverstransport-spiffe-trustDomain-2" title="#opt-serverstransport-spiffe-trustDomain-2">`serverstransport.`<br />`spiffe.trustDomain`</a> | Allow SPIFFE trust domain. | "" | No |
!!! note "CA Secret"
The CA secret must contain a base64 encoded certificate under either a tls.ca or a ca.crt key.

View File

@@ -283,17 +283,21 @@ The following annotations are organized by category for easier navigation.
| <a id="opt-nginx-ingress-kubernetes-ioaffinity" href="#opt-nginx-ingress-kubernetes-ioaffinity" title="#opt-nginx-ingress-kubernetes-ioaffinity">`nginx.ingress.kubernetes.io/affinity`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioaffinity-mode" href="#opt-nginx-ingress-kubernetes-ioaffinity-mode" title="#opt-nginx-ingress-kubernetes-ioaffinity-mode">`nginx.ingress.kubernetes.io/affinity-mode`</a> | Only persistent mode supported; balanced/canary not supported. |
| <a id="opt-nginx-ingress-kubernetes-iosession-cookie-name" href="#opt-nginx-ingress-kubernetes-iosession-cookie-name" title="#opt-nginx-ingress-kubernetes-iosession-cookie-name">`nginx.ingress.kubernetes.io/session-cookie-name`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iosession-cookie-secure" href="#opt-nginx-ingress-kubernetes-iosession-cookie-secure" title="#opt-nginx-ingress-kubernetes-iosession-cookie-secure">`nginx.ingress.kubernetes.io/session-cookie-secure`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iosession-cookie-path" href="#opt-nginx-ingress-kubernetes-iosession-cookie-path" title="#opt-nginx-ingress-kubernetes-iosession-cookie-path">`nginx.ingress.kubernetes.io/session-cookie-path`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iosession-cookie-domain" href="#opt-nginx-ingress-kubernetes-iosession-cookie-domain" title="#opt-nginx-ingress-kubernetes-iosession-cookie-domain">`nginx.ingress.kubernetes.io/session-cookie-domain`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iosession-cookie-samesite" href="#opt-nginx-ingress-kubernetes-iosession-cookie-samesite" title="#opt-nginx-ingress-kubernetes-iosession-cookie-samesite">`nginx.ingress.kubernetes.io/session-cookie-samesite`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iosession-cookie-max-age" href="#opt-nginx-ingress-kubernetes-iosession-cookie-max-age" title="#opt-nginx-ingress-kubernetes-iosession-cookie-max-age">`nginx.ingress.kubernetes.io/session-cookie-max-age`</a> | |
### Load Balancing & Backend
| Annotation | Limitations / Notes |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioload-balance" href="#opt-nginx-ingress-kubernetes-ioload-balance" title="#opt-nginx-ingress-kubernetes-ioload-balance">`nginx.ingress.kubernetes.io/load-balance`</a> | Only round_robin supported; ewma and IP hash not supported. |
| <a id="opt-nginx-ingress-kubernetes-iobackend-protocol" href="#opt-nginx-ingress-kubernetes-iobackend-protocol" title="#opt-nginx-ingress-kubernetes-iobackend-protocol">`nginx.ingress.kubernetes.io/backend-protocol`</a> | FCGI and AUTO_HTTP not supported. |
| <a id="opt-nginx-ingress-kubernetes-ioservice-upstream" href="#opt-nginx-ingress-kubernetes-ioservice-upstream" title="#opt-nginx-ingress-kubernetes-ioservice-upstream">`nginx.ingress.kubernetes.io/service-upstream`</a> | |
| Annotation | Limitations / Notes |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-ioload-balance" href="#opt-nginx-ingress-kubernetes-ioload-balance" title="#opt-nginx-ingress-kubernetes-ioload-balance">`nginx.ingress.kubernetes.io/load-balance`</a> | Only round_robin supported; ewma and IP hash not supported. |
| <a id="opt-nginx-ingress-kubernetes-iobackend-protocol" href="#opt-nginx-ingress-kubernetes-iobackend-protocol" title="#opt-nginx-ingress-kubernetes-iobackend-protocol">`nginx.ingress.kubernetes.io/backend-protocol`</a> | FCGI and AUTO_HTTP not supported. |
| <a id="opt-nginx-ingress-kubernetes-ioservice-upstream" href="#opt-nginx-ingress-kubernetes-ioservice-upstream" title="#opt-nginx-ingress-kubernetes-ioservice-upstream">`nginx.ingress.kubernetes.io/service-upstream`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioupstream-vhost" href="#opt-nginx-ingress-kubernetes-ioupstream-vhost" title="#opt-nginx-ingress-kubernetes-ioupstream-vhost">`nginx.ingress.kubernetes.io/upstream-vhost`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iocustom-headers" href="#opt-nginx-ingress-kubernetes-iocustom-headers" title="#opt-nginx-ingress-kubernetes-iocustom-headers">`nginx.ingress.kubernetes.io/custom-headers`</a> | Header whitelisting, similar to `global-allowed-response-headers` NGINX config is not supported. |
### CORS
@@ -304,6 +308,7 @@ The following annotations are organized by category for easier navigation.
| <a id="opt-nginx-ingress-kubernetes-iocors-allow-headers" href="#opt-nginx-ingress-kubernetes-iocors-allow-headers" title="#opt-nginx-ingress-kubernetes-iocors-allow-headers">`nginx.ingress.kubernetes.io/cors-allow-headers`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iocors-allow-methods" href="#opt-nginx-ingress-kubernetes-iocors-allow-methods" title="#opt-nginx-ingress-kubernetes-iocors-allow-methods">`nginx.ingress.kubernetes.io/cors-allow-methods`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iocors-allow-origin" href="#opt-nginx-ingress-kubernetes-iocors-allow-origin" title="#opt-nginx-ingress-kubernetes-iocors-allow-origin">`nginx.ingress.kubernetes.io/cors-allow-origin`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iocors-expose-headers" href="#opt-nginx-ingress-kubernetes-iocors-expose-headers" title="#opt-nginx-ingress-kubernetes-iocors-expose-headers">`nginx.ingress.kubernetes.io/cors-expose-headers`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iocors-max-age" href="#opt-nginx-ingress-kubernetes-iocors-max-age" title="#opt-nginx-ingress-kubernetes-iocors-max-age">`nginx.ingress.kubernetes.io/cors-max-age`</a> | |
### Routing
@@ -312,6 +317,13 @@ The following annotations are organized by category for easier navigation.
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-iouse-regex" href="#opt-nginx-ingress-kubernetes-iouse-regex" title="#opt-nginx-ingress-kubernetes-iouse-regex">`nginx.ingress.kubernetes.io/use-regex`</a> | |
### IP Whitelist
| Annotation | Limitations / Notes |
|-------------------------------------------------------|--------------------------------------------------------------------------------------------|
| <a id="opt-nginx-ingress-kubernetes-iowhitelist-source-range" href="#opt-nginx-ingress-kubernetes-iowhitelist-source-range" title="#opt-nginx-ingress-kubernetes-iowhitelist-source-range">`nginx.ingress.kubernetes.io/whitelist-source-range`</a> | |
## Limitations
### Caveats and Key Behavioral Differences
@@ -423,9 +435,7 @@ The following annotations are organized by category for easier navigation.
| <a id="opt-nginx-ingress-kubernetes-iomirror-host" href="#opt-nginx-ingress-kubernetes-iomirror-host" title="#opt-nginx-ingress-kubernetes-iomirror-host">`nginx.ingress.kubernetes.io/mirror-host`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iox-forwarded-prefix" href="#opt-nginx-ingress-kubernetes-iox-forwarded-prefix" title="#opt-nginx-ingress-kubernetes-iox-forwarded-prefix">`nginx.ingress.kubernetes.io/x-forwarded-prefix`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioupstream-hash-by" href="#opt-nginx-ingress-kubernetes-ioupstream-hash-by" title="#opt-nginx-ingress-kubernetes-ioupstream-hash-by">`nginx.ingress.kubernetes.io/upstream-hash-by`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioupstream-vhost" href="#opt-nginx-ingress-kubernetes-ioupstream-vhost" title="#opt-nginx-ingress-kubernetes-ioupstream-vhost">`nginx.ingress.kubernetes.io/upstream-vhost`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iodenylist-source-range" href="#opt-nginx-ingress-kubernetes-iodenylist-source-range" title="#opt-nginx-ingress-kubernetes-iodenylist-source-range">`nginx.ingress.kubernetes.io/denylist-source-range`</a> | |
| <a id="opt-nginx-ingress-kubernetes-iowhitelist-source-range" href="#opt-nginx-ingress-kubernetes-iowhitelist-source-range" title="#opt-nginx-ingress-kubernetes-iowhitelist-source-range">`nginx.ingress.kubernetes.io/whitelist-source-range`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffering" href="#opt-nginx-ingress-kubernetes-ioproxy-buffering" title="#opt-nginx-ingress-kubernetes-ioproxy-buffering">`nginx.ingress.kubernetes.io/proxy-buffering`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffers-number" href="#opt-nginx-ingress-kubernetes-ioproxy-buffers-number" title="#opt-nginx-ingress-kubernetes-ioproxy-buffers-number">`nginx.ingress.kubernetes.io/proxy-buffers-number`</a> | |
| <a id="opt-nginx-ingress-kubernetes-ioproxy-buffer-size" href="#opt-nginx-ingress-kubernetes-ioproxy-buffer-size" title="#opt-nginx-ingress-kubernetes-ioproxy-buffer-size">`nginx.ingress.kubernetes.io/proxy-buffer-size`</a> | |

View File

@@ -380,6 +380,9 @@
serverName = "foobar"
insecureSkipVerify = true
rootCAs = ["foobar", "foobar"]
cipherSuites = ["foobar", "foobar"]
minVersion = "foobar"
maxVersion = "foobar"
maxIdleConnsPerHost = 42
disableHTTP2 = true
peerCertURI = "foobar"
@@ -404,6 +407,9 @@
serverName = "foobar"
insecureSkipVerify = true
rootCAs = ["foobar", "foobar"]
cipherSuites = ["foobar", "foobar"]
minVersion = "foobar"
maxVersion = "foobar"
maxIdleConnsPerHost = 42
disableHTTP2 = true
peerCertURI = "foobar"

View File

@@ -443,6 +443,11 @@ http:
keyFile: foobar
- certFile: foobar
keyFile: foobar
cipherSuites:
- foobar
- foobar
minVersion: foobar
maxVersion: foobar
maxIdleConnsPerHost: 42
forwardingTimeouts:
dialTimeout: 42s
@@ -468,6 +473,11 @@ http:
keyFile: foobar
- certFile: foobar
keyFile: foobar
cipherSuites:
- foobar
- foobar
minVersion: foobar
maxVersion: foobar
maxIdleConnsPerHost: 42
forwardingTimeouts:
dialTimeout: 42s

View File

@@ -1869,6 +1869,11 @@ Register the `TLSStore` kind in the Kubernetes cluster before creating `TLSStore
- spiffe://trust-domain/id1
- spiffe://trust-domain/id2
trustDomain: "spiffe://trust-domain" # [14]
cipherSuites: # [15]
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
minVersion: VersionTLS11 # [16]
maxVersion: VersionTLS12 # [17]
```
| Ref | Attribute | Purpose |
@@ -1887,6 +1892,9 @@ Register the `TLSStore` kind in the Kubernetes cluster before creating `TLSStore
| [12] | `spiffe` | The spiffe configuration. |
| [13] | `ids` | Defines the allowed SPIFFE IDs (takes precedence over the SPIFFE TrustDomain). |
| [14] | `trustDomain` | Defines the allowed SPIFFE trust domain. |
| [15] | `cipherSuites` | Defines the cipher suites to use when contacting backend servers. |
| [16] | `minVersion` | Defines the minimum TLS version to use when contacting backend servers. |
| [17] | `maxVersion` | Defines the maximum TLS version to use when contacting backend servers. |
!!! info "CA Secret"

View File

@@ -800,6 +800,129 @@ data:
ca.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
```
#### `cipherSuites`
_Optional_
`cipherSuites` defines the cipher suites to use when contacting backend servers.
This option allows you to control the cryptographic algorithms used for backend connections, which is useful for:
- Connecting to legacy backends that only support specific cipher suites
- Enforcing security policies (e.g., requiring Perfect Forward Secrecy)
- Meeting compliance requirements
If not specified, Go's default cipher suites are used.
```yaml tab="File (YAML)"
## Dynamic configuration
http:
serversTransports:
mytransport:
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
```
```toml tab="File (TOML)"
## Dynamic configuration
[http.serversTransports.mytransport]
cipherSuites = ["TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256","TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"]
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: mytransport
namespace: default
spec:
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
```
#### `minVersion`
_Optional_
`minVersion` defines the minimum TLS version to use when contacting backend servers.
Use this option to enforce a minimum security level for backend connections.
!!! info "Valid Values"
- `VersionTLS10` (discouraged - deprecated and insecure)
- `VersionTLS11` (discouraged - deprecated and insecure)
- `VersionTLS12` (recommended minimum)
- `VersionTLS13` (most secure)
If not specified, Go's default minimum version is used.
```yaml tab="File (YAML)"
## Dynamic configuration
http:
serversTransports:
mytransport:
minVersion: VersionTLS12
```
```toml tab="File (TOML)"
## Dynamic configuration
[http.serversTransports.mytransport]
minVersion = "VersionTLS12"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: mytransport
namespace: default
spec:
minVersion: VersionTLS12
```
#### `maxVersion`
_Optional_
`maxVersion` defines the maximum TLS version to use when contacting backend servers.
!!! warning "Use with Caution"
We discourage using this option to disable TLS 1.3. It should only be used for connecting to legacy backends that don't support newer TLS versions.
!!! info "Valid Values"
- `VersionTLS10`
- `VersionTLS11`
- `VersionTLS12`
- `VersionTLS13`
If not specified, Go's default maximum version (latest) is used.
```yaml tab="File (YAML)"
## Dynamic configuration
http:
serversTransports:
mytransport:
maxVersion: VersionTLS12
```
```toml tab="File (TOML)"
## Dynamic configuration
[http.serversTransports.mytransport]
maxVersion = "VersionTLS12"
```
```yaml tab="Kubernetes"
apiVersion: traefik.io/v1alpha1
kind: ServersTransport
metadata:
name: mytransport
namespace: default
spec:
maxVersion: VersionTLS12
```
#### `maxIdleConnsPerHost`
_Optional, Default=2_

View File

@@ -126,7 +126,7 @@ ingressRoute:
middlewares:
- name: dashboard-auth
# Creates a BasiAuth Middleware and Secret for the Dashboard Security
# Creates a BasicAuth Middleware and Secret for the Dashboard Security
extraObjects:
- apiVersion: v1
kind: Secret

View File

@@ -61,7 +61,7 @@ In the same directory, create `dockercomposeswarm.yaml`:
```yaml
services:
traefik:
image: traefik:v3.4
image: traefik:v3.6
networks:
# Connect to the 'traefik_proxy' overlay network for inter-container communication across nodes

View File

@@ -2,24 +2,27 @@ site_name: Traefik
site_description: Traefik Documentation
site_author: traefik.io
site_url: https://doc.traefik.io/traefik
dev_addr: 0.0.0.0:8000
dev_addr: localhost:8000
repo_name: 'GitHub'
repo_url: 'https://github.com/traefik/traefik'
docs_dir: 'content'
product: proxy
# https://squidfunk.github.io/mkdocs-material/
# Use custom version of mkdocs-material
# See https://github.com/traefik/mkdocs-material
theme:
name: 'traefik-labs'
product: proxy
language: en
include_sidebar: true
favicon: assets/img/traefikproxy-icon-color.png
logo: assets/img/traefikproxy-vertical-logo-color.svg
feature:
tabs: false
features:
- content.code.copy
palette:
primary: 'cyan'
accent: 'cyan'
@@ -27,7 +30,7 @@ theme:
prev: 'Previous'
next: 'Next'
copyright: 'Traefik Labs • Copyright &copy; 2016-2025'
copyright: 'Traefik Labs • Copyright &copy; 2016-2026'
extra_javascript:
- assets/js/hljs/highlight.pack.js # Download from https://highlightjs.org/download/ and enable YAML, TOML and Dockerfile
@@ -35,6 +38,7 @@ extra_javascript:
extra_css:
- assets/css/menu-icons.css
- assets/css/code-copy.css
plugins:
- search
@@ -185,6 +189,7 @@ markdown_extensions:
# Page tree
nav:
- 'What is Traefik': 'index.md'
- 'Features': 'features/index.md'
- 'Getting Started':
- 'Overview': 'getting-started/index.md'
- 'Configuration Introduction': 'getting-started/configuration-overview.md'

View File

@@ -16,3 +16,15 @@
[pymdown-extensions]: https://facelessuser.github.io/pymdown-extensions "PyMdown Extensions"
[pymdown-extensions-src]: https://github.com/facelessuser/pymdown-extensions "PyMdown Extensions - Sources"
## Build locally without docker
```sh
# Pre-requisite: python3, pip and virtualenv
DOCS="/tmp/traefik-docs"
mkdir "$DOCS"
virtualenv "$DOCS"
source "$DOCS/bin/activate"
pip install -r requirements.txt
mkdocs serve # or mkdocs build
```

48
docs/scripts/lint-yaml.sh Executable file
View File

@@ -0,0 +1,48 @@
#!/bin/sh
# This script checks that YAML files with multiple Kubernetes resources
# do not start with '---'
#
# Rule: If a YAML file contains more than one Kubernetes resource
# (indicated by '---' separator in the middle of the file),
# it should NOT start with '---'
set -eu
BASE_DIR="${1:-/app}"
echo "== Linting YAML files (Kubernetes multi-resource format)"
# Find all YAML files in the content directory
find "${BASE_DIR}/content" -type f \( -name "*.yml" -o -name "*.yaml" \) | while read -r file; do
# Count the number of '---' lines in the file
separator_count=$(grep -c "^---" "$file" || true)
# Check if file starts with '---'
starts_with_separator=false
if head -1 "$file" | grep -q "^---"; then
starts_with_separator=true
fi
# If file has multiple resources (separator_count >= 1 when starting with ---, or >= 2 otherwise)
# and starts with '---', it's an error
#
# Logic:
# - If starts with '---' and has more than 1 separator -> multiple resources, error
# - If doesn't start with '---' and has 1+ separators -> multiple resources, ok
if [ "$starts_with_separator" = true ] && [ "$separator_count" -gt 1 ]; then
echo "ERROR: $file starts with '---' but contains multiple Kubernetes resources"
echo " Files with multiple resources should not start with '---'"
# We need to signal error but can't use EXIT_CODE in subshell
# So we output to a temp file
echo "1" > /tmp/yaml_lint_error
fi
done
# Check if any errors were found
if [ -f /tmp/yaml_lint_error ]; then
rm -f /tmp/yaml_lint_error
exit 1
fi
echo "YAML lint passed"
exit 0

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# This script will run a couple of linter on the documentation
set -eu
@@ -6,14 +6,17 @@ set -eu
# We want to run all linters before returning success (exit 0) or failure (exit 1)
# So this variable holds the global exit code
EXIT_CODE=0
readonly BASE_DIR=/app
readonly BASE_DIR="${1:-/app}"
# Run YAML linter for Kubernetes multi-resource files
./docs/scripts/lint-yaml.sh "${BASE_DIR}" || EXIT_CODE=1
echo "== Linting Markdown"
# Uses the file ".markdownlint.json" for setup
cd "${BASE_DIR}" || exit 1
LINTER_EXCLUSIONS="$(find "${BASE_DIR}/content" -type f -name '.markdownlint.json')"
GLOBAL_LINT_OPTIONS="--config ${BASE_DIR}/.markdownlint.json"
LINTER_EXCLUSIONS="$(find "content" -type f -name '.markdownlint.json')"
GLOBAL_LINT_OPTIONS="--config .markdownlint.json"
# Lint the specific folders (containing linter specific rulesets)
for LINTER_EXCLUSION in ${LINTER_EXCLUSIONS}
@@ -24,6 +27,6 @@ do
done
# Lint all the content, excluding the previously done`
eval markdownlint "${GLOBAL_LINT_OPTIONS}" "${BASE_DIR}/content/**/*.md" || EXIT_CODE=1
eval markdownlint "${GLOBAL_LINT_OPTIONS}" "content/**/*.md" || EXIT_CODE=1
exit "${EXIT_CODE}"

View File

@@ -2281,6 +2281,12 @@ spec:
items:
type: string
type: array
cipherSuites:
description: CipherSuites defines the cipher suites to use when contacting
backend servers.
items:
type: string
type: array
disableHTTP2:
description: DisableHTTP2 disables HTTP/2 for connections with backend
servers.
@@ -2341,6 +2347,14 @@ spec:
to keep per-host.
minimum: -1
type: integer
maxVersion:
description: MaxVersion defines the maximum TLS version to use when
contacting backend servers.
type: string
minVersion:
description: MinVersion defines the minimum TLS version to use when
contacting backend servers.
type: string
peerCertURI:
description: PeerCertURI defines the peer cert URI used to match against
SAN URI during the peer certificate verification.

View File

@@ -0,0 +1,12 @@
[entryPoints]
[entryPoints.web]
address = ":8000"
[entryPoints.web.forwardedHeaders]
insecure = true
notAppendXForwardedFor = true
[api]
insecure = true
[providers.file]
filename = "{{ .DynamicConfPath }}"

View File

@@ -0,0 +1,11 @@
[entryPoints]
[entryPoints.web]
address = ":8000"
[entryPoints.web.forwardedHeaders]
insecure = true
[api]
insecure = true
[providers.file]
filename = "{{ .DynamicConfPath }}"

View File

@@ -0,0 +1,16 @@
[entryPoints]
[entryPoints.web]
address = ":8000"
[entryPoints.web.forwardedHeaders]
insecure = true
notAppendXForwardedFor = true
[api]
insecure = true
[experimental]
[experimental.fastProxy]
debug = true
[providers.file]
filename = "{{ .DynamicConfPath }}"

View File

@@ -0,0 +1,15 @@
[entryPoints]
[entryPoints.web]
address = ":8000"
[entryPoints.web.forwardedHeaders]
insecure = true
[api]
insecure = true
[experimental]
[experimental.fastProxy]
debug = true
[providers.file]
filename = "{{ .DynamicConfPath }}"

View File

@@ -0,0 +1,10 @@
[http.routers]
[http.routers.router1]
entryPoints = ["web"]
rule = "PathPrefix(`/`)"
service = "service1"
[http.services]
[http.services.service1.loadBalancer]
[[http.services.service1.loadBalancer.servers]]
url = "{{ .Server }}"

View File

@@ -94,6 +94,197 @@ func (s *SimpleSuite) TestSimpleFastProxy() {
assert.GreaterOrEqual(s.T(), 1, callCount)
}
func (s *SimpleSuite) TestXForwardedForDisabled() {
srv1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// Echo back the X-Forwarded-For header
xff := req.Header.Get("X-Forwarded-For")
_, _ = rw.Write([]byte(xff))
}))
defer srv1.Close()
dynamicConf := s.adaptFile("resources/compose/x_forwarded_for.toml", struct {
Server string
}{
Server: srv1.URL,
})
staticConf := s.adaptFile("fixtures/x_forwarded_for.toml", struct {
DynamicConfPath string
}{
DynamicConfPath: dynamicConf,
})
s.traefikCmd(withConfigFile(staticConf))
// Wait for Traefik to start
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("service1"))
require.NoError(s.T(), err)
// Test with appendXForwardedFor = false
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
require.NoError(s.T(), err)
// Set an existing X-Forwarded-For header
req.Header.Set("X-Forwarded-For", "1.2.3.4")
resp, err := http.DefaultClient.Do(req)
require.NoError(s.T(), err)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
require.NoError(s.T(), err)
// The backend should receive the original X-Forwarded-For header unchanged
// (Traefik should NOT append RemoteAddr when appendXForwardedFor = false)
assert.Equal(s.T(), "1.2.3.4", string(body))
}
func (s *SimpleSuite) TestXForwardedForEnabled() {
srv1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// Echo back the X-Forwarded-For header
xff := req.Header.Get("X-Forwarded-For")
_, _ = rw.Write([]byte(xff))
}))
defer srv1.Close()
dynamicConf := s.adaptFile("resources/compose/x_forwarded_for.toml", struct {
Server string
}{
Server: srv1.URL,
})
// Use a config with appendXForwardedFor = true
staticConf := s.adaptFile("fixtures/x_forwarded_for_enabled.toml", struct {
DynamicConfPath string
}{
DynamicConfPath: dynamicConf,
})
s.traefikCmd(withConfigFile(staticConf))
// Wait for Traefik to start
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("service1"))
require.NoError(s.T(), err)
// Test with default appendXForwardedFor = true
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
require.NoError(s.T(), err)
// Set an existing X-Forwarded-For header
req.Header.Set("X-Forwarded-For", "1.2.3.4")
resp, err := http.DefaultClient.Do(req)
require.NoError(s.T(), err)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
require.NoError(s.T(), err)
// The backend should receive the X-Forwarded-For header with RemoteAddr appended
// (should be "1.2.3.4, 127.0.0.1" since the request comes from localhost)
assert.Contains(s.T(), string(body), "1.2.3.4,")
assert.Contains(s.T(), string(body), "127.0.0.1")
}
func (s *SimpleSuite) TestXForwardedForDisabledFastProxy() {
srv1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// Verify FastProxy is being used
assert.Contains(s.T(), req.Header, "X-Traefik-Fast-Proxy")
// Echo back the X-Forwarded-For header
xff := req.Header.Get("X-Forwarded-For")
_, _ = rw.Write([]byte(xff))
}))
defer srv1.Close()
dynamicConf := s.adaptFile("resources/compose/x_forwarded_for.toml", struct {
Server string
}{
Server: srv1.URL,
})
staticConf := s.adaptFile("fixtures/x_forwarded_for_fastproxy.toml", struct {
DynamicConfPath string
}{
DynamicConfPath: dynamicConf,
})
s.traefikCmd(withConfigFile(staticConf))
// Wait for Traefik to start
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("service1"))
require.NoError(s.T(), err)
// Test with appendXForwardedFor = false
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
require.NoError(s.T(), err)
// Set an existing X-Forwarded-For header
req.Header.Set("X-Forwarded-For", "1.2.3.4")
resp, err := http.DefaultClient.Do(req)
require.NoError(s.T(), err)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
require.NoError(s.T(), err)
// The backend should receive the original X-Forwarded-For header unchanged
// (FastProxy should NOT append RemoteAddr when notAppendXForwardedFor = true)
assert.Equal(s.T(), "1.2.3.4", string(body))
}
func (s *SimpleSuite) TestXForwardedForEnabledFastProxy() {
srv1 := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// Verify FastProxy is being used
assert.Contains(s.T(), req.Header, "X-Traefik-Fast-Proxy")
// Echo back the X-Forwarded-For header
xff := req.Header.Get("X-Forwarded-For")
_, _ = rw.Write([]byte(xff))
}))
defer srv1.Close()
dynamicConf := s.adaptFile("resources/compose/x_forwarded_for.toml", struct {
Server string
}{
Server: srv1.URL,
})
// Use a config with appendXForwardedFor = false (default)
staticConf := s.adaptFile("fixtures/x_forwarded_for_fastproxy_enabled.toml", struct {
DynamicConfPath string
}{
DynamicConfPath: dynamicConf,
})
s.traefikCmd(withConfigFile(staticConf))
// Wait for Traefik to start
err := try.GetRequest("http://127.0.0.1:8080/api/rawdata", 10*time.Second, try.BodyContains("service1"))
require.NoError(s.T(), err)
// Test with default appendXForwardedFor = true
req, err := http.NewRequest(http.MethodGet, "http://127.0.0.1:8000/", nil)
require.NoError(s.T(), err)
// Set an existing X-Forwarded-For header
req.Header.Set("X-Forwarded-For", "1.2.3.4")
resp, err := http.DefaultClient.Do(req)
require.NoError(s.T(), err)
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
require.NoError(s.T(), err)
// The backend should receive the X-Forwarded-For header with RemoteAddr appended
// (FastProxy should append RemoteAddr when notAppendXForwardedFor = false)
// (should be "1.2.3.4, 127.0.0.1" since the request comes from localhost)
assert.Contains(s.T(), string(body), "1.2.3.4,")
assert.Contains(s.T(), string(body), "127.0.0.1")
}
func (s *SimpleSuite) TestWithWebConfig() {
s.cmdTraefik(withConfigFile("fixtures/simple_web.toml"))

View File

@@ -79,7 +79,13 @@ func Append(router *mux.Router, basePath string, customAssets fs.FS) error {
router.Methods(http.MethodGet).
Path(basePath).
HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
prefix := strings.TrimSuffix(req.Header.Get("X-Forwarded-Prefix"), "/")
xfPrefix := req.Header.Get("X-Forwarded-Prefix")
if strings.Contains(xfPrefix, "//") {
log.Error().Msgf("X-Forwarded-Prefix contains an invalid value: %s, defaulting to empty prefix", xfPrefix)
xfPrefix = ""
}
prefix := strings.TrimSuffix(xfPrefix, "/")
http.Redirect(resp, req, prefix+dashboardPath, http.StatusFound)
})

View File

@@ -9,7 +9,9 @@ import (
"testing/fstest"
"time"
"github.com/gorilla/mux"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func Test_ContentSecurityPolicy(t *testing.T) {
@@ -60,6 +62,52 @@ func Test_ContentSecurityPolicy(t *testing.T) {
}
}
func Test_XForwardedPrefix(t *testing.T) {
testCases := []struct {
desc string
prefix string
expected string
}{
{
desc: "location in X-Forwarded-Prefix",
prefix: "//foobar/test",
expected: "/dashboard/",
},
{
desc: "scheme in X-Forwarded-Prefix",
prefix: "http://foobar",
expected: "/dashboard/",
},
{
desc: "path in X-Forwarded-Prefix",
prefix: "foobar",
expected: "/foobar/dashboard/",
},
}
router := mux.NewRouter()
err := Append(router, "/", fstest.MapFS{"index.html": &fstest.MapFile{
Mode: 0o755,
ModTime: time.Now(),
}})
require.NoError(t, err)
for _, test := range testCases {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
req := httptest.NewRequest(http.MethodGet, "/", http.NoBody)
req.Header.Set("X-Forwarded-Prefix", test.prefix)
rw := httptest.NewRecorder()
router.ServeHTTP(rw, req)
assert.Equal(t, http.StatusFound, rw.Code)
assert.Equal(t, test.expected, rw.Result().Header.Get("Location"))
})
}
}
type errorFS struct{}
func (e errorFS) Open(name string) (fs.File, error) {

View File

@@ -449,6 +449,9 @@ type ServersTransport struct {
InsecureSkipVerify bool `description:"Disables SSL certificate verification." json:"insecureSkipVerify,omitempty" toml:"insecureSkipVerify,omitempty" yaml:"insecureSkipVerify,omitempty" export:"true"`
RootCAs []types.FileOrContent `description:"Defines a list of CA certificates used to validate server certificates." json:"rootCAs,omitempty" toml:"rootCAs,omitempty" yaml:"rootCAs,omitempty"`
Certificates traefiktls.Certificates `description:"Defines a list of client certificates for mTLS." json:"certificates,omitempty" toml:"certificates,omitempty" yaml:"certificates,omitempty" export:"true"`
CipherSuites []string `description:"Defines the cipher suites to use when contacting backend servers." json:"cipherSuites,omitempty" toml:"cipherSuites,omitempty" yaml:"cipherSuites,omitempty" export:"true"`
MinVersion string `description:"Defines the minimum TLS version to use when contacting backend servers." json:"minVersion,omitempty" toml:"minVersion,omitempty" yaml:"minVersion,omitempty" export:"true"`
MaxVersion string `description:"Defines the maximum TLS version to use when contacting backend servers." json:"maxVersion,omitempty" toml:"maxVersion,omitempty" yaml:"maxVersion,omitempty" export:"true"`
MaxIdleConnsPerHost int `description:"If non-zero, controls the maximum idle (keep-alive) to keep per-host. If zero, DefaultMaxIdleConnsPerHost is used. If negative, disables connection reuse." json:"maxIdleConnsPerHost,omitempty" toml:"maxIdleConnsPerHost,omitempty" yaml:"maxIdleConnsPerHost,omitempty" export:"true"`
ForwardingTimeouts *ForwardingTimeouts `description:"Defines the timeouts for requests forwarded to the backend servers." json:"forwardingTimeouts,omitempty" toml:"forwardingTimeouts,omitempty" yaml:"forwardingTimeouts,omitempty" export:"true"`
DisableHTTP2 bool `description:"Disables HTTP/2 for connections with backend servers." json:"disableHTTP2,omitempty" toml:"disableHTTP2,omitempty" yaml:"disableHTTP2,omitempty" export:"true"`

View File

@@ -4,7 +4,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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
@@ -1611,6 +1611,11 @@ func (in *ServersTransport) DeepCopyInto(out *ServersTransport) {
*out = make(tls.Certificates, len(*in))
copy(*out, *in)
}
if in.CipherSuites != nil {
in, out := &in.CipherSuites, &out.CipherSuites
*out = make([]string, len(*in))
copy(*out, *in)
}
if in.ForwardingTimeouts != nil {
in, out := &in.ForwardingTimeouts, &out.ForwardingTimeouts
*out = new(ForwardingTimeouts)

View File

@@ -140,9 +140,10 @@ type TLSConfig struct {
// ForwardedHeaders Trust client forwarding headers.
type ForwardedHeaders struct {
Insecure bool `description:"Trust all forwarded headers." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"`
TrustedIPs []string `description:"Trust only forwarded headers from selected IPs." json:"trustedIPs,omitempty" toml:"trustedIPs,omitempty" yaml:"trustedIPs,omitempty"`
Connection []string `description:"List of Connection headers that are allowed to pass through the middleware chain before being removed." json:"connection,omitempty" toml:"connection,omitempty" yaml:"connection,omitempty"`
Insecure bool `description:"Trust all forwarded headers." json:"insecure,omitempty" toml:"insecure,omitempty" yaml:"insecure,omitempty" export:"true"`
TrustedIPs []string `description:"Trust only forwarded headers from selected IPs." json:"trustedIPs,omitempty" toml:"trustedIPs,omitempty" yaml:"trustedIPs,omitempty"`
Connection []string `description:"List of Connection headers that are allowed to pass through the middleware chain before being removed." json:"connection,omitempty" toml:"connection,omitempty" yaml:"connection,omitempty"`
NotAppendXForwardedFor bool `description:"Disable appending RemoteAddr to X-Forwarded-For header. Defaults to false (appending is enabled)." json:"notAppendXForwardedFor,omitempty" toml:"notAppendXForwardedFor,omitempty" yaml:"notAppendXForwardedFor,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
}
// ProxyProtocol contains Proxy-Protocol configuration.

View File

@@ -112,8 +112,9 @@ type CertificateResolver struct {
// Global holds the global configuration.
type Global struct {
CheckNewVersion bool `description:"Periodically check if a new version has been released." json:"checkNewVersion,omitempty" toml:"checkNewVersion,omitempty" yaml:"checkNewVersion,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
SendAnonymousUsage bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
CheckNewVersion bool `description:"Periodically check if a new version has been released." json:"checkNewVersion,omitempty" toml:"checkNewVersion,omitempty" yaml:"checkNewVersion,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
SendAnonymousUsage bool `description:"Periodically send anonymous usage statistics. If the option is not specified, it will be disabled by default." json:"sendAnonymousUsage,omitempty" toml:"sendAnonymousUsage,omitempty" yaml:"sendAnonymousUsage,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
NotAppendXForwardedFor bool `description:"Disable appending RemoteAddr to X-Forwarded-For header. Defaults to false (appending is enabled)." json:"notAppendXForwardedFor,omitempty" toml:"notAppendXForwardedFor,omitempty" yaml:"notAppendXForwardedFor,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
}
// ServersTransport options to configure communication between Traefik and the servers.
@@ -158,6 +159,7 @@ type API struct {
Dashboard bool `description:"Activate dashboard." json:"dashboard,omitempty" toml:"dashboard,omitempty" yaml:"dashboard,omitempty" export:"true"`
Debug bool `description:"Enable additional endpoints for debugging and profiling." json:"debug,omitempty" toml:"debug,omitempty" yaml:"debug,omitempty" export:"true"`
DisableDashboardAd bool `description:"Disable ad in the dashboard." json:"disableDashboardAd,omitempty" toml:"disableDashboardAd,omitempty" yaml:"disableDashboardAd,omitempty" export:"true"`
DashboardName string `description:"Custom name for the dashboard." json:"dashboardName,omitempty" toml:"dashboardName,omitempty" yaml:"dashboardName,omitempty" export:"true"`
// TODO: Re-enable statistics
// Statistics *types.Statistics `description:"Enable more detailed statistics." json:"statistics,omitempty" toml:"statistics,omitempty" yaml:"statistics,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
}
@@ -166,6 +168,7 @@ type API struct {
func (a *API) SetDefaults() {
a.BasePath = "/"
a.Dashboard = true
a.DashboardName = ""
}
// RespondingTimeouts contains timeout configurations for incoming requests to the Traefik instance.
@@ -314,6 +317,18 @@ func (c *Configuration) SetEffectiveConfiguration() {
c.Providers.KubernetesGateway.EntryPoints = entryPoints
}
// Configure Ingress NGINX provider.
if c.Providers.KubernetesIngressNGINX != nil {
var nonTLSEntryPoints []string
for epName, entryPoint := range c.EntryPoints {
if entryPoint.HTTP.TLS == nil {
nonTLSEntryPoints = append(nonTLSEntryPoints, epName)
}
}
c.Providers.KubernetesIngressNGINX.NonTLSEntryPoints = nonTLSEntryPoints
}
// Defines the default rule syntax for the Kubernetes Ingress Provider.
// This allows the provider to adapt the matcher syntax to the desired rule syntax version.
if c.Core != nil && c.Providers.KubernetesIngress != nil {

View File

@@ -9,6 +9,7 @@ import (
"strings"
"github.com/traefik/traefik/v3/pkg/ip"
"github.com/traefik/traefik/v3/pkg/proxy/httputil"
"golang.org/x/net/http/httpguts"
)
@@ -47,16 +48,17 @@ var xHeaders = []string{
// Unless insecure is set,
// it first removes all the existing values for those headers if the remote address is not one of the trusted ones.
type XForwarded struct {
insecure bool
trustedIPs []string
connectionHeaders []string
ipChecker *ip.Checker
next http.Handler
hostname string
insecure bool
trustedIPs []string
connectionHeaders []string
notAppendXForwardedFor bool
ipChecker *ip.Checker
next http.Handler
hostname string
}
// NewXForwarded creates a new XForwarded.
func NewXForwarded(insecure bool, trustedIPs []string, connectionHeaders []string, next http.Handler) (*XForwarded, error) {
func NewXForwarded(insecure bool, trustedIPs []string, connectionHeaders []string, notAppendXForwardedFor bool, next http.Handler) (*XForwarded, error) {
var ipChecker *ip.Checker
if len(trustedIPs) > 0 {
var err error
@@ -72,12 +74,13 @@ func NewXForwarded(insecure bool, trustedIPs []string, connectionHeaders []strin
}
return &XForwarded{
insecure: insecure,
trustedIPs: trustedIPs,
connectionHeaders: connectionHeaders,
ipChecker: ipChecker,
next: next,
hostname: hostname,
insecure: insecure,
trustedIPs: trustedIPs,
connectionHeaders: connectionHeaders,
notAppendXForwardedFor: notAppendXForwardedFor,
ipChecker: ipChecker,
next: next,
hostname: hostname,
}, nil
}
@@ -198,6 +201,10 @@ func (x *XForwarded) ServeHTTP(w http.ResponseWriter, r *http.Request) {
x.removeConnectionHeaders(r)
if x.notAppendXForwardedFor {
r = r.WithContext(httputil.SetNotAppendXFF(r.Context()))
}
x.next.ServeHTTP(w, r)
}

View File

@@ -516,7 +516,7 @@ func TestServeHTTP(t *testing.T) {
}
}
m, err := NewXForwarded(test.insecure, test.trustedIps, test.connectionHeaders,
m, err := NewXForwarded(test.insecure, test.trustedIps, test.connectionHeaders, false,
http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {}))
require.NoError(t, err)
@@ -655,7 +655,7 @@ func TestConnection(t *testing.T) {
t.Run(test.desc, func(t *testing.T) {
t.Parallel()
forwarded, err := NewXForwarded(true, nil, test.connectionHeaders, nil)
forwarded, err := NewXForwarded(true, nil, test.connectionHeaders, false, nil)
require.NoError(t, err)
req := httptest.NewRequest(http.MethodGet, "https://localhost", nil)

View File

@@ -55,6 +55,7 @@ type Configuration struct {
ClientTimeout ptypes.Duration `description:"Timeout for a complete HTTP transaction with the ACME server." json:"clientTimeout,omitempty" toml:"clientTimeout,omitempty" yaml:"clientTimeout,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
ClientResponseHeaderTimeout ptypes.Duration `description:"Timeout for receiving the response headers when communicating with the ACME server." json:"clientResponseHeaderTimeout,omitempty" toml:"clientResponseHeaderTimeout,omitempty" yaml:"clientResponseHeaderTimeout,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
CertificateTimeout ptypes.Duration `description:"Timeout for obtaining the certificate during the finalization request." json:"certificateTimeout,omitempty" toml:"certificateTimeout,omitempty" yaml:"certificateTimeout,omitempty" label:"allowEmpty" file:"allowEmpty" export:"true"`
CACertificates []string `description:"Specify the paths to PEM encoded CA Certificates that can be used to authenticate an ACME server with an HTTPS certificate not issued by a CA in the system-wide trusted root list." json:"caCertificates,omitempty" toml:"caCertificates,omitempty" yaml:"caCertificates,omitempty"`
CASystemCertPool bool `description:"Define if the certificates pool must use a copy of the system cert pool." json:"caSystemCertPool,omitempty" toml:"caSystemCertPool,omitempty" yaml:"caSystemCertPool,omitempty" export:"true"`
@@ -73,6 +74,7 @@ func (a *Configuration) SetDefaults() {
a.CertificatesDuration = 3 * 30 * 24 // 90 Days
a.ClientTimeout = ptypes.Duration(2 * time.Minute)
a.ClientResponseHeaderTimeout = ptypes.Duration(30 * time.Second)
a.CertificateTimeout = ptypes.Duration(30 * time.Second)
}
// CertAndStore allows mapping a TLS certificate to a TLS store.
@@ -298,6 +300,7 @@ func (p *Provider) getClient() (*lego.Client, error) {
config.Certificate.KeyType = GetKeyType(ctx, p.KeyType)
config.UserAgent = fmt.Sprintf("containous-traefik/%s", version.Version)
config.Certificate.DisableCommonName = p.DisableCommonName
config.Certificate.Timeout = time.Duration(p.CertificateTimeout)
config.HTTPClient, err = p.createHTTPClient()
if err != nil {
@@ -921,11 +924,11 @@ func (p *Provider) renewCertificates(ctx context.Context, renewPeriod time.Durat
for _, cert := range certificates {
client, err := p.getClient()
if err != nil {
logger.Info().Err(err).Msgf("Error renewing certificate from LE : %+v", cert.Domain)
logger.Info().Err(err).Msgf("Error renewing ACME certificate: %+v", cert.Domain)
continue
}
logger.Info().Msgf("Renewing certificate from LE : %+v", cert.Domain)
logger.Info().Msgf("Renewing ACME certificate: %+v", cert.Domain)
res := certificate.Resource{
Domain: cert.Domain.Main,
@@ -935,12 +938,14 @@ func (p *Provider) renewCertificates(ctx context.Context, renewPeriod time.Durat
opts := &certificate.RenewOptions{
Bundle: true,
EmailAddresses: p.EmailAddresses,
Profile: p.Profile,
PreferredChain: p.PreferredChain,
}
renewedCert, err := client.Certificate.RenewWithOptions(res, opts)
if err != nil {
logger.Error().Err(err).Msgf("Error renewing certificate from LE: %v", cert.Domain)
logger.Error().Err(err).Msgf("Error renewing ACME certificate: %v", cert.Domain)
continue
}

View File

@@ -169,6 +169,11 @@ spec:
- spiffe://foo/buz
- spiffe://bar/biz
trustDomain: spiffe://lol
cipherSuites:
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
minVersion: VersionTLS11
maxVersion: VersionTLS12
---
apiVersion: traefik.io/v1alpha1

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

View File

@@ -1,7 +1,7 @@
/*
The MIT License (MIT)
Copyright (c) 2016-2020 Containous SAS; 2020-2025 Traefik Labs
Copyright (c) 2016-2020 Containous SAS; 2020-2026 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

Some files were not shown because too many files have changed in this diff Show More