I met an issue while setting up IMAP email server with postfix, so I used letsencrypt to generate the certificates, and sending/receiving email works just fine.
But while I try to setup IMAP protocol with dovecot, I got errors like:
Jul 5 16:00:27 oraclecloud dovecot: imap-login: Error: Failed to initialize SSL server context: Can't load SSL certificate (ssl_cert setting): There is no valid PEM certificate.: user=<>, rip=37.xx.23x.xx, lip=10.0.0.200, session=<nev7qL7//xwl5O0s>
Jul 5 16:00:27 oraclecloud dovecot: auth: Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth
Jul 5 16:00:27 oraclecloud dovecot: auth: Debug: Module loaded: /usr/lib/dovecot/modules/auth/lib20_auth_var_expand_crypt.so
Jul 5 16:00:27 oraclecloud dovecot: auth: Debug: Read auth token secret from /run/dovecot/auth-token-secret.dat
This error Can't load SSL certificate (ssl_cert setting): There is no valid PEM certificate.
looks weird to me, because I do have a valid PEM certificate, under
/etc/letsencrypt/live/$mydomain_name/fullchain.pem
Output:
ubuntu@oraclecloud:~$ openssl s_client -servername $mydomain_name -connect $mydomain_name:993
CONNECTED(00000003)
write:errno=104
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 0 bytes and written 314 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)
---
/etc/postfix/main.cf
aaron@oraclecloud:~$
ubuntu@oraclecloud:~$ sudo cat /etc/postfix/main.cf
# See /usr/share/postfix/main.cf.dist for a commented, more complete version
# Debian specific: Specifying a file name will cause the first
# line of that file to be used as the name. The Debian default
# is /etc/mailname.
#myorigin = /etc/mailname
smtpd_banner = $myhostname ESMTP $mail_name (Ubuntu)
biff = no
# appending .domain is the MUA's job.
append_dot_mydomain = no
# Uncomment the next line to generate "delayed mail" warnings
#delay_warning_time = 4h
readme_directory = no
# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
# fresh installs.
compatibility_level = 3.6
# TLS parameters
smtpd_tls_cert_file = /etc/letsencrypt/live/$mydomain/fullchain.pem
smtpd_tls_key_file = /etc/letsencrypt/live/$mydomain/privkey.pem
smtpd_tls_security_level = encrypt
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_CAfile=/etc/ssl/certs/ca-certificates.crt
smtp_tls_security_level = encrypt
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtpd_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/password
smtp_sasl_security_options =
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
myhostname = $mydomain
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
mydestination = $mydomain, localhost
relayhost =
mynetworks = *0/24
mailbox_size_limit = 0
recipient_delimiter = +
ubuntu@oraclecloud:~$ sudo cat /etc/dovecot/dovecot.conf
disable_plaintext_auth = yes
mail_privileged_group = mail
mail_location = maildir:~/Maildir
#set mailbox location to Maildir style
userdb {
driver = passwd
}
passdb {
args = %s
driver = pam
}
protocols = "imap"
namespace inbox {
inbox = yes
mailbox Trash {
auto = subscribe
special_use = \Trash
}
mailbox Sent {
auto = subscribe
special_use = \Sent
}
mailbox Drafts {
auto = subscribe
special_use = \Drafts
}
mailbox Spam {
auto = subscribe
special_use = \Junk
}
mailbox Archive {
auto = subscribe
special_use = \Archive
}
}
#create and autosubscribe to some default folders
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
ssl = required
ssl_cert = /etc/letsencrypt/live/$mydomain/fullchain.pem
ssl_key = /etc/letsencrypt/live/$mydomain/privkey.pem
# debugging
mail_debug = yes
auth_debug = yes
auth_verbose = yes
auth_verbose_passwords = plain
auth_debug_passwords = yes
#
10-ssl.conf
##
## SSL settings
##
# SSL/TLS support: yes, no, required. <doc/wiki/SSL.txt>
ssl = required
# PEM encoded X.509 SSL/TLS certificate and private key. They're opened before
# dropping root privileges, so keep the key file unreadable by anyone but
# root. Included doc/mkcert.sh can be used to easily generate self-signed
# certificate, just make sure to update the domains in dovecot-openssl.cnf
# ssl_cert = </etc/dovecot/private/dovecot.pem
# ssl_key = </etc/dovecot/private/dovecot.key
ssl_cert = </etc/letsencrypt/live/$mydomain/fullchain.pem
ssl_key = </etc/letsencrypt/live/$mydomain/privkey.pem
ssl_protocols = !SSLv2 !SSLv3
# If key file is password protected, give the password here. Alternatively
# give it when starting dovecot with -p parameter. Since this file is often
# world-readable, you may want to place this setting instead to a different
# root owned 0600 file by using ssl_key_password = <path.
#ssl_key_password =
# PEM encoded trusted certificate authority. Set this only if you intend to use
# ssl_verify_client_cert=yes. The file should contain the CA certificate(s)
# followed by the matching CRL(s). (e.g. ssl_ca = </etc/ssl/certs/ca.pem)
ssl_ca = /etc/ssl/certs/ssl-cert-snakeoil.pem
# Require that CRL check succeeds for client certificates.
#ssl_require_crl = yes
# Directory and/or file for trusted SSL CA certificates. These are used only
# when Dovecot needs to act as an SSL client (e.g. imapc backend or
# submission service). The directory is usually /etc/ssl/certs in
# Debian-based systems and the file is /etc/pki/tls/cert.pem in
# RedHat-based systems. Note that ssl_client_ca_file isn't recommended with
# large CA bundles, because it leads to excessive memory usage.
#ssl_client_ca_dir =
ssl_client_ca_dir = /etc/ssl/certs
#ssl_client_ca_file =
# Require valid cert when connecting to a remote server
#ssl_client_require_valid_cert = yes
# Request client to send a certificate. If you also want to require it, set
# auth_ssl_require_client_cert=yes in auth section.
#ssl_verify_client_cert = no
# Which field from certificate to use for username. commonName and
# x500UniqueIdentifier are the usual choices. You'll also need to set
# auth_ssl_username_from_cert=yes.
#ssl_cert_username_field = commonName
# SSL DH parameters
# Generate new params with `openssl dhparam -out /etc/dovecot/dh.pem 4096`
# Or migrate from old ssl-parameters.dat file with the command dovecot
# gives on startup when ssl_dh is unset.
ssl_dh = </usr/share/dovecot/dh.pem
# Minimum SSL protocol version to use. Potentially recognized values are SSLv3,
# TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3, depending on the OpenSSL version used.
#
# Dovecot also recognizes values ANY and LATEST. ANY matches with any protocol
# version, and LATEST matches with the latest version supported by library.
#ssl_min_protocol = TLSv1.2
# SSL ciphers to use, the default is:
#ssl_cipher_list = ALL:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
# To disable non-EC DH, use:
#ssl_cipher_list = ALL:!DH:!kRSA:!SRP:!kDHd:!DSS:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!PSK:!RC4:!ADH:!LOW@STRENGTH
# Colon separated list of elliptic curves to use. Empty value (the default)
# means use the defaults from the SSL library. P-521:P-384:P-256 would be an
# example of a valid value.
#ssl_curve_list =
# Prefer the server's order of ciphers over client's.
#ssl_prefer_server_ciphers = no
# SSL crypto device to use, for valid values run "openssl engine"
#ssl_crypto_device =
# SSL extra options. Currently supported options are:
# compression - Enable compression.
# no_ticket - Disable SSL session tickets.
#ssl_options =