Docker Swarm+Traefik遭DDoS攻击,求仅放行指定域名的配置方案
如何配置Traefik仅接受指定域名请求以缓解DDoS攻击
环境
- Docker Swarm
- Traefik v2.10.6
- 多服务监听
xxx.domain.com、yyy.domain.com等域名的80/443端口流量 - Hetzner主机
问题描述
域名已配置Cloudflare类抗DDoS防护,但仍遭受针对服务器IP及Hetzner默认域名https://static.IP.clients.your-server.de的攻击,攻击目标为无对应服务的404页面。希望通过配置Traefik,仅接受domain.com及*.domain.com的请求,拒绝其他所有请求,避免无效请求消耗服务器资源。
当前Traefik配置
version: '3.3' services: traefik: image: traefik:v2.10.6 ports: - 80:80 - 443:443 deploy: placement: constraints: - node.labels.traefik-public.traefik-public-certificates == true labels: - traefik.enable=true - traefik.docker.network=traefik-public - traefik.constraint-label=traefik-public - traefik.http.middlewares.https-redirect.redirectscheme.scheme=https - traefik.http.middlewares.https-redirect.redirectscheme.permanent=true - traefik.http.routers.traefik-public-http.rule=Host(`${DOMAIN?Variable not set}`) - traefik.http.routers.traefik-public-http.entrypoints=http - traefik.http.routers.traefik-public-http.middlewares=https-redirect - traefik.http.routers.traefik-public-https.rule=Host(`${DOMAIN?Variable not set}`) - traefik.http.routers.traefik-public-https.entrypoints=https - traefik.http.routers.traefik-public-https.tls=true - traefik.http.routers.traefik-public-https.service=api@internal - traefik.http.routers.traefik-public-https.tls.certresolver=le - traefik.http.routers.traefik-public-https.middlewares=admin-auth - traefik.http.services.traefik-public.loadbalancer.server.port=8080 volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - traefik-public-certificates:/certificates command: - --providers.docker - --providers.docker.constraints=Label(`traefik.constraint-label`, `traefik-public`) - --providers.docker.exposedbydefault=false - --providers.docker.swarmmode - --entrypoints.http.address=:80 - --entrypoints.https.address=:443 - --certificatesresolvers.le.acme.email=${EMAIL?Variable not set} - --certificatesresolvers.le.acme.storage=/certificates/acme.json - --certificatesresolvers.le.acme.tlschallenge=true - --accesslog - --log - --api networks: - traefik-public volumes: traefik-public-certificates: networks: traefik-public: external: true
解决方案
可以通过配置默认拒绝路由或全局过滤中间件实现仅允许指定域名的请求通过,以下是两种务实的实现方式:
方式一:原生无插件实现(推荐)
通过创建优先级最低的默认路由,捕获所有非合法域名请求并返回403,合法请求会匹配对应服务的高优先级路由:
- 在Traefik的
labels中新增拒绝中间件和默认路由:
# 新增拒绝中间件:返回403 Forbidden - traefik.http.middlewares.deny-all.responsegenerator.statuscode=403 - traefik.http.middlewares.deny-all.responsegenerator.body="Forbidden" # HTTP默认路由:优先级1,捕获所有非合法请求 - traefik.http.routers.default-http.rule=HostRegexp(`{any:.*}`) - traefik.http.routers.default-http.entrypoints=http - traefik.http.routers.default-http.priority=1 - traefik.http.routers.default-http.middlewares=https-redirect,deny-all # HTTPS默认路由:优先级1,捕获所有非合法请求 - traefik.http.routers.default-https.rule=HostRegexp(`{any:.*}`) - traefik.http.routers.default-https.entrypoints=https - traefik.http.routers.default-https.priority=1 - traefik.http.routers.default-https.middlewares=deny-all - traefik.http.routers.default-https.tls=true
- 确保所有合法服务的路由优先级高于默认路由(默认路由优先级设为1,合法路由默认优先级更高,也可显式设置
priority=10)。
方式二:插件实现(需启用实验性功能)
使用Traefik的ipallowlist插件实现域名过滤,同时放行Let's Encrypt证书续签路径:
- 在Traefik的
command中启用插件支持:
- --experimental.plugins.ipallowlist.modulename=github.com/traefik/plugin-ipallowlist - --experimental.plugins.ipallowlist.version=v0.6.0
- 在
labels中新增域名过滤中间件,并绑定到入口点:
# 新增域名过滤中间件 - traefik.http.middlewares.allowed-domains.plugin.rules.0.match=HostRegexp(`{subdomain:[a-z0-9-]*}.domain.com`, `domain.com`) || PathPrefix(`/.well-known/acme-challenge`) - traefik.http.middlewares.allowed-domains.plugin.rules.0.action=allow - traefik.http.middlewares.allowed-domains.plugin.rules.1.match=HostRegexp(`{any:.*}`) - traefik.http.middlewares.allowed-domains.plugin.rules.1.action=deny
- 修改入口点配置,绑定过滤中间件:
- --entrypoints.http.address=:80 - --entrypoints.http.http.middlewares=allowed-domains@docker - --entrypoints.https.address=:443 - --entrypoints.https.http.middlewares=allowed-domains@docker
关键说明
- 两种方式都会让非合法域名/IP的请求直接返回403,而非404,减少无效请求的资源消耗。
- 必须放行
/.well-known/acme-challenge路径,确保Let's Encrypt证书能正常续签。 - 原生方式无需额外依赖,更适合生产环境;插件方式配置更简洁,但需启用实验性功能。
内容的提问来源于stack exchange,提问作者mpz
相关产品推荐
相关产品推荐

