Closed ilf closed 4 years ago
For such corner cases you can use the existing tls_fingerprint
.
Thanks. I am using tls_fingerprint
extensively, but it achieves a different goal. It pins a single certificate to a single host. (From the manual: "Set the fingerprint of a single certificate to accept for TLS.")
That is great, but limited. It can be desirable to use the "standard X.509" verification - with a manual hostname.
Certificate validity periods are getting ever shorter, Let's Encrypt currently has 90 days. Every time the certificate is renewed, the fingerprint changes and I have to re-set tls_fingerprint
. This feature would keep the same setting even over certificate renewals - as long as hostname and $tls_trust_file
stay the same.
Some mail-providers have multiple servers for the same service, and sometimes each of these servers has their own certificate. But pinning only works with one cert. This feature would work with multiple certs. (This is a real-world use-case I actually currenty have.)
Yes, tls_fingerprint
is limited. But I would argue that a TLS setup where the host name does not match the server certificate is simply broken (i.e. it violates the TLS specification), and therefore not worth implementing a special workaround for.
I'm not sure I understand. Using tls_fingerprint
also ignores the hostname in the server certificate (from the manual: "This certificate will be trusted regardless of its contents (this overrides tls_trust_file
)."
Also, the TLS specification doesn't say anything about hostnames.
I'd be interested: How would you verify the certificate when using an IP-address or an onion-address, when fingerprint pinning is not viable?
I have shown that other software uses the proposal I made.
When you connect to a TLS server, you have to check that 1) you trust the certificate and 2) you really are connected to the server you intended to connect to. 2) typically means that you check the host name against the names in the certificate (RFC 6125). If it is not in there, you cannot trust the connection. I argue that a server that requires a workaround in this regard is misconfigured.
Everything you're saying is true, and known to me.
I am not trying to use a misconfigured server. My server mail.example.org
offers a valid certificate with its domain mail.example.org
in Common Name (or Alt Name). This works fine:
account test@example.org
host mail.example.org
tls_trust_file /etc/ca-certificates/extracted/cadir/DST_Root_CA_X3.pem
But in my client (mpop), I don't want to set host mail.example.org
. I would like to set host 192.0.2.0
(because I don't want to use DNS every few minutes, it never changes anyways) or host maildotexampledotorglongtorhiddenserviceaddress.onion
. And the TLS certificate doesn't include the IP or onion address (yet).
So far, I can either use pinning (but that only works for one server, and needs to be renewed and re-verified every 90 days), or disable TLS verification. Both are not desirable.
My proposal would do what everyone else does: verify the hostname the client knows against the hostname in the certificate. Only that the client doesn't get that value from "host", but from different variable.
I don't see how this would violate any standard. And, other software does it, too.
How would you verify a server with an onion-address?
Regarding the DNS lookup: you can use a cache on your local system to reduce DNS lookups.
Regarding IP adresses: while these can be in certificates, this is considered a corner case not worthy of much attention (RFC 6125).
Regarding onion adresses: i don't know about those. If they can be in certificates, then the problem is solved, is it not? And if they cannot be, there should be a standardized alternative, right?
Regarding other software: you mentioned unbound, but that use case is not for onion addresses; DNS-over-TLS really is a special case.
(My rationale for arguing in this way is that I want to avoid adding a feature and associated complexity for something only useful in corner cases for 1-3 users.)
I absolutely agree that unnecessary complexity should be avoided. That's why I'm using mpop/msmtp in the first place!
But I think that this proposal is simple and small. AFAICT, the hostname verification logic in tls.c
can mostly remain as-is. The local hostname value continues to default to host
, but if there is a $tls_verify_override_host
, take it from there. That's it. I'd try to code it myself, but my C is not sufficient.
If we're talking about "complexity for corner cases", I can see a few other candidates like source_ip
("Useful only in special cases on multi-home systems.") or ntlmdomain
("This is obsolete." :)
I have the same problem here. It's hard (and expensive) to get a valid TLS certificate for an onion address, I don't know of any email provider doing that.
Usually the TLS certificate is for the original hostname of the provider. For example using riseup.net pop server with onion address zsolxunfmbfuq7wf.onion you will get a certificate for the domain pop.riseup.net
.
Will be great to be able to override the domain that will be used to validate the certificate, or at least to disable the domain validation.
.onion
addresses are only one of the circumstances where "typical" DNS just doesn't work to identify the peer.
As @ilf says, another situation is where there's a desire avoid DNS lookups (that can be addressed with an entry in /etc/hosts
but that only works if you have administrative access).
Additionally, there are cases where a given host has multiple IP addresses backed by different servers, but the user has a specific reason to connect to one of those addresses specifically.
In other cases, the user is on a restrictive network and needs to resort to tunneling a connection to reach a machine on the public internet (e.g. via a forwarded ssh port).
It would be great if mpop-mirror
could work in all those cases.
I can see three possible ways to offer a solutionfor all the cases described above:
ProxyCommand
directive in OpenSSH)Hostname
directive in OpenSSH)--verify-hostname
parameter for gnutls-cli
)Any of these choices could be misused of course, but they're at least as reasonable to support as existing options that fiddle with security-related parameters (like --tls-min-dh-prime-bits
or --tls-cert-check=off
) for the sake of allowing connectivity.
It would be a mistake to encourage --tls-fingerprint
for this use case in the modern era of short-lived certificates, as it makes a brittle mpop configuration that needs frequent adjusting; each manual adjustment is an annoyance to the user, and an opportunity for a security failure.
OK, there are several new points in the comments:
If we're talking about "complexity for corner cases", I can see a few other candidates like source_ip ("Useful only in special cases on multi-home systems.") or ntlmdomain ("This is obsolete." :)
I agree that there are some obscure options in msmtp and mpop now, but that does not mean that adding even more is ok ;-)
As @ilf says, another situation is where there's a desire avoid DNS lookups (that can be addressed with an entry in /etc/hosts but that only works if you have administrative access).
Additionally, there are cases where a given host has multiple IP addresses backed by different servers, but the user has a specific reason to connect to one of those addresses specifically.
In other cases, the user is on a restrictive network and needs to resort to tunneling a connection to reach a machine on the public internet (e.g. via a forwarded ssh port).
It would be great if mpop-mirror could work in all those cases.
We already support SOCKS proxy, and there's stunnel. Is that not enough to support all these use cases? For example, stunnel
has the checkHost
option which looks like it does what the suggested tls_override_verify_host
option would do.
It's hard (and expensive) to get a valid TLS certificate for an onion address, I don't know of any email provider doing that.
Usually the TLS certificate is for the original hostname of the provider. For example using riseup.net pop server with onion address zsolxunfmbfuq7wf.onion you will get a certificate for the domain pop.riseup.net.
Isn't that the problem that should be solved? Convince Let's Encrypt (and/or others) to add support for onion addresses, and all software will just work. In contrast, adding workarounds to every single piece of software just because the correct solution is currently impracticable seems wrong, doesn't it?
Regarding the possibility to use basically any external program to set up the network connection, optionally including TLS, there is one thing that could help: support for UNIX domain sockets. These can be used e.g. with ssh and stunnel and offer file system level access restrictions (in contrast to SOCKS proxies or forwarded TCP ports). A request to add a socket
configuration command has come up in different contexts, and I am beginning to think that it is worth adding as there is no other way to implement some special configurations. I will push an initial version soon. Maybe this helps your situations, too?
I am not sure I fully understand the proposal. Can you provide a sample config how you imagine this setup with onion and TLS verification?
There might be other potential use-cases for a socket configuration. But for this problem the solutions @dkg proposed in https://github.com/marlam/mpop-mirror/issues/2#issuecomment-606146565 sound much simpler to me. And I like the KISS principle.
But maybe I'm missing something and a proposed config can help me understand.
TLS setup and verification would be handled by stunnel, including setting a custom host name for verification. Then msmtp/mpop can either connect to a TCP port provided by stunnel (to which other users can also connect), or to a local socket provided by stunnel (which can be subject to access restrictions).
So the socket option just makes this kind of thing more manageable, but not really simpler, since you still have two programs running.
I understand the simplest option from your point of view is to have a tls_verify_host
option. But why are onion addresses not in server certificates? I still feel this is the problem that should be addressed instead of changing all TLS client software to provide a workaround.
Let's Encrypt is working on support for onions, but it's not there yet.
But this is not just about onions. @dkg has provided three more use-cases in https://github.com/marlam/mpop-mirror/issues/2#issuecomment-606146565
I'm still not entirely convinced that any of these cases are really useful, but ok, I give up ;)
I added tls_host_override
and --tls-host-override
to both msmtp and mpop.
Thank you very much for this! And https://github.com/marlam/mpop-mirror/commit/8b17f6b20196a281be47d8f129df7f428eb4cb2a does look rather simple. :)
I look forward to using this. But I'll wait for a release.
Works like a charm. Thanks a lot! <3
In some cases, it is desirable to verify a TLS certificate against a hostname that is not the FQDN of the certificates Common or Alt Name.
This could be an IP-address (IPs of mailservers rarely change, no point to check for a new one every few minutes via an unencrypted and unsigned protocol like DNS) - or a .onion address as Tor Onion Service.
It would be awesome to allow this in mpop (and msmtp). In order to use an IP or onion as
$host
combined with$tls_trust_file
, I would propose to add something like a$tls_verify_override_host
setting which is verified against the hostname in the certificate.An example:
This isn't completely new, f.e. unbound does something like this for DNS-over-TLS:
Thanks, and keep up the good work!