Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force TLS email traffic over port 587 #366

Closed
WilliamDEdwards opened this issue Oct 1, 2017 · 34 comments
Closed

Force TLS email traffic over port 587 #366

WilliamDEdwards opened this issue Oct 1, 2017 · 34 comments

Comments

@WilliamDEdwards
Copy link

Hello,

Currently, we have STARTTLS enabled on port 25 on Postal. I am aware that port 25 using STARTTLS functions perfectly fine. However, AcyMailing (a Joomla! plugin for newsletters and the like) refuses to send email over that port. For usage of TLS (or SSL for that matter) it requires email to be sent from either port 465 or 587, naturally, the latter being preferred.

This boils down to the question: how do we send TLS email from port 587, despite it functioning on port 25?

Thanks.

@willpower232
Copy link
Collaborator

You can use iptables to forward traffic from 587 to 25.

We have port 2525 open as well as 25 to get around some SMTP restrictions.

Have a look at #306 (comment)

@WilliamDEdwards
Copy link
Author

I did that, now when I telnet into port 587:

MacBook-Pro-van-William-David:~ server$ telnet . 587
Trying ....
Connected to ..
Escape character is '^]'.
220 . ESMTP Postal/KVTSYX
qui
t502 Invalid/unsupported command
quit
502 Invalid/unsupported command
exit
502 Invalid/unsupported command

Not sure why, because it's just an iptables rule...

@willpower232
Copy link
Collaborator

Does your plugin work in spite of the telnet issues?

@WilliamDEdwards
Copy link
Author

Nope...

@willpower232
Copy link
Collaborator

Does telnet work on port 25?

@WilliamDEdwards
Copy link
Author

WilliamDEdwards commented Oct 4, 2017

Yes, on port 25 it works perfectly fine and I'm able to negotiate using the openssl command. However, opening a telnet session to port 587 causes it to act weirdly like the output I posted above.

@willpower232
Copy link
Collaborator

Could you try 2525 and see if telnet still works through that port?

@WilliamDEdwards
Copy link
Author

Nope, connection refused. Same with firewall disabled.

@willpower232
Copy link
Collaborator

I am unable to replicate your issues, I get working telnet with any forwarded port.

Which server provider are you using? Could there be any curious filtering occurring?

@WilliamDEdwards
Copy link
Author

That is very odd. We're using Linode for this customer and I can assure you there is no filtering on any level.

@willpower232
Copy link
Collaborator

Can you check with sudo netstat -lnp that nothing is listening on 587?

@WilliamDEdwards
Copy link
Author

WilliamDEdwards commented Oct 4, 2017

Hi,

I figured I'd send the entire output:

root@localhost:~# netstat -lnp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3456/sshd       
tcp        0      0 0.0.0.0:443             0.0.0.0:*               LISTEN      3582/nginx -g daemo
tcp        0      0 127.0.0.1:5000          0.0.0.0:*               LISTEN      3880/[postal] web.1
tcp        0      0 0.0.0.0:25672           0.0.0.0:*               LISTEN      3475/beam       
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      3764/mysqld     
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3582/nginx -g daemo
tcp        0      0 0.0.0.0:4369            0.0.0.0:*               LISTEN      3668/epmd       
tcp6       0      0 :::22                   :::*                    LISTEN      3456/sshd       
tcp6       0      0 :::25                   :::*                    LISTEN      3886/[postal] smtp.
tcp6       0      0 :::443                  :::*                    LISTEN      3582/nginx -g daemo
tcp6       0      0 :::5672                 :::*                    LISTEN      3475/beam       
tcp6       0      0 :::80                   :::*                    LISTEN      3582/nginx -g daemo
tcp6       0      0 :::4369                 :::*                    LISTEN      3668/epmd       
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node   PID/Program name    Path
unix  2      [ ACC ]     STREAM     LISTENING     8717     1/init              /run/systemd/private
unix  2      [ ACC ]     STREAM     LISTENING     8735     1/init              /run/systemd/journal/stdout
unix  2      [ ACC ]     STREAM     LISTENING     14915    3764/mysqld         /var/run/mysqld/mysqld.sock
unix  2      [ ACC ]     STREAM     LISTENING     13139    1/init              /run/uuidd/request
unix  2      [ ACC ]     STREAM     LISTENING     15709    3938/systemd        /run/user/0/systemd/private
unix  2      [ ACC ]     STREAM     LISTENING     13149    1/init              /var/run/dbus/system_bus_socket
unix  2      [ ACC ]     STREAM     LISTENING     8870     1/init              /run/systemd/fsck.progress
unix  2      [ ACC ]     SEQPACKET  LISTENING     8874     1/init              /run/udev/control
unix  2      [ ACC ]     STREAM     LISTENING     14871    3874/app)           /tmp/postal/pids/procodile.sock

When grepping on 587 there is no output:

root@localhost:~# netstat -lnp | grep 587
root@localhost:~# 

@willpower232
Copy link
Collaborator

Going back a few steps....

Nope, connection refused. Same with firewall disabled.

Did you run the iptables rules for port 2525?

@WilliamDEdwards
Copy link
Author

No, I have not. Why would I? I don't have a firewall.

@WilliamDEdwards
Copy link
Author

By the way, there is nothing listening on port 2525 either:

root@localhost:/opt/postal# netstat -lnp | grep 2525
root@localhost:/opt/postal# 

@willpower232
Copy link
Collaborator

iptables is a way of forwarding the traffic as well as a firewall. If you can try the rules suggested earlier and forward port 2525 to port 25 then see if telnet works.

If you have used iptables to forward both 2525 and 587 and telnet works on 2525 but not 587, you know something is blocking you somehow somewhere.

Does that make sense?

@WilliamDEdwards
Copy link
Author

WilliamDEdwards commented Oct 4, 2017

Apologies! Probably a lack of sleep :)

I disabled the firewall completely to see what'd happen. To my surprise, port 587 still works, but not with SSL...

I setup iptables to forward port 2525 to 25, which works:

MacBook-Pro-van-William-David:~ server$ telnet . 2525
Trying ....
Connected to ..
Escape character is '^]'.
220 . ESMTP Postal/F1GFJY

However, like I mentioned, SSL does not work. Without SSL everything functions fine.

MacBook-Pro-van-William-David:~ server$ openssl s_client -connect .:587 -ssl3
CONNECTED(00000003)
3720:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-59.60.1/src/ssl/s3_pkt.c:300:
MacBook-Pro-van-William-David:~ server$ openssl s_client -connect .:2525 -ssl3
CONNECTED(00000003)
3721:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version 
number:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-
59.60.1/src/ssl/s3_pkt.c:300:

So I figured that might be a problem on my system. I tried that same command on a server, which does not work either, returning:

[root@server admin]# openssl s_client -connect .:587 -ssl3
CONNECTED(00000003)
140353024309152:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version 
number:s3_pkt.c:365:

The entire output:

[root@server admin]# openssl s_client -connect .:587 -ssl3
CONNECTED(00000003)
140353024309152:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version 
number:s3_pkt.c:365:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : SSLv3
    Cipher    : 0000
    Session-ID: 
    Session-ID-ctx: 
    Master-Key: 
    Key-Arg   : None
    Krb5 Principal: None
    PSK identity: None
    PSK identity hint: None
    Start Time: 1507128981
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

@willpower232
Copy link
Collaborator

Ah have you configured a certificate in postal.yml? Have a look at the default settings here:
https://github.com/atech/postal/blob/2a9702ba475b4703540e3edbe9de702b6f4a1dbe/config/postal.defaults.yml#L66

We manually created a letsencrypt certificate for the server so just recycled that:

smtp_server:
  tls_enabled: true
  tls_certificate_path: /etc/letsencrypt/live/postal.example.com/fullchain.pem
  tls_private_key_path: /etc/letsencrypt/live/postal.example.com/privkey.pem

@WilliamDEdwards
Copy link
Author

Yep, definitely, although it is self-signed (but that shouldn't be a problem). I appended the last three lines from the default settings (proxy_protocol, log_connect and strip_received_headers) and after restarting Postal this gives me another error:

MacBook-Pro-van-William-David:~ server$ openssl s_client -connect .:587 -starttls smtp
CONNECTED(00000003)
write:errno=54

Configuration:

smtp_server:
  port: 25
  tls_enabled: true
  tls_certificate_path: config/fast_server.cert
  tls_private_key_path: config/fast_server.key
  proxy_protocol: false
  log_connect: true
  strip_received_headers: false

@willpower232
Copy link
Collaborator

If you aren't changing the values, there shouldn't be a need to include the defaults I would have hoped!

Have you verified that certificate file exists? There have been some .cert/.crt mix ups recently.

@WilliamDEdwards
Copy link
Author

Hi there,

Yes, both files definitely exist:

root@localhost:/opt/postal# ls config/fast_server.key
config/fast_server.key
root@localhost:/opt/postal# ls config/fast_server.cert
config/fast_server.cert
root@localhost:/opt/postal# ls config/fast_server.crt
ls: cannot access 'config/fast_server.crt': No such file or directory

Sorry that the solution isn't more obvious ;-)

@willpower232
Copy link
Collaborator

Can you try SSL connecting over 25 from your terminal?

The self signed part might be an issue, are you able to generate a real certificate?

Finally, heres my openssl output for comparison (I had to drop -ssl3 because its not supported in my desktop ubuntu version of openssl apparently...)

$ openssl s_client -connect postal.example.com:25
CONNECTED(00000003)
140718870431488:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:252:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 5 bytes and written 176 bytes
Verification: OK
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1507131982
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
---

@WilliamDEdwards
Copy link
Author

When I do, I get the following error:

MacBook-Pro-van-William-David:~ server$ openssl s_client -connect .:25
CONNECTED(00000003)
4235:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown 
protocol:/BuildRoot/Library/Caches/com.apple.xbs/Sources/OpenSSL098/OpenSSL098-
59.60.1/src/ssl/s23_clnt.c:618:

And again, from a server:

[root@server01 admin]#  openssl s_client -connect .:25
CONNECTED(00000003)
140572102846368:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:794:

I could try using a certificate signed by a CA, but that shouldn't matter. After all, it is an SSL certificate.

@willpower232
Copy link
Collaborator

Our Postal is running on Ubuntu 16.04 with openssl version 1.0.2g, are you running the same?

@WilliamDEdwards
Copy link
Author

Yes, we are:

root@localhost:/opt/postal/config# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 16.04.2 LTS
Release:	16.04
Codename:	xenial

root@localhost:/opt/postal/config# openssl version
OpenSSL 1.0.2g  1 Mar 2016

Anyway, I replaced the certificate with a Let's Encrypt one. Same error.

@WilliamDEdwards
Copy link
Author

I also tried replacing the path to the certificate and the private key with the full path (/opt/postal/config). No luck unfortunately...

@WilliamDEdwards
Copy link
Author

I have a feeling Postal doesn't pass SSL through at all. When I telnet to port 25, 2525 or 587, I can use auth login without having to negotiate:

MacBook-Pro-van-William-David:~ server$ telnet . 587
Trying ....
Connected to ..
Escape character is '^]'.
220 . ESMTP Postal/W5AWNQ
ehlo .
250-My capabilities are
250-STARTTLS
250 AUTH CRAM-MD5 PLAIN LOGIN
auth login
334 VXNlcm5hbWU6

I'm able to execute starttls:

starttls
220 Ready to start TLS

But from what I remember, STARTTLS should be chosen automatically. Or am I mistaken?

@spheron1
Copy link

spheron1 commented Oct 4, 2017

Traditionally you would have opportunistic/explicit SSL/TLS with STARTTLS on port 25 and/or 587 and implicit SSL/TLS (depreciated) on port 465.

The key difference is that with opportunistic/explicit SSL/TLS the mail server advertises that it has the STARTTLS capability and if the client supports it then it issues the STARTTLS command to upgrade the connection from plain text to TLS encrypted.
This means that an SMTP client which doesn't understand SSL/TLS can continue to work without any modifications whereas with implicit SSL/TLS as you establish an encrypted connection first all clients needs to specifically support this otherwise they can't connect at all.

You can test opportunistic/explicit SSL/TLS using the openssl client as follows:

openssl s_client -connect <ip>:587 -starttls smtp

Whereas with implicit SSL/TLS you would use:

With openssl s_client -connect <ip>:465

@willpower232
Copy link
Collaborator

Thanks for the explanation!

openssl s_client -connect postal.example.com:25 -starttls smtp returns the content of the certificate and a lot of output about SSL sessions and I get the same output on 2525 as I would expect from the iptables port forwarding.

Also mxtoolbox is pretty happy
image

So @WilliamDEdwards is everything working now?

@WilliamDEdwards
Copy link
Author

Hi,

It does not work yet. On MxToolbox it mentions "SMTP TLS | OK - Supports TLS."

However, it still doesn't work in AcyMailing which is a problem...

@spheron1
Copy link

spheron1 commented Oct 5, 2017

Is AcyMailing expecting implicit or explicit TLS?

@WilliamDEdwards
Copy link
Author

"Acymailing supports both implicit or explicit TLS connections."

@WilliamDEdwards
Copy link
Author

For some reason it suddenly works now. Just out of nowhere...

@pschoenmakers
Copy link

pschoenmakers commented Mar 2, 2018

I did face the same problems, after a lot of testing I found the problem to be related that the postal user couldn't read the letsencrypt certs.

To test if this is the case
su postal
cat /etc/letsencrypt/live/postal.example.com/fullchain.pem

I did face a Permission denied.

Solution was to give read access to both etc/letsencrypt/live and etc/letsencrypt/archive as the cert in /live is a symlink to the archive dir.

Hope this help someone else having the same problem in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants