Revamp docs and add Traefik Basic Auth guide

This commit is contained in:
2026-01-14 14:00:13 +01:00
parent 6eca87bfa9
commit 2237a6fb95
2 changed files with 747 additions and 776 deletions

1085
README.md

File diff suppressed because it is too large Load Diff

430
TRAEFIK_BASIC_AUTH.md Normal file
View File

@@ -0,0 +1,430 @@
# Traefik Basic Authentication for Dashboard and API
## Overview
This guide explains how to enable basic authentication for the Traefik dashboard (`/dashboard`) and API (`/api`) endpoints in your Helm-deployed Traefik instance.
## Prerequisites
- Traefik deployed via Helm with IngressRoute enabled
- `htpasswd` utility (usually comes with Apache utilities)
- `kubectl` configured and access to your cluster
## Step 1: Generate Credentials
### Option 1: Using htpasswd (Recommended)
Generate a hashed password for your basic auth user:
```bash
# Install htpasswd if not already installed
# macOS:
brew install httpd
# Linux:
sudo apt-get install apache2-utils
# Create credentials file (replace 'admin' with your desired username)
htpasswd -c auth admin
# You'll be prompted to enter a password
# View the generated credentials
cat auth
# Output example: admin:$apr1$H6uskkkW$FTbVJriq9dMj0O/3YbCzC0
```
### Option 2: Using Python
```bash
python3 << 'EOF'
import bcrypt
import base64
username = "admin"
password = "your_secure_password"
# Hash password using bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
# Format for htpasswd
htpasswd_line = f"{username}:{hashed.decode()}"
print(htpasswd_line)
EOF
```
## Step 2: Create Kubernetes Secret
Once you have the credentials, create a Kubernetes Secret:
```bash
# Using the auth file from htpasswd
kubectl create secret generic traefik-basic-auth \
--from-file=users=auth \
-n traefik
```
Or create it directly without a file:
```bash
# Replace 'admin' and hashed_password with your actual values
kubectl create secret generic traefik-basic-auth \
--from-literal=users='admin:$apr1$H6uskkkW$FTbVJriq9dMj0O/3YbCzC0' \
-n traefik
```
### Verify Secret Creation
```bash
kubectl get secret traefik-basic-auth -n traefik
kubectl get secret traefik-basic-auth -n traefik -o yaml
```
## Step 3: Create BasicAuth Middleware
Create a Traefik BasicAuth middleware that references the secret:
```yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: traefik-basic-auth
namespace: kube-system
spec:
basicAuth:
secret: traefik-basic-auth
removeHeader: true # Remove Authorization header after auth
headerField: Authorization # Standard HTTP auth header
```
Save this to a file and apply it:
```bash
kubectl apply -f - <<'EOF'
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: traefik-basic-auth
namespace: traefik
spec:
basicAuth:
secret: traefik-basic-auth
removeHeader: true
EOF
```
## Step 4: Update IngressRoute with Middleware
Now update your Traefik IngressRoute to use the BasicAuth middleware:
```yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- traefik
routes:
- match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
kind: Rule
services:
- kind: TraefikService
name: api@internal
middlewares:
- name: traefik-basic-auth
namespace: traefik
tls: {}
```
### Apply Updated IngressRoute
```bash
kubectl apply -f - <<'EOF'
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: traefik
spec:
entryPoints:
- traefik
routes:
- match: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
kind: Rule
services:
- kind: TraefikService
name: api@internal
middlewares:
- name: traefik-basic-auth
namespace: kube-system
tls: {}
EOF
```
## Step 5: Test Basic Auth
### Test Dashboard Access
```bash
# Port-forward to Traefik
kubectl port-forward -n traefik svc/traefik 8080:8080 &
# Test without credentials (should fail with 401)
curl -i http://localhost:8080/dashboard/
# Output: HTTP/1.1 401 Unauthorized
# Test with correct credentials
curl -i -u admin:your_password http://localhost:8080/dashboard/
# Output: HTTP/1.1 200 OK
# Test with wrong credentials (should fail)
curl -i -u admin:wrong_password http://localhost:8080/dashboard/
# Output: HTTP/1.1 401 Unauthorized
```
### Test API Access
```bash
# Without auth
curl http://localhost:8080/api/http/routers
# With auth
curl -u admin:your_password http://localhost:8080/api/http/routers
```
## Using with Helm Chart Values
If you want to configure this permanently via Helm, add to your values.yaml:
```yaml
ingressRoute:
dashboard:
enabled: true
entryPoints:
- traefik
matchRule: PathPrefix(`/dashboard`) || PathPrefix(`/api`)
middlewares:
- name: traefik-basic-auth
namespace: traefik
services:
- kind: TraefikService
name: api@internal
tls: {}
# Create BasicAuth middleware as an extra object
extraObjects:
- apiVersion: v1
kind: Secret
metadata:
name: traefik-basic-auth
namespace: traefik
type: Opaque
stringData:
users: |
admin:$apr1$H6uskkkW$FTbVJriq9dMj0O/3YbCzC0
- apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: traefik-basic-auth
namespace: traefik
spec:
basicAuth:
secret: traefik-basic-auth
removeHeader: true
```
Then update via Helm:
```bash
helm upgrade traefik traefik/traefik \
-n traefik \
-f values.yaml
```
## Multiple Users
To add multiple users to the basic auth secret:
```bash
# Create auth file with multiple users
htpasswd -c auth admin
htpasswd -B auth user2
htpasswd -B auth user3
# View the file
cat auth
# Output:
# admin:$apr1$H6uskkkW$FTbVJriq9dMj0O/3YbCzC0
# user2:$2y$05$...
# user3:$2y$05$...
# Create secret
kubectl create secret generic traefik-basic-auth \
--from-file=users=auth \
-n traefik \
-o yaml --dry-run=client | kubectl apply -f -
```
## Rotate Credentials
To update credentials without recreating the middleware:
```bash
# Delete old secret
kubectl delete secret traefik-basic-auth -n traefik
# Create new secret with updated credentials
htpasswd -c auth admin # Enter new password
kubectl create secret generic traefik-basic-auth \
--from-file=users=auth \
-n kube-system
```
Traefik will automatically reload the secret without needing a pod restart.
## Security Best Practices
1. **Use Strong Passwords**: Generate strong random passwords
```bash
openssl rand -base64 16
# Generate: dRw3k8F9P2mL7qX1nV4bZ6
```
2. **Use HTTPS/TLS**: Configure TLS for the dashboard in production
```yaml
tls:
secretName: traefik-tls # Your TLS certificate secret
```
3. **Restrict Access**: Use IP-based access restrictions
```yaml
middlewares:
- name: traefik-basic-auth
namespace: kube-system
- name: ip-whitelist
namespace: kube-system
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: ip-whitelist
namespace: kube-system
spec:
ipWhiteList:
sourceRange:
- 192.168.1.0/24 # Your IP range
```
4. **Rotate Credentials Regularly**: Update passwords every 90 days
5. **Use Network Policies**: Restrict access to Traefik API port
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: traefik-api-restrict
namespace: kube-system
spec:
podSelector:
matchLabels:
app.kubernetes.io/name: traefik
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: kube-system
ports:
- protocol: TCP
port: 8080
```
## Troubleshooting
### Secret not found error
```
Error: secret "traefik-basic-auth" not found
```
**Solution:**
```bash
# Verify secret exists in correct namespace
kubectl get secret traefik-basic-auth -n kube-system
# If missing, recreate it
kubectl create secret generic traefik-basic-auth \
--from-file=users=auth \
-n traefik
```
### 401 Unauthorized even with correct credentials
**Possible causes:**
- Secret format is wrong
- Middleware not applied to IngressRoute
- Password hash algorithm mismatch
**Debug:**
```bash
# Check secret content
kubectl get secret traefik-basic-auth -n traefik -o yaml
# Check IngressRoute
kubectl get ingressroute traefik-dashboard -n traefik -o yaml
# Check Traefik logs
kubectl logs -n traefik -l app.kubernetes.io/name=traefik -f | grep -i auth
```
### Htpasswd format issues
Valid formats:
- **APR1**: `$apr1$...` (from `htpasswd -b`)
- **Bcrypt**: `$2y$...` (from `htpasswd -B`)
- **SHA**: `{SHA}...` (from `htpasswd -s`)
Use APR1 or Bcrypt for best compatibility.
## Quick Reference Commands
```bash
# Generate credentials
htpasswd -c auth admin
# Create secret
kubectl create secret generic traefik-basic-auth --from-file=users=auth -n traefik
# Create middleware
kubectl apply -f - <<'EOF'
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: traefik-basic-auth
namespace: traefik
spec:
basicAuth:
secret: traefik-basic-auth
removeHeader: true
EOF
# Update IngressRoute
kubectl patch ingressroute traefik-dashboard -n traefik --type merge \
-p '{"spec":{"routes":[{"middlewares":[{"name":"traefik-basic-auth","namespace":"traefik"}]}]}}'
# Test access
curl -u admin:password http://localhost:8080/dashboard/
# Verify middleware is applied
kubectl get middleware -n traefik
kubectl describe middleware traefik-basic-auth -n traefik
```
## References
- [Traefik BasicAuth Middleware](https://doc.traefik.io/traefik/middlewares/http/basicauth/)
- [Traefik Helm Chart](https://github.com/traefik/traefik-helm-chart)
- [Kubernetes Secrets Documentation](https://kubernetes.io/docs/concepts/configuration/secret/)