[英]Mailcow setup behind Traefik Proxy causes https certificate error
I am trying to setup the mailcow
installation behind Traefik
proxy.我正在尝试在
Traefik
代理后面设置mailcow
安装。 Apparently, Traefik proxy is not able to recognize the nginx-mailcow
container in its network and hence does not create a certificate for https
connection.显然,Traefik 代理无法识别其网络中的
nginx-mailcow
容器,因此不会为https
连接创建证书。 so when I bring up the mailcow service using docker-compose up
, I can access the mailcow services but on insecure connection (http) and browser warns that connection is not secure.因此,当我使用
docker-compose up
mailcow 服务时,我可以访问 mailcow 服务,但连接不安全(http)并且浏览器警告连接不安全。
When I check my acme.json
file from Traefik
: I can not find any certificate related to mailcow domain ie, mail.tld.com
there.当我从
Traefik
检查我的acme.json
文件时:我找不到任何与 mailcow 域相关的证书,即那里的mail.tld.com
。
I have the following setup:我有以下设置:
Logs of affected containers:受影响容器的日志:
Traefik
Container Logs: Traefik
容器日志:
time="2020-04-18T13:40:35+02:00" level=error msg="accept tcp [::]:80: use of closed network connection" entryPointName=http
time="2020-04-18T13:40:35+02:00" level=error msg="accept tcp [::]:443: use of closed network connection" entryPointName=https
time="2020-04-18T13:40:35+02:00" level=error msg="close tcp [::]:80: use of closed network connection" entryPointName=http
time="2020-04-18T13:40:35+02:00" level=error msg="close tcp [::]:443: use of closed network connection" entryPointName=https
time="2020-04-18T13:40:35+02:00" level=error msg="Cannot connect to docker server context canceled" providerName=docker
time="2020-04-18T13:40:37+02:00" level=info msg="Configuration loaded from file: /traefik.yml"
time="2020-04-19T00:27:31+02:00" level=error msg="service \"nginx-mailcow\" error: unable to find the IP address for the container \"/mailcowdockerized_nginx-mailcow_1\": the server is ignored" container=nginx-mailcow-mailcowdockerized-5f3a25b43c42fd85df675d2d9682b6053501844c2cfe15b7802cf918df138025 providerName=docker
time="2020-04-19T00:33:32+02:00" level=error msg="service \"nginx-mailcow\" error: unable to find the IP address for the container \"/mailcowdockerized_nginx-mailcow_1\": the server is ignored" providerName=docker container=nginx-mailcow-mailcowdockerized-f4d41ee79e382b413e04b039b5fc91e1c6217c78740245c8666373fe2d6a9b23
2020/04/19 00:39:44 reverseproxy.go:445: httputil: ReverseProxy read error during body copy: unexpected EOF
time="2020-04-19T00:50:32+02:00" level=error msg="service \"nginx-mailcow\" error: unable to find the IP address for the container \"/mailcowdockerized_nginx-mailcow_1\": the server is ignored" providerName=docker container=nginx-mailcow-mailcowdockerized-915f80e492c2c22917d0af81add1dde15577173c82cc928b0b6101c8a260adc5
time="2020-04-19T00:58:43+02:00" level=error msg="service \"nginx-mailcow\" error: unable to find the IP address for the container \"/mailcowdockerized_nginx-mailcow_1\": the server is ignored" container=nginx-mailcow-mailcowdockerized-852985c4efc48559ca3568b1829e31b46eb9f968fc328a8566e3dc6ab6f1af21 providerName=docker
time="2020-04-19T02:02:39+02:00" level=error msg="Error while Peeking first byte: read tcp 172.21.0.2:80->208.91.109.90:55153: read: connection reset by peer"
time="2020-04-19T08:11:32+02:00" level=error msg="service \"nginx-mailcow\" error: unable to find the IP address for the container \"/mailcowdockerized_nginx-mailcow_1\": the server is ignored" providerName=docker container=nginx-mailcow-mailcowdockerized-840ef4db0ccc9fa84038dc7a52133779926dba4c51554516c17404ede80a2c01
The contents of Traefik
docker-compose.yml
: Traefik
docker-compose.yml
的内容:
version: '3'
services:
traefik:
image: traefik:v2.1
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/traefik.yml:/traefik.yml:ro
- ./data/acme.json:/acme.json
labels:
- "traefik.enable=true"
- "traefik.http.routers.traefik.entrypoints=http"
- "traefik.http.routers.traefik.rule=Host(`traefik.tld.com`)"
- "traefik.http.middlewares.traefik-auth.basicauth.users=admin:pass"
- "traefik.http.middlewares.traefik-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.traefik.middlewares=traefik-https-redirect"
- "traefik.http.routers.traefik-secure.entrypoints=https"
- "traefik.http.routers.traefik-secure.rule=Host(`traefik.tld.com`)"
- "traefik.http.routers.traefik-secure.middlewares=traefik-auth"
- "traefik.http.routers.traefik-secure.tls=true"
- "traefik.http.routers.traefik-secure.tls.certresolver=http"
- "traefik.http.routers.traefik-secure.service=api@internal"
networks:
proxy:
external: true
Contents of traefik.yml (I used.yml instead of.toml) traefik.yml 的内容(我用.yml 代替.toml)
api:
dashboard: true
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
endpoint: "unix:///var/run/docker.sock"
exposedByDefault: false
certificatesResolvers:
http:
acme:
email: myemail@tld.com
storage: acme.json
httpChallenge:
entryPoint: http
Just to point out, with this setup of Traefik
, certificates are generated automatically for other services like gitlab
.需要指出的是,通过
Traefik
的这种设置,会为其他服务(如gitlab
)自动生成证书。 For that, I just correctly labelled the gitlab
service and assigned the Traefik
network to it and Traefik
service would recognize the gitlab
service and generates the certificate in acme.json
but sadly not for nginx-mailcow
.为此,我只是正确地标记了
gitlab
服务并将Traefik
网络分配给它, Traefik
服务将识别gitlab
服务并在acme.json
nginx-mailcow
中生成证书。
The contents of my docker-compose.override.yml
for mailcow:我的
docker-compose.override.yml
的内容为 mailcow:
version: '2.1'
services:
nginx-mailcow:
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx-mailcow.entrypoints=http"
- "traefik.http.routers.nginx-mailcow.rule=HostRegexp(`{host:(autodiscover|autoconfig|webmail|mail|email).+}`)"
- "traefik.http.middlewares.nginx-mailcow-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.nginx-mailcow.middlewares=nginx-mailcow-https-redirect"
- "traefik.http.routers.nginx-mailcow-secure.entrypoints=https"
- "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.tld.com`)"
- "traefik.http.routers.nginx-mailcow-secure.tls=true"
- "traefik.http.routers.nginx-mailcow-secure.service=nginx-mailcow"
- "traefik.http.services.nginx-mailcow.loadbalancer.server.port=80"
- "traefik.docker.network=proxy"
networks:
proxy:
certdumper:
image: humenius/traefik-certs-dumper
container_name: traefik_certdumper
network_mode: none
command: --restart-containers mailcowdockerized_postfix-mailcow_1,mailcowdockerized_dovecot-mailcow_1
volumes:
- /opt/containers/traefik/data:/traefik:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/assets/ssl:/output:rw
environment:
- DOMAIN=tld.com
networks:
proxy:
external: true
The contents of my nginx-mailcow
service in docker-compose.yml
我的
nginx-mailcow
服务在docker-compose.yml
中的内容
version: '2.1'
services:
...
nginx-mailcow:
depends_on:
- sogo-mailcow
- php-fpm-mailcow
- redis-mailcow
image: nginx:mainline-alpine
dns:
- ${IPV4_NETWORK:-172.22.1}.254
command: /bin/sh -c "envsubst < /etc/nginx/conf.d/templates/listen_plain.template > /etc/nginx/conf.d/listen_plain.active &&
envsubst < /etc/nginx/conf.d/templates/listen_ssl.template > /etc/nginx/conf.d/listen_ssl.active &&
envsubst < /etc/nginx/conf.d/templates/server_name.template > /etc/nginx/conf.d/server_name.active &&
envsubst < /etc/nginx/conf.d/templates/sogo.template > /etc/nginx/conf.d/sogo.active &&
envsubst < /etc/nginx/conf.d/templates/sogo_eas.template > /etc/nginx/conf.d/sogo_eas.active &&
. /etc/nginx/conf.d/templates/sogo.auth_request.template.sh > /etc/nginx/conf.d/sogo_proxy_auth.active &&
. /etc/nginx/conf.d/templates/sites.template.sh > /etc/nginx/conf.d/sites.active &&
nginx -qt &&
until ping phpfpm -c1 > /dev/null; do sleep 1; done &&
until ping sogo -c1 > /dev/null; do sleep 1; done &&
until ping redis -c1 > /dev/null; do sleep 1; done &&
until ping rspamd -c1 > /dev/null; do sleep 1; done &&
exec nginx -g 'daemon off;'"
environment:
- HTTPS_PORT=${HTTPS_PORT:-443}
- HTTP_PORT=${HTTP_PORT:-80}
- MAILCOW_HOSTNAME=${MAILCOW_HOSTNAME}
- IPV4_NETWORK=${IPV4_NETWORK:-172.22.1}
- TZ=${TZ}
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
volumes:
- ./data/web:/web:ro
- ./data/conf/rspamd/dynmaps:/dynmaps:ro
- ./data/assets/ssl/:/etc/ssl/mail/:ro
- ./data/conf/nginx/:/etc/nginx/conf.d/:rw
- ./data/conf/rspamd/meta_exporter:/meta_exporter:ro
- sogo-web-vol-1:/usr/lib/GNUstep/SOGo/
ports:
- "${HTTPS_BIND:-0.0.0.0}:${HTTPS_PORT:-443}:${HTTPS_PORT:-443}"
- "${HTTP_BIND:-0.0.0.0}:${HTTP_PORT:-80}:${HTTP_PORT:-80}"
restart: always
networks:
mailcow-network:
aliases:
- nginx
....
I have also tried comment out ports in nginx-mailcow
service but the problem persists.我也尝试在
nginx-mailcow
服务中注释掉端口,但问题仍然存在。 My current mailcow.conf
changes:我当前的
mailcow.conf
更改:
HTTP_BIND=127.0.0.1
HTTP_PORT=8080
HTTPS_BIND=127.0.0.1
HTTPS_PORT=8443
SKIP_LETS_ENCRYPT=y
SKIP_CLAMD=y
Reproduction of said bug:重现所述错误:
I setup the traefik proxy first (see contents above).我首先设置了 traefik 代理(参见上面的内容)。 Once the Traefik is up and running (I also tested for other services and it works fine in generating a certificate).
一旦 Traefik 启动并运行(我还测试了其他服务,它可以正常生成证书)。 Now first I cloned the mailcow repository.
现在首先我克隆了 mailcow 存储库。 Then I run
./generate_config.sh
to generate mailcow.conf
file.然后我运行
./generate_config.sh
来生成mailcow.conf
文件。 As input to generate_config.sh I provide my domain name ie, mail.tld.com
作为 generate_config.sh 的输入,我提供了我的域名,即
mail.tld.com
Then I comment out the ports in docker-compose.yml
file because I do not want to use port 80 and 443 for nginx-mailcow
as these ports are already being used by Traefik
.然后我注释掉
docker-compose.yml
文件中的端口,因为我不想为nginx-mailcow
使用端口 80 和 443,因为Traefik
已经在使用这些端口。
Then I create a docker-compose.override.yml
(see contents above) to add additional configs to nginx-mailcow
service (traefik labels, traefik network).然后我创建了一个
docker-compose.override.yml
(见上面的内容)来添加额外的配置到nginx-mailcow
服务(traefik 标签,traefik 网络)。 The override file also contain the certdumper
service which would copy https certificate from acme.json to mailcow services.覆盖文件还包含
certdumper
服务,该服务会将 https 证书从 acme.json 复制到 mailcow 服务。
Then, I change the following two variables in mailcow.conf
:然后,我在
mailcow.conf
中更改以下两个变量:
SKIP_LETS_ENCRYPT=y
SKIP_CLAMD=y
Finally, I run the mailcow
using docker-compose up -d
.最后,我使用
docker-compose up -d
运行mailcow
。 In browser, if check https://mail.tld.com
=> It warns that connection is insecure.在浏览器中,如果检查
https://mail.tld.com
=> 它警告连接不安全。 If I check acme.json
.如果我检查
acme.json
。 I find no certificate for mail.tld.com
.我找不到
mail.tld.com
的证书。
System information:系统信息:
+-------------------------------------------------+---------------------------------+
| Question | Answer |
+-------------------------------------------------+---------------------------------+
| My operating system | linux x86_64 Ubuntu 18.04.1 LTS |
| Is Apparmor, SELinux or similar active? | No |
| Virtualization technlogy | KVM |
| Server/VM specifications (Memory, CPU Cores) | 16GB, 6 cores |
| Docker Version (docker version) | 19.03.8 |
| Docker-Compose Version (docker-compose version) | 1.25.4, build 8d51620a |
| Reverse proxy (custom solution) | Traefik |
+-------------------------------------------------+---------------------------------+
If you need more information, I would be happy to provide.如果您需要更多信息,我很乐意提供。 Any help will be much appreciated.
任何帮助都感激不尽。 Thank you.
谢谢你。
Finally I was able to solve the problem after investing many hours in reading the Traefik Documentation.在投入大量时间阅读 Traefik 文档后,我终于解决了这个问题。 I made tiny mistake in assigning proxy labels to the nginx-mailcow service.
我在为 nginx-mailcow 服务分配代理标签时犯了一个小错误。 The solution is below.
解决方案如下。
I forgot to mention certificate resolver and I had to expose the port which I now added as follows:我忘了提到证书解析器,我不得不公开我现在添加的端口,如下所示:
services:
nginx-mailcow:
expose:
- "8080"
labels:
- "traefik.enable=true"
- "traefik.http.routers.nginx-mailcow.entrypoints=http"
- "traefik.http.routers.nginx-mailcow.rule=HostRegexp(`{host:(autodiscover|autoconfig|webmail|mail|email).+}`)"
- "traefik.http.middlewares.nginx-mailcow-https-redirect.redirectscheme.scheme=https"
- "traefik.http.routers.nginx-mailcow.middlewares=nginx-mailcow-https-redirect"
- "traefik.http.routers.nginx-mailcow-secure.entrypoints=https"
- "traefik.http.routers.nginx-mailcow-secure.rule=Host(`mail.example.com`)"
- "traefik.http.routers.nginx-mailcow-secure.tls=true"
- "traefik.http.routers.nginx-mailcow-secure.certresolver=http"
- "traefik.http.routers.nginx-mailcow-secure.service=nginx-mailcow"
- "traefik.http.services.nginx-mailcow.loadbalancer.server.port=8080"
- "traefik.docker.network=proxy"
networks:
proxy:
certdumper:
image: humenius/traefik-certs-dumper
container_name: traefik_certdumper
network_mode: none
command: --restart-containers mailcowdockerized_postfix-mailcow_1,mailcowdockerized_dovecot-mailcow_1
volumes:
- <path_to_acme.json_file_dir>:/traefik:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/assets/ssl:/output:rw
environment:
- DOMAIN=example.com
For people who are setting up for the first time, I had to make some additional changes beforehand.对于第一次设置的人,我必须事先进行一些额外的更改。
Firstly, when you run generate.sh file then in mailcow.conf file you need to make following changes:首先,当您运行 generate.sh 文件时,您需要在 mailcow.conf 文件中进行以下更改:
HTTP_PORT=8080 HTTP_PORT=8080
HTTP_BIND=127.0.0.1 HTTP_BIND=127.0.0.1
HTTPS_PORT=8443 HTTPS_PORT=8443
HTTPS_BIND=127.0.0.1 HTTPS_BIND=127.0.0.1
SKIP_LETS_ENCRYPT=y SKIP_LETS_ENCRYPT=y
SKIP_CLAMD=y SKIP_CLAMD=y
We make these changes as we can not run mailcow nginx on the same ports as traefik.我们进行这些更改是因为我们无法在与 traefik 相同的端口上运行 mailcow nginx。
Now as nginx-mailcow will be running on 8080 or 8443 so we need to expose one of these ports so traefik can talk to mailcow-nginx service.现在由于 nginx-mailcow 将在 8080 或 8443 上运行,所以我们需要公开这些端口之一,以便 traefik 可以与 mailcow-nginx 服务通信。 I already exposed port 8080 in the override compose file)
我已经在覆盖撰写文件中公开了端口 8080)
I hope this helps.我希望这有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.