Traefik和Nginx在Docker上使用HTTPS / 400错误请求

时间:2018-06-19 23:30:47

标签: docker nginx https traefik

我正在尝试使用基于Docker的Traefik和Nginx构建堆栈。如果没有HTTPS,一切都会好起来,但是一旦我进行HTTPS配置,就会收到一个错误消息。

我在example.com上从Nginx收到此错误: 400错误的请求/普通的HTTP请求已发送到HTTPS端口。在地址栏中,我可以看到绿色的锁说连接是安全的。

Certbot可以正常工作,因此我在正确的文件夹中具有真实的SSL证书。

当我访问traefik.example.com时,我可以进入Traefik控制台,但是我不必接受SSL浏览器警告,并且该控制台也可以在没有HTTPS的情况下正常工作。

docker-compose.yml

version: '3.4'
services:
    traefik:
        image: traefik:latest
        ports:
            - "80:80"
            - "443:443"
            - "8080:8080"
        volumes:
            - /var/run/docker.sock:/var/run/docker.sock
            - ./traefik/traefik.toml:/etc/traefik/traefik.toml
            - ../letsencrypt:/etc/letsencrypt
        labels:
            - traefik.backend=traefik
            - traefik.frontend.rule=Host:traefik.example.com
            - traefik.port=8080
        networks:
           - traefik
    nginx:
        image: nginx:latest
        volumes:
            - ../www:/var/www
            - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
            - ../letsencrypt:/etc/letsencrypt
        labels:
            - traefik.backend=nginx
            - traefik.frontend.rule=Host:example.com
            - traefik.port=80
            - traefik.port=443
        networks:
            - traefik
networks:
    traefik:
        driver: overlay
        external: true
        attachable: true

traefik.toml

defaultEntryPoints = ["http", "https"]

[web]
    address = ":8080"

[entryPoints]
    [entryPoints.http]
        address = ":80"
        [entryPoints.http.redirect]
            entryPoint = "https"
    [entryPoints.https]
        address = ":443"
        [entryPoints.https.tls]
            [[entryPoints.https.tls.certificates]]
                certFile = "/etc/letsencrypt/live/example.com/fullchain.pem"
                keyFile = "/etc/letsencrypt/live/example.com/privkey.pem"

[docker]
    domain="example.com"
    watch = true
    exposedByDefault = true
    swarmMode = false

nginx.conf

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl http2;

    server_name www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/public;
    index index.html;
}

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

首先,不需要在Traefik和Nginx中都配置SSL重定向。同样,Traefik前端仅匹配non www变体,但后端应用程序期望www。最后,不推荐Traefik web提供程序,因此应该有较新的api提供程序。

答案 1 :(得分:0)

因为我刚刚在 Traefik v2 上偶然发现了一个类似的问题

400 Bad Request / The plain HTTP request was sent to HTTPS port

带有 Nginx 错误日志说明

400 client sent plain HTTP request to HTTPS port while reading client request headers

并抓紧我的头,我终于找到了那个错误的根源。不是 TLS 证书无效或传输中的某些内容损坏,而是路由器、服务和端口映射之间的线路断开。

以前我没有看到 Docker Compose 堆栈有一个 Nginx 容器,它只监听 80/tcp。我假设一切正常,因为我将端口连接到 Traefik 负载均衡器,这些负载均衡器连接到每个带有单独路由器的 http/https 端点的单独服务。这不知何故不起作用:

- "traefik.http.services.proxy.loadbalancer.server.port=80"
- "traefik.http.services.proxy-secure.loadbalancer.server.port=443"

中介 现在我打开了 port: - "8008:80" - "8443:443" 并让它工作。进一步调查 Traefik 端口的问题,因为默认情况下这些端口应该得到 exposed。这不是一个解决方案,因为这些端口现在可供外部世界使用,但我将这个解释留在这里,因为我找不到关于这个主题的任何内容,可以为我指明正确的方向,所以希望以后对其他人有帮助.