[GH-ISSUE #265] Using directly TLS #172

Closed
opened 2026-03-15 13:00:34 +03:00 by kerem · 18 comments
Owner

Originally created by @tsmanuelanton on GitHub (Mar 13, 2024).
Original GitHub issue: https://github.com/axllent/mailpit/issues/265

Hi, maybe I'm missing something, but is there a way to connect using TLS directly instead of starting without encryption and then upgrading with STARTTLS?

Originally created by @tsmanuelanton on GitHub (Mar 13, 2024). Original GitHub issue: https://github.com/axllent/mailpit/issues/265 Hi, maybe I'm missing something, but is there a way to connect using TLS directly instead of starting without encryption and then upgrading with STARTTLS?
kerem 2026-03-15 13:00:34 +03:00
Author
Owner

@axllent commented on GitHub (Mar 13, 2024):

Hi @tsmanuelanton. Currently no, it's only STARTTLS. Is there a particular reason you want/need TLS only? I'm not 100% sure if this is even possible via the smtpd module I use, so I'd need to look into that first.

<!-- gh-comment-id:1995419052 --> @axllent commented on GitHub (Mar 13, 2024): Hi @tsmanuelanton. Currently no, it's only STARTTLS. Is there a particular reason you want/need TLS only? I'm not 100% sure if this is even possible via the smtpd module I use, so I'd need to look into that first.
Author
Owner

@tsmanuelanton commented on GitHub (Mar 13, 2024):

Thank you for your fast reply, @axllent 💯. I am using this server for integration tests and wanted to ensure that my code is compatible with TLS from the beginning. However, I will assume that if it works with STARTTLS, the same would happen with TLS.

<!-- gh-comment-id:1995499897 --> @tsmanuelanton commented on GitHub (Mar 13, 2024): Thank you for your fast reply, @axllent 💯. I am using this server for integration tests and wanted to ensure that my code is compatible with TLS from the beginning. However, I will assume that if it works with STARTTLS, the same would happen with TLS.
Author
Owner

@axllent commented on GitHub (Mar 14, 2024):

I cannot see why it wouldn't work. TLS requires encryption from beginning to end, where STARTTLS does not initially require it for the handshake. The thing to note is that if you are using authentication, TLS is required and your client must upgrade to TLS (unless you specifically disabled that in the Mailpit with --smtp-auth-allow-insecure).

So the short answer is, TLS is definitely used for sending using authentication (unless disabled in Mailpit), even when using STARTTLS.

<!-- gh-comment-id:1996483990 --> @axllent commented on GitHub (Mar 14, 2024): I cannot see why it wouldn't work. TLS requires encryption from beginning to end, where STARTTLS does not initially require it for the handshake. The thing to note is that if you are using authentication, TLS **is** required and your client must upgrade to TLS (unless you specifically disabled that in the Mailpit with `--smtp-auth-allow-insecure`). So the short answer is, TLS is definitely used for sending using authentication (unless disabled in Mailpit), even when using STARTTLS.
Author
Owner

@tsmanuelanton commented on GitHub (Mar 14, 2024):

There might be some configuration issue on the server or in my code. I am using the Go net/smtp package, and everything works fine when I set Security=SecurityStartTLS. However, when I set Security=SecuritySSLTLS, it gives me the error shown in the image below

if srv.Security == SecurityStartTLS {
	if client, err = smtp.Dial(srv.ServerName()); err != nil {
		return fmt.Errorf("new client: %w", err)
	}

	if err = client.StartTLS(tlsconfig); err != nil {
		return fmt.Errorf("start TLS: %w", err)
	}
} else if srv.Security == SecuritySSLTLS {
	conn, err := tls.Dial("tcp", srv.ServerName(), tlsconfig)
	if err != nil {
		return fmt.Errorf("set TLS Dial: %w", err)
	}

	if client, err = smtp.NewClient(conn, srv.Host); err != nil {
		return fmt.Errorf("new client: %w", err)
	}
} else {
	return fmt.Errorf("security not implemented")
}

imagen

<!-- gh-comment-id:1996984853 --> @tsmanuelanton commented on GitHub (Mar 14, 2024): There might be some configuration issue on the server or in my code. I am using the Go `net/smtp` package, and everything works fine when I set `Security=SecurityStartTLS`. However, when I set `Security=SecuritySSLTLS`, it gives me the error shown in the image below ```go if srv.Security == SecurityStartTLS { if client, err = smtp.Dial(srv.ServerName()); err != nil { return fmt.Errorf("new client: %w", err) } if err = client.StartTLS(tlsconfig); err != nil { return fmt.Errorf("start TLS: %w", err) } } else if srv.Security == SecuritySSLTLS { conn, err := tls.Dial("tcp", srv.ServerName(), tlsconfig) if err != nil { return fmt.Errorf("set TLS Dial: %w", err) } if client, err = smtp.NewClient(conn, srv.Host); err != nil { return fmt.Errorf("new client: %w", err) } } else { return fmt.Errorf("security not implemented") } ``` ![imagen](https://github.com/axllent/mailpit/assets/90830684/e8858fb2-8937-472f-9bfc-93e02c5bcec1)
Author
Owner

@axllent commented on GitHub (Mar 14, 2024):

Maybe it does in fact require TSL (I've never tested that). Leave this with me and I'll look into how/if it's possible to add an option to Mailpit to use TSL instead of STARTTSL. I'm not too sure when I'll get a chance to look into it, bit I hope in the next couple of days.

<!-- gh-comment-id:1997032420 --> @axllent commented on GitHub (Mar 14, 2024): Maybe it does in fact require TSL (I've never tested that). Leave this with me and I'll look into how/if it's possible to add an _option_ to Mailpit to use TSL instead of STARTTSL. I'm not too sure when I'll get a chance to look into it, bit I hope in the next couple of days.
Author
Owner

@tsmanuelanton commented on GitHub (Mar 14, 2024):

Thank you very much, I really appreciate your help. Please, don't feel the need to rush for me 😄.

<!-- gh-comment-id:1997065625 --> @tsmanuelanton commented on GitHub (Mar 14, 2024): Thank you very much, I really appreciate your help. Please, don't feel the need to rush for me 😄.
Author
Owner

@axllent commented on GitHub (Mar 15, 2024):

You are absolutely correct - I have been doing a bit of testing and you cannot connect to STARTTLS directly using TLS in a client. The good news it I can add this feature (it is supported) - I just need to figure out a way to add it so that it makes sense to the user.

Currently there are the following logic in Mailpit:

  • When you add SMTP certificates the SMTP server automatically allows STARTTLS, but it does not require/enforce STARTTLS (ie: you can send unencrypted although most clients automatically upgrade). Basically the client connects and can decide whether to send plain or encrypted (the connection is then upgraded to TLS after the client connects).
  • If the SMTP server is using authentication, then STARTTLS is required (although you can override this with --smtp-auth-allow-insecure to allow auth over an unencrypted connection - just like before TLS was "a thing" in the good old days).
  • There is also an option to enforce STARTTLS (--smtp-tls-required) even without authentication, meaning that a client connecting must use STARTTLS to send the email. This option does not imply TLS-only (what you are after), but rather that a client must upgrade to encryption after it connects. This logic aligns with the TLSRequired flag in the smtpd package I use, and from what I understand aligns with the evolution of SMTP encryption in general.

Now I want to add the option for actual TLS (only) which means that the entire connection must run only over TLS only. This aligns with the TLSListener flag, and is different to STARTTLS because the TCP handshake is encrypted too (and why the two are not compatible even though they both use TLS).

As you can probably see, there will be probably confusion for Mailpit users because of the existing --smtp-tls-required flag in Mailpit.

I think I may have to deprecate the --smtp-tls-required and replace it with two new flags to either:

  1. require STARTTLS, or
  2. enforce & require TLS/SSL

I am thinking maybe --smtp-require-starttls and --smtp-require-tls (they cannot both be used at the same time). I really do not like deprecating flags, but I feel this may be the only way as it will help prevent confusion moving forward when I add "actual TLS" into the mix.

I'm going to slap on this decision as I may have a fresh idea in the morning, but I'd appreciate your comments if you have any. Sorry for the long post!

<!-- gh-comment-id:1999451641 --> @axllent commented on GitHub (Mar 15, 2024): You are absolutely correct - I have been doing a bit of testing and you cannot connect to STARTTLS directly using TLS in a client. The good news it I can add this feature (it is supported) - I just need to figure out a way to add it so that it makes sense to the user. Currently there are the following logic in Mailpit: - When you add SMTP certificates the SMTP server automatically **allows** STARTTLS, but it does not require/enforce STARTTLS (ie: you can send unencrypted although most clients automatically upgrade). Basically the client connects and can decide whether to send plain or encrypted (the connection is then upgraded to TLS after the client connects). - If the SMTP server is using authentication, then STARTTLS is required (although you can override this with `--smtp-auth-allow-insecure` to allow auth over an unencrypted connection - just like before TLS was "a thing" in the good old days). - There is also an option to enforce STARTTLS (`--smtp-tls-required`) even without authentication, meaning that a client connecting must use STARTTLS to send the email. This option does not imply TLS-only (what you are after), but rather that a client must upgrade to encryption after it connects. This logic aligns with the [TLSRequired flag](https://github.com/mhale/smtpd/blob/master/smtpd.go#L100) in the smtpd package I use, and from what I understand aligns with the evolution of SMTP encryption in general. Now I want to add the option for actual TLS (only) which means that the entire connection must run only over TLS only. This aligns with the [TLSListener flag](https://github.com/mhale/smtpd/blob/master/smtpd.go#L99), and is different to STARTTLS because the TCP handshake is encrypted too (and why the two are not compatible even though they both use TLS). As you can probably see, there will be probably confusion for Mailpit users because of the existing `--smtp-tls-required` flag in Mailpit. I think I may have to deprecate the `--smtp-tls-required` and replace it with two new flags to either: 1. require STARTTLS, or 2. enforce & require TLS/SSL I am thinking maybe `--smtp-require-starttls` and `--smtp-require-tls` (they cannot both be used at the same time). I really do not like deprecating flags, but I feel this may be the only way as it will help prevent confusion moving forward when I add "actual TLS" into the mix. I'm going to slap on this decision as I may have a fresh idea in the morning, but I'd appreciate your comments if you have any. Sorry for the long post!
Author
Owner

@tsmanuelanton commented on GitHub (Mar 15, 2024):

Apologies for the extra workload 😉. Although I'm not very familiar with this topic, you might consider keeping the --smtp-tls-required flag and detecting whether the client is already using TLS, ensuring the conversion is transparent for the client. I would be happy to assist you in any way I can.

<!-- gh-comment-id:1999615707 --> @tsmanuelanton commented on GitHub (Mar 15, 2024): Apologies for the extra workload 😉. Although I'm not very familiar with this topic, you might consider keeping the `--smtp-tls-required` flag and detecting whether the client is already using TLS, ensuring the conversion is transparent for the client. I would be happy to assist you in any way I can.
Author
Owner

@axllent commented on GitHub (Mar 15, 2024):

Unfortunately that's not how it works, TLS is TLS and doesn't support upgrading from an unencrypted connection (it doesn't allow an unencrypted connection at all). STARTTLS on the other hand does, which is why it is the more common (though slightly less secure) protocol as it is more backwards compatible. This is why email providers who support both protocols run these on different ports.

Ultimately I predict everything will eventually move to pure TLS in the future (a bit like HTTPS), but that's not for a long time.

In the meantime I will add the option soon to use TLS (instead of STARTTLS) for those like yourself wanting to explicitly test SSL/TLS rather than STARTTLS. I just need to implement it and do the changes I mentioned earlier. I'll also need to write up some documentation as this is a somewhat confusing topic to most.

Also don't apologise for the time/work to implement this. This investigation has allowed me to investigate and better understand the SMTP protocols and their differences, and I see the benefits of adding this feature 👍

<!-- gh-comment-id:2000391916 --> @axllent commented on GitHub (Mar 15, 2024): Unfortunately that's not how it works, TLS is TLS and doesn't support upgrading from an unencrypted connection (it doesn't allow an unencrypted connection at all). STARTTLS on the other hand does, which is why it is the more common (though slightly less secure) protocol as it is more backwards compatible. This is why email providers who support both protocols run these on different ports. Ultimately I predict everything will eventually move to pure TLS in the future (a bit like HTTPS), but that's not for a long time. In the meantime I will add the option soon to use TLS (instead of STARTTLS) for those like yourself wanting to explicitly test SSL/TLS rather than STARTTLS. I just need to implement it and do the changes I mentioned earlier. I'll also need to write up some documentation as this is a somewhat confusing topic to most. Also don't apologise for the time/work to implement this. This investigation has allowed me to investigate and better understand the SMTP protocols and their differences, and I see the benefits of adding this feature 👍
Author
Owner

@axllent commented on GitHub (Mar 17, 2024):

@tsmanuelanton I have just released a new version of Mailpit (v1.15.0) which includes TLS support for SMTP 🥳 You can read the documentation on the website.

Please confirm this works for you?

<!-- gh-comment-id:2002284774 --> @axllent commented on GitHub (Mar 17, 2024): @tsmanuelanton I have just released a new version of Mailpit (v1.15.0) which includes TLS support for SMTP :partying_face: You can read the documentation on [the website](https://mailpit.axllent.org/docs/configuration/smtp/#smtp-with-ssltls). Please confirm this works for you?
Author
Owner

@tsmanuelanton commented on GitHub (Mar 18, 2024):

I've just tried and still not working for me. Keeps giving same error tls: first record does not look like a TLS handshake when calling tls.Dial("tcp", srv.ServerName(), tlsconfig). Do I have to use/open any new port?

imagen

<!-- gh-comment-id:2004436043 --> @tsmanuelanton commented on GitHub (Mar 18, 2024): I've just tried and still not working for me. Keeps giving same error `tls: first record does not look like a TLS handshake` when calling ` tls.Dial("tcp", srv.ServerName(), tlsconfig)`. Do I have to use/open any new port? ![imagen](https://github.com/axllent/mailpit/assets/90830684/bbbd9d06-c022-43c2-9ffd-3637006ee267)
Author
Owner

@axllent commented on GitHub (Mar 18, 2024):

It's MP_SMTP_REQUIRE_TLS=true 😄 It runs on the same port you configured (which now should only accept TLS).

<!-- gh-comment-id:2004498038 --> @axllent commented on GitHub (Mar 18, 2024): It's `MP_SMTP_REQUIRE_TLS=true` 😄 It runs on the same port you configured (which now should only accept TLS).
Author
Owner

@tsmanuelanton commented on GitHub (Mar 18, 2024):

My bad, I am dumb 💀. Yeah, now it works fine. Much thank you!

<!-- gh-comment-id:2004621245 --> @tsmanuelanton commented on GitHub (Mar 18, 2024): My bad, I am dumb 💀. Yeah, now it works fine. Much thank you!
Author
Owner

@axllent commented on GitHub (Mar 19, 2024):

Excellent, thanks for the feedback!

<!-- gh-comment-id:2005494877 --> @axllent commented on GitHub (Mar 19, 2024): Excellent, thanks for the feedback!
Author
Owner

@yoke88 commented on GitHub (Oct 24, 2024):

excellent jobs,but i want more,can we support pop3 tls(pop3s) as smtps?

<!-- gh-comment-id:2435073972 --> @yoke88 commented on GitHub (Oct 24, 2024): excellent jobs,but i want more,can we support pop3 tls(pop3s) as smtps?
Author
Owner

@axllent commented on GitHub (Oct 24, 2024):

POP3 already supports TLS @yoke88 (see docs). Is this not what you mean?

<!-- gh-comment-id:2436045197 --> @axllent commented on GitHub (Oct 24, 2024): POP3 already supports TLS @yoke88 ([see docs](https://mailpit.axllent.org/docs/configuration/pop3/)). Is this not what you mean?
Author
Owner

@yoke88 commented on GitHub (Oct 26, 2024):

thanks, I think it was pop3 with starttls. I use this soft to test multiple email protocols ,so i need pop3,pop3 with starttls,pop3s etc. so it support pop3s and pop currently, but lack pop3 with starttls?

<!-- gh-comment-id:2439583511 --> @yoke88 commented on GitHub (Oct 26, 2024): thanks, I think it was pop3 with starttls. I use this soft to test multiple email protocols ,so i need pop3,pop3 with starttls,pop3s etc. so it support pop3s and pop currently, but lack pop3 with starttls?
Author
Owner

@axllent commented on GitHub (Oct 26, 2024):

Sorry, STARTTLS for the POP3 server is currently not supported.

<!-- gh-comment-id:2439589755 --> @axllent commented on GitHub (Oct 26, 2024): Sorry, STARTTLS for the POP3 server is currently not supported.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/mailpit#172
No description provided.