尝试在Traefik上配置HTTPS时获取502坏网关



我在这里得到了一个适用于HTTP的基本Traefik 2设置。。。

现在我正在尝试使用HTTPS,并使用TLS和重定向对仪表板进行基本身份验证。。。

docker_compose.yml

version: '3.8'
networks:
myweb:
external: true
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
# Mount the certs drive
- ./traefik-ssl-certs/:c:/certs/
# Mount the config folder
- ./traefik-config/:c:/config/
# Mount the host docker engine pipe ("docker volume ls")
- source: '\.pipedocker_engine'
target: '\.pipedocker_engine'
type: npipe
command:
- "--api.insecure=true"
# Register the traefik config directory as per: https://docs.traefik.io/providers/file/#directory
- --providers.file.directory=c:/config/
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Redirect http to https
- --entrypoints.web.http.redirections.entryPoint.to=websecure
- --entrypoints.web.http.redirections.entryPoint.scheme=https
- --entrypoints.web.http.redirections.entrypoint.permanent=true
# Configure Docker provider
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.endpoint=npipe:////./pipe/docker_engine"
- "--providers.docker.network=myweb"
- "--providers.docker.watch=true"
networks:
- myweb
labels:
- traefik.http.routers.api.service=api@internal
- traefik.enable=true
- traefik.docker.network=myweb

remoteling:
image: remoteling:latest
container_name: remoteling
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
- traefik.http.middlewares.http2https.redirectscheme.scheme=https
- traefik.http.routers.remoteling-http.middlewares=http2https
- traefik.http.routers.remoteling-http.rule=Host(`example.com`) || Host(`example.example.com`)
- traefik.http.routers.remoteling-http.entrypoints=web

- traefik.http.services.remoteling.loadbalancer.server.port=443
- traefik.http.routers.remoteling-https.rule=Host(`example.com`) || Host(`example.example.com`)
- traefik.http.routers.remoteling-https.entrypoints=websecure
- traefik.http.routers.remoteling-https.tls=true
depends_on:
- proxy

从powershell我正在运行:

docker network create -d nat myweb
docker-compose -p myweb up 

在我的工作目录中,我有以下文件结构:

  • /docker-compose.yml
  • /traefik配置/traefik.yml
  • /traefik ssl证书/example.com.crt
  • /traefik ssl证书/example.com.key
  • /traefik ssl证书/example.example.com.key
  • /traefik ssl证书/example.example.com.key

traefik.yml文件如下所示:

tls:
certificates:
- certFile: c:/certs/example.example.com.crt
keyFile: c:/certs/example.example.com.key
- certFile: c:/certs/example.com.crt
keyFile: c:/certs/example.com.key

traefik仪表板显示了我的服务被定义为负载平衡器,这很好(除了负载平衡器之外还有其他类型的服务吗?我不知道除了通过负载平衡器之外如何定义端口)。单击该服务会为我提供本地网络IP,并且当我访问该IP时,我的网站加载良好(尽管会出现SSL证书不匹配警告-预期)。

然而,当我试图访问https://example.com或https://example.example.com-我得到一个502坏网关。知道我为什么会得到这个吗

浏览器显示SSL证书是有效的,没有任何警告,所以我认为我的证书配置是好的。

http到https的重定向似乎正在工作,如果我访问http://example.com它转发给我https://example.com

我的路由配置有什么问题导致这些坏网关

我已经解决了我的问题!有几个问题:

  1. 我在Dockerfile中配置了TLS证书,这是我在服务器上作为单个服务运行映像时的情况。所以我的镜像已经有443端口绑定了TLS证书。我认为这在Traefik路由器尝试为服务配置TLS时造成了问题。所以我不得不重建我的图像,删除TLS。我还删除了需要HTTPS属性的代码,这现在是traefik的责任

映像只需要暴露1个端口:我现在的理解是,我的web应用程序应该只通过端口80运行(例如,甚至不需要映像防火墙中暴露的端口443),Traefik路由器通过端口80配置和处理TLS/443等。

  1. 我实际上并没有正确定义我的HTTP和HTTPS服务。我在下面分享了我的docker-compose.yml文件——注意,对于traefik和我的其他服务,我将标签分为几个部分:定义服务、HTTP路由、HTTPS路由、重定向中间件和traefik面板的基本身份验证。我找不到任何好的文档或教程来真正分解traefik2.0的必要方面并对它们进行清晰的分类

服务定义标签/负载均衡器端口应该指向映像服务托管的任何端口,例如,在大多数情况下是端口80,或者在traefik服务8080的情况下是。但至关重要的是,它不需要为https指向443。

总之,我的(详细的)学习笔记毕竟是,你需要:

  • 再次将服务定义为标签:没有服务定义标签对我来说不起作用。我必须添加一个服务标签,指向定义图像的服务名称
  • 定义http和https的路由器:无论你在traefik.http.routers.YOUR_ROUTER_NAME后面放什么文本,都会成为你的路由器。我不清楚http和https都需要单独的路由器。您必须为每项服务(例如traefik、whoami、remoteing等)执行此操作
  • 定义路由器的入口点:AFAIK在traefik命令中放在入口点后面的名称定义了一个可以用于其他服务的新入口点。因此,在traefik服务定义中,您将有--entrypoints.WEBNAME.address=:80和--entryppoints.WEBSECURENAME.address=:443(用您自己的名称替换这些大写字母,以便在整个docker-compose.yml文件中使用
  • 定义要捕获的路由器的域名:就像为每个http和https定义路由器一样,您必须为这两个路由器定义要捕捉的域,即使只是相同的域/路径
  • 为https路由器添加tls:对于https路由器,您需要tls.true标签
  • traefik和您的每个服务的单独中间件重定向定义:我读到您可以声明一个全局重定向定义,但AFAIK每个服务必须通过将中间件分配给http路由器来选择加入
  • 在Docker for Windows上提供您自己的SSL证书:关于使用您自己的SSL证书运行Docker for Windows,几乎没有什么信息。我在"traefik"工作目录中有一个批处理脚本,其中有一个子文件夹,包含SSL证书(crt和密钥文件)。我将其装载为第一个卷- ./traefik-ssl-certs/:c:/certs/。然后,在我的工作目录中,我有另一个名为traefik-config的文件夹,其中包含我的traefik.yml文件(详细信息请参阅上面的问题)。在linux中,每个人似乎都直接挂载配置文件,但挂载文件在Windows中不起作用,所以我不得不将其作为文件夹挂载,然后我使用命令providers.file.directory=c:/config/,它告诉traefik在其中查找配置文件。配置文件提供了要加载traefik的SSL证书的位置。如果您为路由器启用TLS,Traefik将自动使用与您在该路由器上指定的域匹配的任何证书
  • 基本身份验证:必须将中间件定义为一个标签,然后将该中间件分配给https路由器。我想,如果你不使用HTTPS重定向,那么你可以将其分配给你的http路由器,但这显然是不安全的

docker compose.yml:

version: '3.8'
networks:
myweb:
external: true
services:
proxy:
image: traefik:v2.3.0-rc4-windowsservercore-1809
container_name: traefik
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
# Mount the certs drive
- ./traefik-ssl-certs/:c:/certs/
# Mount the config folder
- ./traefik-config/:c:/config/
# Mount the host docker engine pipe ("docker volume ls")
- source: '\.pipedocker_engine'
target: '\.pipedocker_engine'
type: npipe
command:
- --api=true
- --api.dashboard=true
- --api.insecure=false
# Register the traefik config directory as per: https://docs.traefik.io/providers/file/#directory
- --providers.file.directory=c:/config/
- --providers.file.watch=true
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
# Configure Docker provider
- --providers.docker=true
- --providers.docker.exposedbydefault=false
- --providers.docker.endpoint=npipe:////./pipe/docker_engine
- --providers.docker.network=myweb
- --providers.docker.watch=true
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
# Define the service
- traefik.http.services.proxy.loadbalancer.server.port=8080
# Routing for dashboard HTTP
- traefik.http.routers.dash-http.service=api@internal
- traefik.http.routers.dash-http.rule=Host(`example.com`)
- traefik.http.routers.dash-http.entrypoints=web
# Routing for dashboard HTTPS
- traefik.http.routers.dash-https.service=api@internal
- traefik.http.routers.dash-https.rule=Host(`example.com`)
- traefik.http.routers.dash-https.entrypoints=websecure
- traefik.http.routers.dash-https.tls=true
# Http-to-Https redirect Middleware
- traefik.http.middlewares.dash-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.dash-http2https.redirectscheme.permanent=true
- traefik.http.routers.dash-http.middlewares=dash-http2https
# BasicAuth for dashboard
# Windows doesn't have htpasswd command so I generated one here: https://hostingcanada.org/htpasswd-generator/
# As per Traefik documentation, escaped single $ char with $$ for the yml parser
# user/pass = admin/testpassword 
- traefik.http.middlewares.api-auth.basicauth.users=admin:$$2y$$10$$mfWQ11K16V6gVK.8Y6q1Eeh765NZscmjCrjJlAtaWubEsjU8HLYOO
- traefik.http.routers.dash-https.middlewares=api-auth
remoteling:
image: remoteling:latest
container_name: remoteling
networks:
- myweb
labels:
- traefik.enable=true
- traefik.docker.network=myweb
# Define the service
- traefik.http.services.remoteling.loadbalancer.server.port=80
# Routing for remoteling HTTP
- traefik.http.routers.remoteling-http.service=remoteling
- traefik.http.routers.remoteling-http.entrypoints=web
- traefik.http.routers.remoteling-http.rule=Host(`services.example.com`) 
# Routing for remoteling HTTPS
- traefik.http.routers.remoteling-https.service=remoteling
- traefik.http.routers.remoteling-https.entrypoints=websecure
- traefik.http.routers.remoteling-https.rule=Host(`services.example.com`)
- traefik.http.routers.remoteling-https.tls=true

# Http-to-Https redirect Middleware
- traefik.http.middlewares.remoteling-http2https.redirectscheme.scheme=https
- traefik.http.middlewares.remoteling-http2https.redirectscheme.permanent=true
- traefik.http.routers.remoteling-http.middlewares=remoteling-http2https
depends_on:
- proxy

希望其他人觉得这很有用。

最新更新