ginskill-init 2.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.wrangler/cache/pages.json +4 -0
- package/.wrangler/cache/wrangler-account.json +6 -0
- package/DEVELOPMENT.md +510 -0
- package/README.md +104 -0
- package/agents/developer.md +56 -0
- package/agents/frontend-design.md +69 -0
- package/agents/mobile-reviewer.md +36 -0
- package/agents/review-code.md +49 -0
- package/agents/security-scanner.md +50 -0
- package/agents/tester.md +72 -0
- package/bin/cli.js +461 -0
- package/landing/ai-build-ai.png +0 -0
- package/landing/index.html +1495 -0
- package/landing/logo.png +0 -0
- package/package.json +37 -0
- package/skills/active-life-dev/SKILL.md +157 -0
- package/skills/active-life-dev/docs/auth.md +187 -0
- package/skills/active-life-dev/docs/customers.md +216 -0
- package/skills/active-life-dev/docs/integrations.md +209 -0
- package/skills/active-life-dev/docs/inventory.md +192 -0
- package/skills/active-life-dev/docs/modules.md +181 -0
- package/skills/active-life-dev/docs/orders.md +180 -0
- package/skills/active-life-dev/docs/patterns.md +319 -0
- package/skills/active-life-dev/docs/products.md +216 -0
- package/skills/active-life-dev/docs/schema.md +502 -0
- package/skills/active-life-dev/docs/setup.md +169 -0
- package/skills/active-life-dev/docs/vouchers.md +144 -0
- package/skills/ai-asset-generator/SKILL.md +247 -0
- package/skills/ai-asset-generator/docs/gen-image.md +274 -0
- package/skills/ai-asset-generator/docs/genvideo.md +341 -0
- package/skills/ai-asset-generator/docs/remove-background.md +19 -0
- package/skills/ai-asset-generator/lib/bg-remove.mjs +34 -0
- package/skills/ai-asset-generator/lib/env.mjs +48 -0
- package/skills/ai-asset-generator/lib/kie-client.mjs +100 -0
- package/skills/ai-build-ai/SKILL.md +127 -0
- package/skills/ai-build-ai/docs/agent-teams.md +293 -0
- package/skills/ai-build-ai/docs/checkpointing.md +161 -0
- package/skills/ai-build-ai/docs/create-agent.md +399 -0
- package/skills/ai-build-ai/docs/create-mcp.md +395 -0
- package/skills/ai-build-ai/docs/create-skill.md +299 -0
- package/skills/ai-build-ai/docs/headless-mode.md +614 -0
- package/skills/ai-build-ai/docs/hooks.md +578 -0
- package/skills/ai-build-ai/docs/memory-claude-md.md +375 -0
- package/skills/ai-build-ai/docs/output-styles.md +208 -0
- package/skills/ai-build-ai/docs/overview.md +162 -0
- package/skills/ai-build-ai/docs/permissions.md +391 -0
- package/skills/ai-build-ai/docs/plugins.md +396 -0
- package/skills/ai-build-ai/docs/sandbox.md +262 -0
- package/skills/ai-build-ai/docs/team-lead-workflow.md +648 -0
- package/skills/ant-design/SKILL.md +323 -0
- package/skills/ant-design/docs/components.md +160 -0
- package/skills/ant-design/docs/data-entry.md +406 -0
- package/skills/ant-design/docs/display.md +594 -0
- package/skills/ant-design/docs/feedback.md +451 -0
- package/skills/ant-design/docs/key-components.md +414 -0
- package/skills/ant-design/docs/navigation.md +310 -0
- package/skills/ant-design/docs/pro-components.md +543 -0
- package/skills/ant-design/docs/setup.md +213 -0
- package/skills/ant-design/docs/theme.md +265 -0
- package/skills/flutter-performance/SKILL.md +803 -0
- package/skills/flutter-performance/references/flutter-patterns.md +595 -0
- package/skills/icon-generator/SKILL.md +270 -0
- package/skills/mobile-app-review/SKILL.md +321 -0
- package/skills/mobile-app-review/references/apple-review.md +132 -0
- package/skills/mobile-app-review/references/google-play-review.md +203 -0
- package/skills/mongodb/SKILL.md +667 -0
- package/skills/mongodb/references/mongoose-patterns.md +368 -0
- package/skills/nestjs-architecture/SKILL.md +1086 -0
- package/skills/nestjs-architecture/references/advanced-patterns.md +590 -0
- package/skills/performance/SKILL.md +509 -0
- package/skills/react-fsd-architecture/SKILL.md +693 -0
- package/skills/react-fsd-architecture/references/fsd-patterns.md +747 -0
- package/skills/react-native-expo/SKILL.md +128 -0
- package/skills/react-native-expo/references/data-layer.md +252 -0
- package/skills/react-native-expo/references/design-system.md +252 -0
- package/skills/react-native-expo/references/navigation.md +199 -0
- package/skills/react-native-expo/references/performance.md +229 -0
- package/skills/react-native-expo/references/platform-services.md +179 -0
- package/skills/react-native-expo/references/state-management.md +209 -0
- package/skills/react-native-expo/references/ui-patterns.md +301 -0
- package/skills/react-query/SKILL.md +685 -0
- package/skills/react-query/references/query-patterns.md +365 -0
- package/skills/review-code/SKILL.md +374 -0
- package/skills/review-code/references/clean-code-principles.md +395 -0
- package/skills/review-code/references/frontend-patterns.md +136 -0
- package/skills/review-code/references/nestjs-patterns.md +184 -0
- package/skills/security-scanner/SKILL.md +366 -0
- package/skills/security-scanner/references/nestjs-security.md +260 -0
- package/skills/security-scanner/references/nextjs-security.md +201 -0
- package/skills/security-scanner/references/react-native-security.md +199 -0
- package/skills/traefik/SKILL.md +105 -0
- package/skills/traefik/docs/advanced-routing.md +186 -0
- package/skills/traefik/docs/auth-providers.md +137 -0
- package/skills/traefik/docs/cicd-devops.md +396 -0
- package/skills/traefik/docs/core-config.md +171 -0
- package/skills/traefik/docs/distributed-config.md +96 -0
- package/skills/traefik/docs/docker-compose.md +182 -0
- package/skills/traefik/docs/ha-performance.md +177 -0
- package/skills/traefik/docs/kubernetes.md +278 -0
- package/skills/traefik/docs/middleware.md +205 -0
- package/skills/traefik/docs/monitoring.md +357 -0
- package/skills/traefik/docs/security.md +391 -0
- package/skills/traefik/docs/tls-acme.md +155 -0
- package/skills/ui-ux-pro-max/SKILL.md +377 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# Traefik Security Hardening
|
|
2
|
+
|
|
3
|
+
## Security Headers (apply globally)
|
|
4
|
+
|
|
5
|
+
```yaml
|
|
6
|
+
http:
|
|
7
|
+
middlewares:
|
|
8
|
+
security-headers:
|
|
9
|
+
headers:
|
|
10
|
+
# XSS Protection
|
|
11
|
+
browserXssFilter: true
|
|
12
|
+
# Prevent MIME sniffing
|
|
13
|
+
contentTypeNosniff: true
|
|
14
|
+
# Clickjacking protection
|
|
15
|
+
frameDeny: true
|
|
16
|
+
customFrameOptionsValue: "SAMEORIGIN"
|
|
17
|
+
# HSTS
|
|
18
|
+
stsSeconds: 31536000
|
|
19
|
+
stsIncludeSubdomains: true
|
|
20
|
+
stsPreload: true
|
|
21
|
+
forceSTSHeader: true
|
|
22
|
+
# CSP
|
|
23
|
+
contentSecurityPolicy: "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'"
|
|
24
|
+
# Referrer
|
|
25
|
+
referrerPolicy: "strict-origin-when-cross-origin"
|
|
26
|
+
# Permissions
|
|
27
|
+
permissionsPolicy: "camera=(), microphone=(), geolocation=(), payment=()"
|
|
28
|
+
# Remove server info
|
|
29
|
+
customResponseHeaders:
|
|
30
|
+
server: ""
|
|
31
|
+
X-Powered-By: ""
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## TLS Hardening
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
tls:
|
|
38
|
+
options:
|
|
39
|
+
default:
|
|
40
|
+
minVersion: VersionTLS12
|
|
41
|
+
sniStrict: true
|
|
42
|
+
cipherSuites:
|
|
43
|
+
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
|
44
|
+
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
45
|
+
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
|
|
46
|
+
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
|
|
47
|
+
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
|
48
|
+
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
For maximum security (TLS 1.3 only):
|
|
52
|
+
```yaml
|
|
53
|
+
strict:
|
|
54
|
+
minVersion: VersionTLS13
|
|
55
|
+
sniStrict: true
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Rate Limiting
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
http:
|
|
62
|
+
middlewares:
|
|
63
|
+
global-rate-limit:
|
|
64
|
+
rateLimit:
|
|
65
|
+
average: 100
|
|
66
|
+
burst: 50
|
|
67
|
+
period: 1s
|
|
68
|
+
sourceCriterion:
|
|
69
|
+
ipStrategy:
|
|
70
|
+
depth: 1 # Correct depth for your proxy chain
|
|
71
|
+
|
|
72
|
+
api-rate-limit:
|
|
73
|
+
rateLimit:
|
|
74
|
+
average: 20
|
|
75
|
+
burst: 10
|
|
76
|
+
period: 1s
|
|
77
|
+
|
|
78
|
+
login-rate-limit:
|
|
79
|
+
rateLimit:
|
|
80
|
+
average: 5
|
|
81
|
+
burst: 3
|
|
82
|
+
period: 1m
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## IP Allowlisting
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
http:
|
|
89
|
+
middlewares:
|
|
90
|
+
internal-only:
|
|
91
|
+
ipAllowList:
|
|
92
|
+
sourceRange:
|
|
93
|
+
- "10.0.0.0/8"
|
|
94
|
+
- "172.16.0.0/12"
|
|
95
|
+
- "192.168.0.0/16"
|
|
96
|
+
ipStrategy:
|
|
97
|
+
depth: 1
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Docker Socket Security
|
|
101
|
+
|
|
102
|
+
**Never** mount Docker socket directly in production. Use a socket proxy:
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
services:
|
|
106
|
+
socket-proxy:
|
|
107
|
+
image: tecnativa/docker-socket-proxy
|
|
108
|
+
environment:
|
|
109
|
+
CONTAINERS: 1
|
|
110
|
+
SERVICES: 0
|
|
111
|
+
TASKS: 0
|
|
112
|
+
NETWORKS: 0
|
|
113
|
+
NODES: 0
|
|
114
|
+
IMAGES: 0
|
|
115
|
+
VOLUMES: 0
|
|
116
|
+
BUILD: 0
|
|
117
|
+
COMMIT: 0
|
|
118
|
+
CONFIGS: 0
|
|
119
|
+
DISTRIBUTION: 0
|
|
120
|
+
EXEC: 0
|
|
121
|
+
GRPC: 0
|
|
122
|
+
INFO: 0
|
|
123
|
+
PLUGINS: 0
|
|
124
|
+
POST: 0
|
|
125
|
+
SECRETS: 0
|
|
126
|
+
SESSION: 0
|
|
127
|
+
SWARM: 0
|
|
128
|
+
SYSTEM: 0
|
|
129
|
+
volumes:
|
|
130
|
+
- /var/run/docker.sock:/var/run/docker.sock:ro
|
|
131
|
+
networks:
|
|
132
|
+
- socket-proxy
|
|
133
|
+
restart: unless-stopped
|
|
134
|
+
|
|
135
|
+
networks:
|
|
136
|
+
socket-proxy:
|
|
137
|
+
internal: true
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Dashboard Security
|
|
141
|
+
|
|
142
|
+
```yaml
|
|
143
|
+
# NEVER use api.insecure: true in production
|
|
144
|
+
|
|
145
|
+
# Secure dashboard with ForwardAuth
|
|
146
|
+
labels:
|
|
147
|
+
- "traefik.http.routers.dashboard.rule=Host(`traefik.internal.example.com`)"
|
|
148
|
+
- "traefik.http.routers.dashboard.service=api@internal"
|
|
149
|
+
- "traefik.http.routers.dashboard.middlewares=dashboard-auth,internal-only"
|
|
150
|
+
- "traefik.http.routers.dashboard.tls.certresolver=letsencrypt"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Forwarded Headers Security
|
|
154
|
+
|
|
155
|
+
```yaml
|
|
156
|
+
entryPoints:
|
|
157
|
+
websecure:
|
|
158
|
+
address: ":443"
|
|
159
|
+
forwardedHeaders:
|
|
160
|
+
trustedIPs:
|
|
161
|
+
- "127.0.0.1/32"
|
|
162
|
+
- "10.0.0.0/8"
|
|
163
|
+
# Add your load balancer / CDN IPs
|
|
164
|
+
# Cloudflare IPs:
|
|
165
|
+
- "173.245.48.0/20"
|
|
166
|
+
- "103.21.244.0/22"
|
|
167
|
+
- "103.22.200.0/22"
|
|
168
|
+
- "103.31.4.0/22"
|
|
169
|
+
- "141.101.64.0/18"
|
|
170
|
+
- "108.162.192.0/18"
|
|
171
|
+
- "190.93.240.0/20"
|
|
172
|
+
- "188.114.96.0/20"
|
|
173
|
+
- "197.234.240.0/22"
|
|
174
|
+
- "198.41.128.0/17"
|
|
175
|
+
- "162.158.0.0/15"
|
|
176
|
+
- "104.16.0.0/13"
|
|
177
|
+
- "104.24.0.0/14"
|
|
178
|
+
- "172.64.0.0/13"
|
|
179
|
+
- "131.0.72.0/22"
|
|
180
|
+
proxyProtocol:
|
|
181
|
+
trustedIPs:
|
|
182
|
+
- "10.0.0.0/8" # Only trust your LB
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**NEVER** trust `0.0.0.0/0` for proxy protocol or forwarded headers.
|
|
186
|
+
|
|
187
|
+
## Container Security
|
|
188
|
+
|
|
189
|
+
```yaml
|
|
190
|
+
services:
|
|
191
|
+
traefik:
|
|
192
|
+
security_opt:
|
|
193
|
+
- no-new-privileges:true
|
|
194
|
+
cap_drop:
|
|
195
|
+
- ALL
|
|
196
|
+
cap_add:
|
|
197
|
+
- NET_BIND_SERVICE
|
|
198
|
+
read_only: true
|
|
199
|
+
tmpfs:
|
|
200
|
+
- /tmp
|
|
201
|
+
deploy:
|
|
202
|
+
resources:
|
|
203
|
+
limits:
|
|
204
|
+
cpus: "1.0"
|
|
205
|
+
memory: 512M
|
|
206
|
+
reservations:
|
|
207
|
+
cpus: "0.1"
|
|
208
|
+
memory: 128M
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Known CVEs to Watch
|
|
212
|
+
|
|
213
|
+
- **CVE-2026-29054**: Case-sensitive bypass for X-Forwarded header removal (fixed v3.6.9)
|
|
214
|
+
- **CVE-2025-66491**: `Verify=On` actually disabled TLS verification (fixed v3.6.3)
|
|
215
|
+
- Always run latest patch version
|
|
216
|
+
|
|
217
|
+
## CORS Configuration
|
|
218
|
+
|
|
219
|
+
```yaml
|
|
220
|
+
http:
|
|
221
|
+
middlewares:
|
|
222
|
+
cors:
|
|
223
|
+
headers:
|
|
224
|
+
accessControlAllowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
|
|
225
|
+
accessControlAllowHeaders: ["Content-Type", "Authorization"]
|
|
226
|
+
accessControlAllowOriginList:
|
|
227
|
+
- "https://app.example.com"
|
|
228
|
+
- "https://admin.example.com"
|
|
229
|
+
accessControlMaxAge: 86400
|
|
230
|
+
accessControlAllowCredentials: true
|
|
231
|
+
addVaryHeader: true
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Request Size Limits (Buffering)
|
|
235
|
+
|
|
236
|
+
```yaml
|
|
237
|
+
http:
|
|
238
|
+
middlewares:
|
|
239
|
+
request-limit:
|
|
240
|
+
buffering:
|
|
241
|
+
maxRequestBodyBytes: 10485760 # 10MB
|
|
242
|
+
maxResponseBodyBytes: 10485760
|
|
243
|
+
memRequestBodyBytes: 2097152 # 2MB in memory
|
|
244
|
+
memResponseBodyBytes: 2097152
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## WAF Integration (Traefik Hub + Coraza)
|
|
248
|
+
|
|
249
|
+
Traefik Hub integrates Coraza WAF with OWASP Core Rule Set:
|
|
250
|
+
```yaml
|
|
251
|
+
# Traefik Hub WAF middleware
|
|
252
|
+
apiVersion: traefik.io/v1alpha1
|
|
253
|
+
kind: Middleware
|
|
254
|
+
metadata:
|
|
255
|
+
name: waf
|
|
256
|
+
spec:
|
|
257
|
+
plugin:
|
|
258
|
+
coraza:
|
|
259
|
+
directives:
|
|
260
|
+
- "SecRuleEngine On"
|
|
261
|
+
- "Include @owasp_crs/*.conf"
|
|
262
|
+
- "SecRule REQUEST_URI \"@rx /etc/passwd\" \"id:1,phase:1,deny,status:403\""
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
For open-source Traefik, use the community Coraza plugin or place ModSecurity/Coraza as a sidecar.
|
|
266
|
+
|
|
267
|
+
## Secrets Management
|
|
268
|
+
|
|
269
|
+
```yaml
|
|
270
|
+
# Docker secrets (preferred over env vars)
|
|
271
|
+
services:
|
|
272
|
+
traefik:
|
|
273
|
+
secrets:
|
|
274
|
+
- cf_api_token
|
|
275
|
+
- dashboard_password
|
|
276
|
+
environment:
|
|
277
|
+
- CF_DNS_API_TOKEN_FILE=/run/secrets/cf_api_token
|
|
278
|
+
|
|
279
|
+
secrets:
|
|
280
|
+
cf_api_token:
|
|
281
|
+
file: ./secrets/cf_api_token.txt # Docker Compose
|
|
282
|
+
# external: true # Docker Swarm
|
|
283
|
+
dashboard_password:
|
|
284
|
+
file: ./secrets/dashboard_password.txt
|
|
285
|
+
```
|
|
286
|
+
|
|
287
|
+
Kubernetes:
|
|
288
|
+
```yaml
|
|
289
|
+
# Use External Secrets Operator for Vault/AWS SM integration
|
|
290
|
+
apiVersion: external-secrets.io/v1beta1
|
|
291
|
+
kind: ExternalSecret
|
|
292
|
+
metadata:
|
|
293
|
+
name: traefik-certs
|
|
294
|
+
spec:
|
|
295
|
+
refreshInterval: 1h
|
|
296
|
+
secretStoreRef:
|
|
297
|
+
name: vault
|
|
298
|
+
kind: ClusterSecretStore
|
|
299
|
+
target:
|
|
300
|
+
name: traefik-tls-secret
|
|
301
|
+
data:
|
|
302
|
+
- secretKey: tls.crt
|
|
303
|
+
remoteRef:
|
|
304
|
+
key: secret/traefik/tls
|
|
305
|
+
property: cert
|
|
306
|
+
- secretKey: tls.key
|
|
307
|
+
remoteRef:
|
|
308
|
+
key: secret/traefik/tls
|
|
309
|
+
property: key
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
## Network Segmentation
|
|
313
|
+
|
|
314
|
+
```yaml
|
|
315
|
+
# Docker: isolate proxy network from internal networks
|
|
316
|
+
networks:
|
|
317
|
+
proxy:
|
|
318
|
+
external: true # Public-facing services
|
|
319
|
+
backend:
|
|
320
|
+
internal: true # Backend services only
|
|
321
|
+
socket-proxy:
|
|
322
|
+
internal: true # Docker socket proxy only
|
|
323
|
+
monitoring:
|
|
324
|
+
internal: true # Prometheus, Grafana, Loki
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Kubernetes:
|
|
328
|
+
```yaml
|
|
329
|
+
# NetworkPolicy: restrict Traefik egress to app namespaces only
|
|
330
|
+
apiVersion: networking.k8s.io/v1
|
|
331
|
+
kind: NetworkPolicy
|
|
332
|
+
metadata:
|
|
333
|
+
name: traefik-egress
|
|
334
|
+
namespace: traefik
|
|
335
|
+
spec:
|
|
336
|
+
podSelector:
|
|
337
|
+
matchLabels:
|
|
338
|
+
app.kubernetes.io/name: traefik
|
|
339
|
+
policyTypes: [Egress]
|
|
340
|
+
egress:
|
|
341
|
+
- to:
|
|
342
|
+
- namespaceSelector:
|
|
343
|
+
matchLabels:
|
|
344
|
+
traefik-access: "true"
|
|
345
|
+
ports:
|
|
346
|
+
- protocol: TCP
|
|
347
|
+
port: 80
|
|
348
|
+
- protocol: TCP
|
|
349
|
+
port: 8080
|
|
350
|
+
- to: # Allow DNS
|
|
351
|
+
- namespaceSelector: {}
|
|
352
|
+
ports:
|
|
353
|
+
- protocol: UDP
|
|
354
|
+
port: 53
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
## InFlightReq (Connection Limiting)
|
|
358
|
+
|
|
359
|
+
```yaml
|
|
360
|
+
http:
|
|
361
|
+
middlewares:
|
|
362
|
+
inflight-limit:
|
|
363
|
+
inFlightReq:
|
|
364
|
+
amount: 100 # Max concurrent requests
|
|
365
|
+
sourceCriterion:
|
|
366
|
+
ipStrategy:
|
|
367
|
+
depth: 1
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Security Checklist
|
|
371
|
+
|
|
372
|
+
- [ ] `api.insecure: false`
|
|
373
|
+
- [ ] `exposedByDefault: false`
|
|
374
|
+
- [ ] Docker socket proxy or read-only mount
|
|
375
|
+
- [ ] `forwardedHeaders.trustedIPs` configured
|
|
376
|
+
- [ ] `proxyProtocol.trustedIPs` configured (if behind LB)
|
|
377
|
+
- [ ] Security headers middleware applied globally
|
|
378
|
+
- [ ] Rate limiting on all public routers
|
|
379
|
+
- [ ] TLS min version 1.2+
|
|
380
|
+
- [ ] `sniStrict: true`
|
|
381
|
+
- [ ] Dashboard behind authentication
|
|
382
|
+
- [ ] ACME storage persisted and backed up
|
|
383
|
+
- [ ] Access logs enabled with filtering
|
|
384
|
+
- [ ] Container runs with minimal privileges
|
|
385
|
+
- [ ] Latest Traefik version with security patches
|
|
386
|
+
- [ ] CORS configured (not wildcard `*` with credentials)
|
|
387
|
+
- [ ] Request body size limits set
|
|
388
|
+
- [ ] Network segmentation (internal networks)
|
|
389
|
+
- [ ] Secrets in Docker secrets / K8s secrets (not env vars)
|
|
390
|
+
- [ ] InFlightReq limits on critical endpoints
|
|
391
|
+
- [ ] WAF enabled for public-facing services
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# TLS, ACME & Let's Encrypt
|
|
2
|
+
|
|
3
|
+
## ACME Certificate Resolvers
|
|
4
|
+
|
|
5
|
+
### HTTP-01 Challenge (simplest, no wildcard support)
|
|
6
|
+
```yaml
|
|
7
|
+
certificatesResolvers:
|
|
8
|
+
letsencrypt:
|
|
9
|
+
acme:
|
|
10
|
+
email: admin@example.com
|
|
11
|
+
storage: /acme.json
|
|
12
|
+
httpChallenge:
|
|
13
|
+
entryPoint: web
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
### DNS-01 Challenge (required for wildcard certs)
|
|
17
|
+
```yaml
|
|
18
|
+
certificatesResolvers:
|
|
19
|
+
letsencrypt:
|
|
20
|
+
acme:
|
|
21
|
+
email: admin@example.com
|
|
22
|
+
storage: /acme.json
|
|
23
|
+
dnsChallenge:
|
|
24
|
+
provider: cloudflare # See supported providers below
|
|
25
|
+
resolvers: ["1.1.1.1:53", "8.8.8.8:53"]
|
|
26
|
+
delayBeforeCheck: 10s
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Supported DNS providers: cloudflare, route53, googlecloud, azure, digitalocean, namecheap, ovh, gandi, hetzner, linode, vultr, and many more.
|
|
30
|
+
|
|
31
|
+
Environment variables per provider (e.g., Cloudflare):
|
|
32
|
+
```bash
|
|
33
|
+
CF_DNS_API_TOKEN=your-api-token
|
|
34
|
+
# OR
|
|
35
|
+
CF_API_EMAIL=your-email
|
|
36
|
+
CF_API_KEY=your-global-api-key
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### TLS-ALPN-01 Challenge
|
|
40
|
+
```yaml
|
|
41
|
+
certificatesResolvers:
|
|
42
|
+
letsencrypt:
|
|
43
|
+
acme:
|
|
44
|
+
email: admin@example.com
|
|
45
|
+
storage: /acme.json
|
|
46
|
+
tlsChallenge: {}
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Wildcard Certificates
|
|
50
|
+
|
|
51
|
+
```yaml
|
|
52
|
+
entryPoints:
|
|
53
|
+
websecure:
|
|
54
|
+
address: ":443"
|
|
55
|
+
http:
|
|
56
|
+
tls:
|
|
57
|
+
certResolver: letsencrypt
|
|
58
|
+
domains:
|
|
59
|
+
- main: "example.com"
|
|
60
|
+
sans:
|
|
61
|
+
- "*.example.com"
|
|
62
|
+
- main: "example.org"
|
|
63
|
+
sans:
|
|
64
|
+
- "*.example.org"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## TLS Options
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
# dynamic/tls.yml
|
|
71
|
+
tls:
|
|
72
|
+
options:
|
|
73
|
+
default: # "default" applies to all routers without explicit tls options
|
|
74
|
+
minVersion: VersionTLS12
|
|
75
|
+
cipherSuites:
|
|
76
|
+
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
|
77
|
+
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
|
78
|
+
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
|
|
79
|
+
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
|
|
80
|
+
sniStrict: true
|
|
81
|
+
|
|
82
|
+
modern:
|
|
83
|
+
minVersion: VersionTLS13
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Kubernetes CRD:
|
|
87
|
+
```yaml
|
|
88
|
+
apiVersion: traefik.io/v1alpha1
|
|
89
|
+
kind: TLSOption
|
|
90
|
+
metadata:
|
|
91
|
+
name: default
|
|
92
|
+
namespace: traefik
|
|
93
|
+
spec:
|
|
94
|
+
minVersion: VersionTLS12
|
|
95
|
+
sniStrict: true
|
|
96
|
+
cipherSuites:
|
|
97
|
+
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Mutual TLS (mTLS)
|
|
101
|
+
|
|
102
|
+
```yaml
|
|
103
|
+
tls:
|
|
104
|
+
options:
|
|
105
|
+
mtls:
|
|
106
|
+
clientAuth:
|
|
107
|
+
caFiles:
|
|
108
|
+
- /certs/client-ca.pem
|
|
109
|
+
clientAuthType: RequireAndVerifyClientCert
|
|
110
|
+
# Options: NoClientCert, RequestClientCert, RequireAnyClientCert,
|
|
111
|
+
# VerifyClientCertIfGiven, RequireAndVerifyClientCert
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Custom Certificates (no ACME)
|
|
115
|
+
|
|
116
|
+
```yaml
|
|
117
|
+
tls:
|
|
118
|
+
certificates:
|
|
119
|
+
- certFile: /certs/example.com.crt
|
|
120
|
+
keyFile: /certs/example.com.key
|
|
121
|
+
- certFile: /certs/wildcard.example.com.crt
|
|
122
|
+
keyFile: /certs/wildcard.example.com.key
|
|
123
|
+
stores:
|
|
124
|
+
default:
|
|
125
|
+
defaultCertificate:
|
|
126
|
+
certFile: /certs/default.crt
|
|
127
|
+
keyFile: /certs/default.key
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## ServersTransport (TLS to backends)
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
# Kubernetes CRD
|
|
134
|
+
apiVersion: traefik.io/v1alpha1
|
|
135
|
+
kind: ServersTransport
|
|
136
|
+
metadata:
|
|
137
|
+
name: mtls-transport
|
|
138
|
+
spec:
|
|
139
|
+
serverName: "backend.internal"
|
|
140
|
+
insecureSkipVerify: false
|
|
141
|
+
rootCAsSecrets:
|
|
142
|
+
- backend-ca
|
|
143
|
+
certificatesSecrets:
|
|
144
|
+
- client-cert
|
|
145
|
+
maxIdleConnsPerHost: 10
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Best Practices
|
|
149
|
+
|
|
150
|
+
- Use DNS-01 for wildcard certs
|
|
151
|
+
- Set `minVersion: VersionTLS12` minimum
|
|
152
|
+
- Enable `sniStrict: true` to reject unknown domains
|
|
153
|
+
- Persist `acme.json` on a volume (mode 600)
|
|
154
|
+
- Use staging CA for testing: `caServer: https://acme-staging-v02.api.letsencrypt.org/directory`
|
|
155
|
+
- In HA setups, use shared cert storage (Consul KV or Traefik Enterprise)
|