docker-mailserver: Using Let's encrypt certs obtained with Caddy, not working so far

Context

I am trying to setup this project, everything seems to work but tls certificates. I use Caddy to renew automatically Let’s Encrypt certificates (private.key and public.crt). I have digged into existing issues but haven’t found an answer really.

The container has hostname mail and DNS configuration also uses mail for the FQDN. I use the environment variables:

SSL_TYPE=manual
SSL_CERT_PATH=/tmp/ssl/cert/public.crt
SSL_KEY_PATH=/tmp/ssl/private/private.key

With my docker-compose.yml volumes as

- ../caddy/data/acme/acme-v02.api.letsencrypt.org/sites/mail.domain.tld/mail.domain.tld.crt:/tmp/ssl/cert/public.crt:ro
- ../caddy/data/acme/acme-v02.api.letsencrypt.org/sites/mail.domain.tld/mail.domain.tld.key:/tmp/ssl/private/private.key:ro

And verified with docker exec that these are present and right, and also copied properly to /etc/postfix/ by the startup script.

All ports are also port forwarded on my router, DNS settings should be correct as well.

Expected Behavior

  1. Running docker exec mail openssl s_client -connect 0.0.0.0:25 -starttls smtp -CApath /etc/ssl/certs/ should give some certificates information and no error
  2. Logging in with my Gmail Android app should not fail, using username@mail.domain.tld, IMAP, with incoming and outgoing username and server as username@domain.tld and mail.domain.tld respectively.

Actual Behavior

  1. Gives the following message:

    CONNECTED(00000003)
    140342221178112:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:ssl/record/rec_layer_s3.c:1543:SSL alert number 40
    ---
    no peer certificate available
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 294 bytes and written 326 bytes
    Verification: OK
    ---
    New, (NONE), Cipher is (NONE)
    Secure Renegotiation IS NOT supported
    Compression: NONE
    Expansion: NONE
    No ALPN negotiated
    Early data was not sent
    Verify return code: 0 (ok)
    ---
    
  2. I get the warning message in my app Email security not guaranteed... The highest security available may not be supported. In the Docker logs I get (all at the same second I try to login):

    mail postfix/submission/smtpd[2064]: connect from er4.x[192.168.2.1]
    mail postfix/submission/smtpd[2064]: SSL_accept error from er4.x[192.168.2.1]: -1
    mail postfix/submission/smtpd[2064]: warning: TLS library problem: error:1417A0C1:SSL routines:tls_post_process_client_hello:no shared cipher:../ssl/statem/statem_srvr.c:1419:
    mail postfix/submission/smtpd[2064]: lost connection after STARTTLS from er4.x[192.168.2.1]
    mail postfix/submission/smtpd[2064]: disconnect from er4.x[192.168.2.1] ehlo=1 starttls=0/1 commands=1/2
    mail postfix/submission/smtpd[2064]: connect from er4.x[192.168.2.1]
    mail postfix/submission/smtpd[2064]: lost connection after UNKNOWN from er4.x[192.168.2.1]
    mail postfix/submission/smtpd[2064]: disconnect from er4.x[192.168.2.1] unknown=0/2 commands=0/2
    

Possible Fix

  • The certs are definitely picked up by postfix as if I give another domain certs, I will obtain a warning in my Gmail app about it being for another domain.
  • The certificate (public.crt) contains two certificates (two BEGIN CERTIFICATE), is this expected
  • The private key (private.key) is an EC key

Steps to Reproduce

Try using certificates obtained from Caddy and its Lets encrypt implementation. There might be an issue with my configuration as well.

Your Environment

  • Amount of RAM available:
  • Mailserver version used: latest (pulled 2 days ago)
  • Docker version used: 19.03.5-ce

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 5
  • Comments: 27 (10 by maintainers)

Most upvoted comments

For people using Caddy and/or EC keys (@hoerbi1000), you need to use RSA keys.

I changed my Caddyfile to have

https://mail.domain.com {
    tls yourcurrentemail@gmail.com {
        key_type  rsa2048
    }
}

such that RSA keys are obtained from Let’s encrypt and auto-renewed.

In my docker-compose.yml for docker-mailserver, I bind mount them directly:

volumes:
  - ../caddy/data/acme/acme-v02.api.letsencrypt.org/sites/mail.domain.com/mail.domain.com.crt:/tmp/ssl/cert/public.crt:ro
  - ../caddy/data/acme/acme-v02.api.letsencrypt.org/sites/mail.domain.com/mail.domain.com.key:/tmp/ssl/private/private.key:ro

Then restarting the container and running the following works as expected:

docker exec -ail popenssl s_client -starttls smtp -crlf -connect localhost:25

Before closing the issue, one last little question: @casperklein it seems you are using EC keys, any idea why my self signed generated EC key mentioned above does not work?

Thanks!

TL;DR: key_type rsa2048 works, make sure to have an updated docker image. I use the stable tag

Hi! I tried the trick with key_type rsa2048 and it didn’t work, so I got back to the paid certificate. But, today, my paid certificate expired… So I had to find a solution again, pay and update every year, or let LE with Caddy deal with it. Reading my posts on the forum made me think my docker image hasn’t been updated/pulled in a while. So maybe I had an incompatible OpenSSL lib on it. I updated it with docker pull. After updating my Caddyfile, the certificate didn’t update to rsa2048. I figured it was because it has been created recently, and didn’t feel it needed updating. And caddy (v1) didn’t get the difference in key_type between execution needed a request to LE. So I deleted the previously generated LE certs from /root/.caddy/acme folder and started caddy again. I referenced the newly LE generated certs with rsa2048 from Caddy in my mail configuration, and BOOM, it works.

Thanks all!

Any progress with this one? For example, would it be possible to test manually generated EC test certificates or to change Caddy to use RSA certificates? It would be nice to find the root cause here.

Is it possible to use RSA certificates with Caddy? They are far more common, so perhaps the use of an EC certificate is the problem? Postfix 2.6+ should support it, but one never knows.

That is my basic test setup: removed

  1. extract to /test or adjust paths in docker-compose.yml
  2. run docker-compose up
  3. test: docker exec mail openssl s_client -starttls smtp -crlf -connect localhost:25

It seems also that at least 2 other people had the same issue as me with Caddy

IMHO it’s a problem with the certificates obtained with Caddy.

Hi @erik-wramner thanks for your reply!

Running the command returns the same error message, even with TLS_LEVEL=intermediate:

docker exec mail openssl s_client -starttls smtp -crlf -connect mail.domain.com:25
140279144157248:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../ssl/record/rec_layer_s3.c:1407:SSL alert number 40
CONNECTED(00000003)
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 251 bytes and written 209 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1586015524
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

I also verified files are as expected with:

docker exec mail cat /etc/postfix/ssl/cert
docker exec mail cat /etc/postfix/ssl/key

Maybe the key/certificate format is not compatible with postfix? Would you know the openssl command to verify that perhaps? Thanks!

@qdm12 i have the same issue with caddy and mailserver.

my docker-compose looks like this:

mail:
    image: tvial/docker-mailserver:latest
    restart: always
    hostname: mail
    domainname: domain.tld
    container_name: mail
    ports:
      - "25:25"
      - "143:143"
      - "587:587"
      - "993:993"
      - "4190:4190"
    volumes:
      - ./data/mail/data:/var/mail
      - ./data/mail/state:/var/mail-state
      - ./data/config:/tmp/docker-mailserver/
      - /etc/localtime:/etc/localtime:ro
      - /home/app/main/data/caddycerts/acme/acme-v02.api.letsencrypt.org/sites/mail.domain.tld:/tmp/ssl:ro
    environment:
            #- ENABLE_SPAMASSASSIN=1
      - ENABLE_CLAMAV=1
      - ENABLE_FAIL2BAN=1
      - ENABLE_POSTGREY=1
      - ONE_DIR=1
      - DMS_DEBUG=0
      - ENABLE_MANAGESIEVE=1
      - SSL_TYPE=manual
      - SSL_CERT_PATH=/tmp/ssl/mail.domain.tld.crt
      - SSL_KEY_PATH=/tmp/ssl/mail.domain.tld.key
      - POSTFIX_INET_PROTOCOLS=ipv4
      - PERMIT_DOCKER=connected-networks
    networks:
     - mail_nw
    cap_add:
      - NET_ADMIN