Can I set a different certificate per listen port?
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
On 27/04/2022 22:14 Kees van Vloten <keesvanvloten@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
Op 28-04-2022 om 07:30 schreef Aki Tuomi:
On 27/04/2022 22:14 Kees van Vloten <keesvanvloten@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
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 postfix outgoing test for reference.
- OK [CAPABILITY IMAP4rev1 SASL-IR LOGIN-REFERRALS ID ENABLE IDLE LITERAL+ AUTH=PLAIN AUTH=LOGIN] SCOM.CA Internet Services Inc. - Dovecot ready
# 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@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
participants (3)
-
Aki Tuomi
-
Kees van Vloten
-
Paul Kudla (SCOM.CA Internet Services Inc.)