Dovecot with virtual hosts and SSL - wrong certificate? - ssl

I'm trying to set up Dovecot with multiple vhosts using SSL.
I've set up my main domain (example.de) and for my vhosts (example2.com & example3.co.uk) I'm using the local -option.
My problem:
When I connect to my server, it complains about a wrong hostname
(example3.co.uk) on my main and other domain for the certificate.
How can I make dovecot use the correct certificate for each host?
Here's my dovecot config:
listen = *
ssl = yes
protocols = imap pop3
disable_plaintext_auth = no
auth_mechanisms = plain login
mail_access_groups = vmail
default_login_user = vmail
first_valid_uid = 2222
first_valid_gid = 2222
#mail_location = maildir:~/Maildir
mail_location = maildir:/home/vmail/%d/%n
passdb {
driver = passwd-file
args = scheme=SHA1 /etc/dovecot/passwd
}
userdb {
driver = static
args = uid=2222 gid=2222 home=/home/vmail/%d/%n allow_all_users=yes
}
service auth {
unix_listener auth-client {
group = postfix
mode = 0660
user = root
}
user = root
}
service imap-login {
process_min_avail = 1
user = vmail
}
ssl_cert = </etc/pki/tls/certs/example.de.crt
ssl_key = </etc/pki/tls/private/example.de.key
local ohmygodpresents.com {
ssl_cert = </etc/pki/tls/certs/example2.com.crt
ssl_key = </etc/pki/tls/private/example2.com.key
}
local ohmygodpresents.co.uk {
ssl_cert = </etc/pki/tls/certs/example3.co.uk.crt
ssl_key = </etc/pki/tls/private/example3.co.uk.key
}

How can I make dovecot use the correct certificate for each host?
Its not Dovecot per se.
The client needs to use TLS 1.0 or above, and it needs to utilize the Server Name Indication (SNI) extension. Otherwise, Dovecot does not know which virtual server the client is attempting to connect to when the channel is being set up.
You can duplicate/test it with OpenSSL s_client. For example, a "good" connection:
openssl s_client -tls1 -starttls smtp -connect mail.example.com:587 -servername mail.example.com
In the above example, Dovecot will know to send the certificate for example.com when the SSL/TLS connection is started. Even though a STARTTLS extension is used in mail, Dovecot does not know the virtual server because the RCPT command has not yet been sent. Because the RCPT command has not been sent, Dovecot does not know the user or his/her domain.
Here's a "bad" connection. Its SSLv3, so it cannot utilize SNI (SNI is a TLS extension):
openssl s_client -ssl3 -starttls smtp -connect mail.example.com:587
Here's another "bad" connection. Its TLS 1.0, but it does not utlize SNI:
openssl s_client -tls1 -starttls smtp -connect mail.example.com:587
You can also duplicate/test/observe with Wireshark. SNI is sent in the plain text as part of the ClientHello. So you will be able to see protocols, cipher suites, extensions like SNI, and other parameters. Everything in SSL/TLS's handshake and key exchange are plain text (some hand waiving). The plain text messages are integrity checked later when the Finished messages are sent.
You can disable SSLv2/SSLv3 and force TLS, and things will work as expected for most clients. However, a client does not have to send the SNI extension. Windows XP clients will be a problem - they utilize TLS 1.0 but omit SNI. So there's really no fix other than using a modern client.
Your other option is to create a "super certificate". That is, use a certificates with all the DNS names that the mail server serves. In your case, use one certificate with SANs of DNS:3und80.de, DNS:ohmygodpresents.co.uk, DNS:example1.com, etc. Every time you add a new domain or remove an existing domain, you will have to get a new certificate.

See https://doc.dovecot.org/configuration_manual/dovecot_ssl_configuration/
it is not
local domain.com { ...
it is
local_name domain.com { ...

Related

Python secure channel gRPC 'ssl_transport_security.cc:1807] No match found for server name' on remote instance

I have a Debian GCP instance that I'm trying to run a Python gRPC server. My instance has a static IP and I'm trying to establish a secure channel between my remote instance (server) and a local client.
I have generated self-signed OpenSSL certificates on the server and I am using the same certificates on the client. To generate I've used:
openssl req -newkey rsa:2048 -nodes -keyout ML.key -x509 -days 365 -out ML.crt
My server is set up like so (the .key and .crt files are loaded with an open as 'rb'):
server_credentials = grpc.ssl_server_credentials(((private_key, certificate_chain,),))
self.server.add_secure_port('0.0.0.0:%d' % self.port, server_credentials)
self.server.start()
My client is set up as:
host = '78.673.121.16' #this is the instance's static IP
port = 9063
certificate_chain = __load_ssl_certificate() #this loads the certificate file
# create credentials
credentials = grpc.ssl_channel_credentials(root_certificates=certificate_chain)
# create channel using ssl credentials
channel = grpc.secure_channel('{}:{}'.format(host, port), credentials)
and then I proceed to make a request.
At the server I am met with the following error, in response to my request:
E1017 17:21:22.964227087 1881 ssl_transport_security.cc:1807] No match found for server name: 78.673.121.16.
I have tried to change the Common Name (CN) of the certificate to localhost, 0.0.0.0 and 78.673.121.16 but to no avail.
Is there any suggestion?
I just had a similar problem, and was able to get it resolved finally. In my case I was hosting the server in a kubernetes cluster with a static ip and port. The key components of the solution were (in the server certificate):
Use the static IP address as the Common Name
Add the static IP address as a DNSName within the SubjectAlternativeName extension of the certificate
Step 2 turned out to be critical. In python (using grpc version 1.34.0) this was accomplished by:
from cryptography import x509
host = '78.673.121.16'
builder = x509.CertificateBuilder()
...
builder = builder.add_extension(x509.SubjectAlternativeName([x509.DNSName(host)]), critical=False)
try passing these options in secure_channel function call
options = {
'grpc.ssl_target_name_override' : 'localhost',
'grpc.default_authority': 'localhost'
}
channel = grpc.secure_channel('{}:{}'.format(host, port), credentials, options)
I have failed to find how to solve this and have opted to set up a permanent DNS for my instance instead. I was using GCP which, as of the time of writing, doesn't staightforwardly provide a way to assign this to an instance.
I switched to Azure, assigned the DNS to my instance and used that DNS and CN on my self-signed SSL certificate.
After that I changed the client (the server remains as originally) as:
host = 'myinstance.westus.azure.com' #this is the instance's DNS
port = 9063
This resolved my issue.

Invalid SSL Certificate for Mail Server

Though this question is in the context of a particular software (Discourse forum software), it is really about SSL certificates of mail servers.
Here is my setup:
Main Website: mydomain.com (Hosted on Hostgator)
Forum Website (Discourse forum software): forum.mydomain.com (Hosted on DigitalOcean)
Mail Server (used by Discourse to send email to members): mail.mydomain.com (Hosted on Hostgator)
Discourse settings for SMTP:
DISCOURSE_SMTP_ADDRESS: mail.mydomain.com
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: forum-no-reply#mydomain.com
DISCOURSE_SMTP_PASSWORD: "mypassword"
DISCOURSE_SMTP_ENABLE_START_TLS: true # (optional, default true)
I have SSL certificates set up for mydomain.com and mail.mydomain.com on Hostgator (A single SSL certificate for mydomain.com as well as several subdomains (like mail.mydomain.com, webmail.mydomain.com, etc)).
When I try to send a test email from the Discourse admin interface using the above settings, it gives me an 'invalid certificate' error.
So, I tried to debug through openssl s_client with the following command:
openssl s_client -servername mail.mydomain.com -starttls smtp -crlf -connect mail.mydomain.com:587
It sends the SSL certificate of mydomain.com with CN as follows
subject=CN = mydomain.com
and establishes a SSL Session with TLS v1.2
Here are the weird results of EHLO after that:
EHLO mail.mydomain.com
250-xx-xx-xx.webhostbox.net Hello forum.mydomain.com [xx.xx.xx.xx]
250-SIZE 52428800
250-8BITMIME
250-PIPELINING
250-AUTH PLAIN LOGIN
250 HELP
As you can see with the second line in the above code, it responds from xx-xx-xx.webhostbox.net instead of mail.mydomain.com or mydomain.com
I think this is why I'm getting a 'invalid certificate' error.
If I change the Discourse SMTP settings as below (just changing the first line)
DISCOURSE_SMTP_ADDRESS: xx-xx-xx.webhostbox.net
DISCOURSE_SMTP_PORT: 587
DISCOURSE_SMTP_USER_NAME: forum-no-reply#mydomain.com
DISCOURSE_SMTP_PASSWORD: "mypassword"
DISCOURSE_SMTP_ENABLE_START_TLS: true # (optional, default true)
then everything works fine and all emails gets sent.
Could someone please let me know if this working solution is secure? I think it's not secure since I am using xx-xx-xx.webhostbox.net as SMTP address (which could expose the emails to risks) instead of mail.mydomain.com. If this is not secure, how should I proceed to get a secure solution to this problem?
As documented by Hostgator it is actually the correct setup to use the name of the hostgator server full.servername.com and NOT the name of your own domain example.com as the mail server. This is because the mail server is not specific to your domain but is a common mail server for multiple domains.
Note that this is very similar to Can't seem to connect to FTPS via Atom editor Remote FTP but only for SMTP not FTP. My explanation there can be applied to SMTP too.

Akka.NET TLS implementaion

I'm following https://getakka.net/articles/remoting/security.html documentation to implement TLS Secured communication using an Akka.Net cluster.
I have generated a self-signed certificate using IIS and imported the certoficate TheCertifcate.pfx to Local Computer/Trusted Root Certification Authorities. The certificate is listed there now.
I need to know how to use the certificate path
remote {
dot-netty.tcp {
hostname = "localhost"
port = XXXX
enable-ssl = true
log-transport = true
ssl {
suppress-validation = true
certificate {
# valid ssl certificate must be installed on both hosts
path = "C:\\Workspace\\CertficateUtils\\TheCertificate.pfx"
password = "thepassword"
}
}
}
}
What am I supposed to use in path?
Short answer The path will be just like above.
Long answer The path is the physical folder path where you save the self-signed certificate. In my case "C:\\Workspace\\CertficateUtils\\TheCertificate.pfx". You need to import this certificate to Local Computer/ Trusted Root Certification Authorities though.
But the above configuration is NOT ENOUGH to make an Akka.NET Actor System communicate with SSL encryption.
We need to specify the transport protocol as ssl where we specify actor node addresses.
That is in the hocon configurations or in code where we use any node adress like
"akka.tcp://lighthouse#127.0.0.1:port", "akka.tcp://RemoteSystem#127.0.0.1:port"
need to be updated to
"akka.ssl.tcp://lighthouse#127.0.0.1:port", "akka.ssl.tcp://RemoteSystem#127.0.0.1:port"
where akka.ssl.tcp is the transport protocol.

LDAPS not working in Samba 4.3.11-Ubuntu

I'm running Samba 4.3.11-Ubuntu on Ubuntu 16.04, and I'm unable to get LDAPS (port 636) to work at all.
Samba is running as an Active Directory Domain Controller, and other AD DC fncitonality seems to be fine.
This used to work, but now there's nothing listening on that port. I'm not sure what I did to break it, but it stopped working after I updated my server with a trusted certificate.
Here's what I have for /etc/samba/smb.conf:
# Global parameters
[global]
workgroup = AD
realm = AD.<redacted>.COM
netbios name = SAMBADC
server role = active directory domain controller
dns forwarder = 8.8.8.8
idmap_ldb:use rfc2307 = yes
tls enabled = yes
tls keyfile = tls/ad.<redacted>.com.key
tls certfile = tls/c7535fc6c5e8e557.crt
tls cafile = tls/gd_bundle-g2-g1.crt
ldap server require strong auth = allow_sasl_over_tls
[netlogon]
path = /var/lib/samba/sysvol/ad.<redacted>.com/scripts
read only = No
[sysvol]
path = /var/lib/samba/sysvol
read only = No
The error I'm getting is:
nitsadmin#sambadc:/etc/samba$ telnet localhost 636
Trying 127.0.0.1...
Trying ::1...
telnet: Unable to connect to remote host: Cannot assign requested address
Anyone have any idea why this might not work? Any idea what Cannot assign requested address means?
Could you please provide a log file which is specified in your smb.conf parameter log file = while you start the samba service?
There could be something wrong with your certificates.
One thing you could try is to switch to autogenerated self-signed certificate and see if it solves the issue. If it does - you have to fix your certificates.
To do this, remove all certificates from tls folder and reconfigure smb.conf:
tls enabled = yes
tls keyfile = tls/key.pem
tls certfile = tls/cert.pem
tls cafile = tls/ca.pem
Then restart samba service and see if it helps.

Unable to send mail to local SMTP server with TLS

So we have a local exchange server that we use as a SMTP server for our internal servers. I'm trying to fix so it works with TLS but right now it's not.
I have a wildcard certificate assigned to both SMTP and the IIS roles. But When I try to use send-mailmessage through PowerShell for example I am getting.
Send-MailMessage -SmtpServer mail.domain.com -UseSsl -port 465 -From fromaddress
-To tomailaddress -Subject test -BodyAsHtml test -Encoding ([System.Text.Encoding]::UTF8)
The remote certificate is invalid according to the validation procedure.
The certificate used is valid for me when I go to the IIS site (or any other site that uses the same certificate).
So what am I doing wrong? Or how can I troubleshoot this.
Keep noted that the SSL certificate for SMTP couldn´t be managed with the IIS. You need to use powershell here (Enable-ExchangeCertificate) [more infos here].
Example:
Enable-ExchangeCertificate -Thumbprint
434AC224C8459924B26521298CE8834C514856AB -Services SMTP
In general you can troubleshoot such a TLS connection (over port 465) with Openssl (see here for a howto).
The URL also has also some solutions in place, so I will not copy them all here. In general the issues are:
The SSL certificate isn´t fully trusted on the remote machine (or in the keystore, which didn´t apply to your powershell test, but might apply to your 3rd party software)
There is still a self signed SSL certificate in use with SMTP
Conclusion:
I think you still use a self signed ssl certificate on the SMTP port and should change that with the command above.
I had the same issue. First I used the below code to save a copy of the certificate used by the SMTP server (since I didn't have access to the server itself / even if you do have access, this shows which server's being presented so may flag if it's different to what you'd expected). I ran this via LinqPad5 as a c# Program.
void Main()
{
System.Net.ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(OutputCertificateCallback);
using (System.Net.Mail.SmtpClient S = new System.Net.Mail.SmtpClient("smtprelay.subdomain.example.com"))
{
S.EnableSsl = true;
using (System.Net.Mail.MailMessage M = new System.Net.Mail.MailMessage("john.bevan#example.com", "john.bevan#example.com", "Test", "Test"))
{
try
{
S.Send(M);
Console.WriteLine("Sent");
}
catch (Exception e)
{
Console.WriteLine("Error {0}", e);
}
}
}
}
private bool OutputCertificateCallback(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
Console.WriteLine(certificate);
System.IO.File.WriteAllBytes(#"C:\Temp\cert.cer", certificate.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert));
var c2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(certificate);
return c2.Verify();
}
I was then able to inspect the certificate by viewing the saved file: C:\Temp\cert.cer
Check the expiry date to ensure the certificate is valid.
If it's not, that's the problem. Get a new certificate.
Check that the root certificate in my client's trusted CAs:
Start, Run, MMC
File > Add/Remove SnapIn > Certificates > Add > My User Account > Finish > OK
Certificates - Current User > Trusted Root Certificate Authorities > Certificates
Search for the root CA (i.e. the one with the same name as your certificate) in this list
If it's not you may need to install the root CA, the intermediary CA, or the certificate itself (which you can do using the file you just saved using the above script).
Check that the port is open on the firewall. You can test this via the below PowerShell:
try {
$tcp = New-Object -TypeName 'system.net.sockets.tcpclient' -ArgumentList 'smtprelay.subdomain.example.com', 465
if ($tcp.Connected) {':)'} else {':('}
} catch {
':('
$_.Exception.Message
}
In my case, all of the above weren't enough to spot the issue. Eventually I realised the service used a wildcard certificate (e.g. *.example.com), but the mail server was on a subdomain (e.g. smtprelay.subdomain.example.com) so wasn't covered by this certificate. Using a wildcard on the subdomain (e.g. *.subdomain.example.com) would have worked; though we just requested that the service be given an explicitly named certificate (for smtprelay.subdomain.example.com), including the service's individual nodes' FQDNs as Subject Alternative Names, in case we ever needed to target a specific node for debugging.