Haraka icon indicating copy to clipboard operation
Haraka copied to clipboard

Nginx proxy protocol to Haraka on port 465 w/ proxy protocol enabled = SSL handshake fail

Open DoobleD opened this issue 2 years ago • 3 comments

Is proxy protocol supposed to work also on port 465 (implicit SSL/TLS)?

I've set up an Nginx stream proxy in front of Haraka, that works fine. But when I enable the proxy protocol (proxy_protocol directive on Nginx and haproxy_hosts config file on Haraka), the connection breaks before Haraka logs even a single thing, with the following error from Nginx:

peer closed connection in SSL handshake while SSL handshaking to upstream

I tried the same thing without SSL (targeting port 587 STARTTLS instead), and it worked fine. Hence I'm wondering if there could be some issue when using proxy protocol with SSL/TLS?

Interestingly Dovecot works fine with the same setup (proxy protocol to implicit SSL/TLS IMAP and POP ports).

DoobleD avatar Nov 12 '22 19:11 DoobleD

I just noticed some strangeness around the proxy protocol too.

Using swaks on port 25 with the --tls flag:

<-  220 relay-96596467c-t4w47 ESMTP Test Server (96E2E2DC-AD48-4F27-821B-E9DC11A96ED9)
 -> EHLO iridal
<** 220 relay-96596467c-t4w47 ESMTP Test Server (96E2E2DC-AD48-4F27-821B-E9DC11A96ED9)
 -> HELO iridal
<-  250-relay-96596467c-t4w47 Hello -redacted-.com [re.da.ct.ed]Haraka is at your service.
<-  250-PIPELINING
<-  250-8BITMIME
<-  250-SMTPUTF8
<-  250-SIZE 0
<-  250 STARTTLS
*** Host did not advertise STARTTLS
 -> QUIT

I mean...it shows the server sending 250 STARTTLS from the client side, so I'm not sure why it's not picking it up.

I'm assuming you're using Kubernetes. I'm not sure how you're defining your ingress-nginx, but I noticed that it's possible to misconfigure it with Digital Ocean.

If you set: controller.service.annotations."service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol"="true" and: tcp.25="relay/relay:25:25:PROXY" STARTTLS will fail.

If you set: tcp.25="relay/relay:25:25:" things should work properly...

darkpixel avatar Dec 20 '22 18:12 darkpixel

Thanks for the input @darkpixel. We haven't used Kubernetes in our attempt, we simply ran both Nginx and Haraka on the same machine. The simplified Nginx stream config we used looks like that (assuming we set Haraka smtps to run on port 466):

stream {
  ...

  server {
    listen 465 ssl;
    listen [::]:465 ssl;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_certificate /etc/ssl/server.crt;
    ssl_certificate_key /etc/ssl/server.key;
    ssl_dhparam /etc/ssl/dh4096.pem;

    proxy_ssl on;
    proxy_protocol on;
    proxy_pass 127.0.0.1:466;
  }
}

A similar config works for Dovecot with proxy protocol enabled. But it fails with Haraka, though connecting via openssl s_client to port 466 and manually sending proxy protocol commands does work. The certs served by Nginx and Haraka are both valid.

Possibly Nginx is sending proxy protocol commands before Haraka is ready to accept them? Just a guess.

DoobleD avatar Dec 20 '22 22:12 DoobleD

Could be. I've been doing a bunch of crazy/stupid stuff in my test environment today, and for the life of me, I can't bring up 465. 25 and 587 work just fine. I'll do some testing tomorrow after I handle an unrelated issue with external-dns and multiple load balancers.

darkpixel avatar Dec 20 '22 22:12 darkpixel