Can I set a different certificate per listen port?
Paul Kudla (SCOM.CA Internet Services Inc.)
paul at scom.ca
Thu Apr 28 10:48:21 UTC 2022
Technically yes (under 2.3.18 & SNI Support)
here is my sni.conf file it is imported at the end of my dovecot.conf
basically sni allows for multiple different certificates inside dovecot
please note each domain (or subdomain) config below
most of this was provided via
https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/
in dovecot.conf (at the end)
#Addition ssl config
!include sni.conf
then make an sni.conf file adjust to your certificate / ssl needs etc
# cat sni.conf
#sni.conf
ssl = yes
verbose_ssl = yes
ssl_dh =</usr/local/etc/dovecot/dh-4096.pem
ssl_prefer_server_ciphers = yes
#ssl_min_protocol = TLSv1.2
#Default *.scom.ca
ssl_key =</usr/local/etc/dovecot/scom.pem
ssl_cert =</usr/local/etc/dovecot/scom.pem
ssl_ca =</usr/local/etc/dovecot/scom.pem
local_name .scom.ca {
ssl_key = /programs/common/getssl.cert -c *.scom.ca -q yes
ssl_cert = /programs/common/getssl.cert -c *.scom.ca -q yes
ssl_ca = /programs/common/getssl.cert -c *.scom.ca -q yes
}
local_name mail.clancyca.com {
ssl_key = /programs/common/getssl.cert -c mail.clancyca.com -q yes
ssl_cert = /programs/common/getssl.cert -c mail.clancyca.com -q yes
ssl_ca = /programs/common/getssl.cert -c mail.clancyca.com -q yes
}
local_name secure.clancyca.com {
ssl_key = /programs/common/getssl.cert -c secure.clancyca.com -q yes
ssl_cert = /programs/common/getssl.cert -c secure.clancyca.com -q yes
ssl_ca = /programs/common/getssl.cert -c secure.clancyca.com -q yes
}
Also note this is for incomming only connections
port should not matter sni matches the incoming dns name from the sni
compatible client (thunderbird for example)
however do a telent to ip <port> to make sure there is an active
listener on the port you are trying to use.
i already listen on 143 & 993 and this works for both.
Check for dovecot
# telnet localhost 143
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE
LITERAL+ STARTTLS AUTH=PLAIN AUTH=LOGIN] SCOM.CA Internet Services Inc.
- Dovecot ready
# imap service over SSL/TLS
openssl s_client -connect imap_dns_server_name_or_ip:993
note : imap_dns_server_name_or_ip is the actual name of the certificate
you are trying to test for.
note when run you will/should get all the certificate stuff and it
should then end with something like above :
read R BLOCK
* OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE
LITERAL+ AUTH=PLAIN AUTH=LOGIN] SCOM.CA Internet Services Inc. - Dovecot
ready
postfix outgoing test for reference.
# telnet localhost 465
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
220 mail18.scom.ca ESMTP Postfix
// Send EHLO servername gives what the server can do.
EHLO scom.ca
250-mail18.scom.ca
250-PIPELINING
250-SIZE 1000000000
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250-DSN
250-SMTPUTF8
250 CHUNKING
sni only works if the mail client supports it so you need to run a mail
client less then a few years old.
sni was developed with a lot of hit and misses and little documentation,
and is still kinda being debugged but does work without issue for the
most part inside postfix & dovecot.
i dont believe cyrus and others are fully supporting sni which makes
this kinda a nice thing dovecot support wise - thanks to the developers.
Also note postfix also supports sni which needs to be setup seperately
if used for outgoing emails.
main.cf
#SSL SNI
tls_server_sni_maps = hash:/usr/home/postfix/config/sni
smtpd_tls_chain_files = /etc/ssl/.scom.ca
smtpd_tls_CApath = /etc/ssl/certs
# cat sni.good
.scom.ca /etc/ssl/postfix.pem.scom
secure.mail.elirpa.com /etc/ssl/postfix.pem.elirpa
please note . at front indicates a *.scom.ca (for wildcard cert example
above)
also note sni must be hashes into a sni.db file for postfix to be used
/usr/local/sbin/postmap -c /usr/home/postfix/config -F
/usr/home/postfix/config/sni
will make the hash file from sni (text file)
please note i use pgsql database to store the certs etc hence the
/programs/common/getssl.cert -c mail.clancyca.com -q yes
it is from a django instance
text files would still be loaded with the < (pipe from file command)
both samples are noted above.
here is the python script i use to generate the dovecot ssl stuff
# cat /programs/common/getssl.cert
#!/usr/local/bin/python3
#update the ssl certificates for this mail server
import sys
import os
import string
import psycopg2
from optparse import OptionParser
USAGE_TEXT = '''\
usage: %%prog %s[options]
'''
parser = OptionParser(usage=USAGE_TEXT % '', version='0.4')
parser.add_option("-c", "--cert", dest="cert", help="Domain Certificate
Requested")
parser.add_option("-k", "--key", dest="key", help="Domain Key Requested")
parser.add_option("-r", "--crt", dest="crt", help="Domain CRT Requested")
parser.add_option("-s", "--csr", dest="csr", help="Domain CSR Requested")
parser.add_option("-i", "--inter", dest="inter", help="Domain INTER
Requested")
parser.add_option("-x", "--pem", dest="pem", help="Domain Pem Requested")
parser.add_option("-q", "--quiet", dest="quiet", help="Quiet")
options, args = parser.parse_args()
#print (options.quiet)
if options.cert != None :
ssl = options.cert
if options.quiet == None :
print ('\nGetting Full Pem Certificate : %s\n'
%options.cert)
if options.key != None :
ssl = options.key
if options.quiet == None :
print ('\nGetting Key Certificate : %s\n' %options.key)
if options.crt != None :
ssl = options.crt
if options.quiet == None :
print ('\nGetting CRT Certificate : %s\n' %options.crt)
if options.csr != None :
ssl = options.csr
if options.quiet == None :
print ('\nGetting CSR Certificate : %s\n' %options.csr)
if options.inter != None :
ssl = options.inter
if options.quiet == None :
print ('\nGetting Inter Certificate : %s\n' %options.inter)
if options.pem != None :
ssl = options.pem
if options.quiet == None :
print ('\nGetting Pem Certificate : %s\n' %options.pem)
#sys.exit()
#from lib import *
#print ('Opening the Database ....')
conn = psycopg2.connect(host='localhost', port = 5433,
database='db_table', user='pgsql', password='password')
pg = conn.cursor()
#print ('Connected !')
#Ok now go get the email keys
command = ("""select domain,ssl_key,ssl_cert,ssl_csr,ssl_chain from
email_ssl_certificates where domain = $$%s$$ """ %ssl)
#print (command)
pg.execute(command)
certs = pg.fetchone()
#print (certs)
#ok from here we have to decide the output ?
domain = certs[0]
if options.cert != None :
key = '#SSL Pem file (Key / Certificate / Intermediate) for
%s\n\n#Key\n\n' %domain + certs[1] + '\n\n#Certificate\n' + certs[2] +
'\n\n#Intermediate\n' + certs[4]
if options.key != None :
key = '#SSL Key file for %s\n\n' %domain + certs[1]
if options.crt != None :
key = '#SSL CERT file for %s\n\n' %domain + certs[2]
if options.csr != None :
key = '#SSL CSR Request file for %s\n\n' %domain + certs[3]
if options.inter != None :
key = '#SSL Intermediate file for %s\n\n' %domain + certs[4]
if options.pem != None :
key = '#SSL Pem (Certificate / Intermediate) file for
%s\n\n#Certificate\n\n' %domain + certs[2] + '\n\n#Intermediate\n' +
certs[4]
key = key.replace('\r','')
print (key)
conn.close()
sys.exit()
Happy Thursday !!!
Thanks - paul
Paul Kudla
Scom.ca Internet Services <http://www.scom.ca>
004-1009 Byron Street South
Whitby, Ontario - Canada
L1N 4S3
Toronto 416.642.7266
Main 1.866.411.7266
Fax 1.888.892.7266
On 4/28/2022 4:01 AM, Kees van Vloten wrote:
>
>
> Op 28-04-2022 om 07:30 schreef Aki Tuomi:
>>> On 27/04/2022 22:14 Kees van Vloten <keesvanvloten at gmail.com> wrote:
>>>
>>> Hi all,
>>>
>>> I am trying to setup dovecot to listen to imaps on the local network and
>>> through haproxy from the internet.
>>>
>>> service imap-login {
>>> inet_listener imaps {
>>> port = 993
>>> ssl = yes
>>> }
>>> inet_listener imaps_haproxy {
>>> haproxy = yes
>>> port = 10993
>>> ssl = yes
>>> }
>>> }
>>>
>>> Obviously the dns-name on the internet connection (10993) is different
>>> than on the lan (993).
>>>
>>> In the docs
>>> (https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/)
>>>
>>> I found multiple options, but unfortunately none of those have the
>>> option to distinguish per listen port.
>>>
>>> Is there a way to setup two different certificates for the two
>>> listeners?
>>>
>>> - Kees
>> Hi!
>>
>> Currently port is not supported. What we usually recommend here is
>> that you use haproxy to distribute connections to different local IP
>> addresses and use
>>
>> local 127.0.0.5/32 {
>> ssl_cert=</path
>> ssl_key=</path
>> }
>>
>> Aki
>
> Hi Aki,
>
> Would it then look like this?
>
>
> Internet -> haproxy on dmz-server -> haproxy on mailserver -> dovecot on
> 127.0.0.5
>
>
> - Kees
>
>
>
>
More information about the dovecot
mailing list