Docker/400 错误请求上使用 HTTPS 的 Traefik 和 Nginx
Traefik and Nginx with HTTPS on Docker / 400 Bad Request
我正在尝试基于 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;
}
感谢您的帮助。
首先不需要在Traefik和Nginx中都配置SSL重定向。此外,Traefik 前端仅匹配 non www
变体,但后端应用程序需要 www
。最后,Traefik web
提供程序已弃用,因此应该有更新的 api
提供程序。
因为我刚刚偶然发现了 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
。这不是解决方案,因为这些端口现在可供外界使用,但我将此解释留在这里,因为我找不到关于该主题的任何内容可以为我指明正确的方向,因此希望它对以后的其他人有所帮助.
我正在尝试基于 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;
}
感谢您的帮助。
首先不需要在Traefik和Nginx中都配置SSL重定向。此外,Traefik 前端仅匹配 non www
变体,但后端应用程序需要 www
。最后,Traefik web
提供程序已弃用,因此应该有更新的 api
提供程序。
因为我刚刚偶然发现了 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
。这不是解决方案,因为这些端口现在可供外界使用,但我将此解释留在这里,因为我找不到关于该主题的任何内容可以为我指明正确的方向,因此希望它对以后的其他人有所帮助.