Nginx reversed proxy -> email imap?

Started by RamSense, December 31, 2021, 10:03:28 AM

Previous topic - Next topic
I am using nginx reversed proxy for my webserver and that works like a charm.
Now I just read an article about nginx being able to function as a reversed proxy for email - IMAP for my email server for the same domain as my website.
" Simplify your email service and improve its performance with NGINX or NGINX Plus as a proxy for the IMAP, POP3, and SMTP protocols "

I can not find it in the GUI in opnsense. Is this function not included / not available?
I know there is a plugin "os-postfix" available, why should I use that instead of the already running nginx? Or what is preferred to use as an reversed email proxy?

thanks for the help in advance


Deciso DEC850v2

hi
QuoteI can not find it in the GUI in opnsense. Is this function not included / not available?
afaik nginx is built with mail module but
-there is no gui for mail proxy settings (you will need to make .conf manually for this and place it in templates)
-"Having an authentication server is obligatory for NGINX mail server proxy. ". you will need to set http auth server or make auth script to authenticate users and get backend parameters from HTTP auth response.

if the mail infrastructure is simple and you only need to pass traffic through the nginx, then you can simply do it with streams (available in the gui)

January 01, 2022, 08:39:21 AM #2 Last Edit: January 01, 2022, 08:43:24 AM by RamSense
Thnx Fright. I did not know about stream.

Quoteif the mail infrastructure is simple and you only need to pass traffic through the nginx, then you can simply do it with streams (available in the gui)
yes it is simple mail infrastructure. Is there a how to guide on how to set this up?

Deciso DEC850v2

i think https://docs.opnsense.org/manual/how-tos/nginx_streams.html#upstream-servers is enough )
(no SNI routing. just upstream mapping. works fine for pop\imap\smtp traffic)

what's the benefit of using a TCP stream via nginx as opposed to just NATing the port? i can't help but think it's just additional complexity to achieve the exact same outcome.

Quotewhat's the benefit of using a TCP stream via nginx as opposed to just NATing the port?
first that comes to mind: tls termination (can use strict tls setting on frontend and relaxed on backend), load balance, sni routing, logging, proxy protocol support

Quote from: Fright on January 01, 2022, 11:10:32 AM
Quotewhat's the benefit of using a TCP stream via nginx as opposed to just NATing the port?
first that comes to mind: tls termination (can use strict tls setting on frontend and relaxed on backend), load balance, sni routing, logging, proxy protocol support

Isn't that all functionality you get when you actually proxy the application protocol though? I get the benefits of that, but my point is why would one want to forward raw TCP connections using nginx rather than NAT?

TLS termination and SNI routing are good points, although i'm personally a fan of keeping things simple - i'd just slap a valid TLS cert on the application server(s) - but yeah those i get. The other features all depend on the application protocol don't they?

So circling back to the use case in this thread - except for offloading TLS for performance reasons, there isn't much benefit compared to NATing, or am i missing something else? I realize this is the nginx sub and i don't want to argue about right or wrong. I'm just trying to figure out what possible benefits of using nginx to forward TCP connections i'm not yet fully understanding that might be beneficial for my own use cases. I currently never do it, nginx is my tool of choice for publishing web applications though.

Sorry for derailing the thread

January 01, 2022, 02:04:29 PM #7 Last Edit: January 01, 2022, 02:10:15 PM by RamSense
Fright:
I did remove my current firewall portforward rule of port 25 to the mailserver and added a rule-wan->rule port 25 to "this firewall"

than in nginx I added

"stream servers"
Listen address: 25
TLS certificate: domain.com (ACME Client)
Route with: Upstream
Upstream Servers: Backend-Mail


"upstream server"
description: mailserver
server: ip-mailserver
port: 25


"upstream"
description: Backend-Mail
server entries: mailserver
Enable TLS(HTTPS): enabled
TLS server override: domain.com
TLS supported Versions: v1.2; v1.3 (or should I still enable v1 and v1.1 also for email?)
TLS session reuse: enabled
TLS trusted certificate: Lets Encrypt R3+ISRG Root X1
TLS verify certificate: enabled

But this does not work, what did I miss?



Deciso DEC850v2

@RamSense
try to look at the nginx access logs and error logs - maybe there will be something. and see the logs on the mail server itself - is there anything there. for the period of debugging, I would start without TLS
is tls enabled on backend 25 port?
Quote(or should I still enable v1 and v1.1 also for email?
it depends on the settings and capabilities of the backend

@marcquark
QuoteIsn't that all functionality you get when you actually proxy the application protocol though?
with streams, there is no way to control connection parameters at the application layer (authentication etc). but still there are some opportunities at the transport layer (TLS offload, custom TLS settings, client certificate validation etc). Speaking about logging, I was talking, of course, not about logging a mail session, but the ability to log network connections. speaking about "proxy protocol support", i talked about the support of the HAProxy PROXY protocol (https://www.haproxy.org/download/1.8/doc/proxy-protocol.txt) which allows to use the proxy\nat chains and save information about the initial connection.

my usecases of streams: use stream to allow TLS1.3 client connections to backend server that supports TLS1.1 only; use streams with LetsEncrypt certs on public side and internal certificates on backends; use stream to verify client cert before it reach backend; use stream with encrypted connection from client to nginx and plain connection from nginx to internal smtp (same physical host) that allows suricata to be used to inspect smtp traffic (for example, password bruteforce on smtp auth)

Quotei don't want to argue about right or wrong
me neither. I'm just trying to answer the question  ;)

When I run: curl https://domain.com:25 -vkI --resolve domain.com:25:192.168.1.1

I get in the last lines of response:
* TLSv1.2 (IN), TLS alert, close notify (256):
* Empty reply from server
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (52) Empty reply from server

in nginx stream error log i see:
*1 SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while proxying connection, client: 192.168.1.46, server: 0.0.0.0:25, upstream: "192.168.1.50:25", bytes from/to client:81/0, bytes from/to upstream:0/0

Deciso DEC850v2

QuoteWhen I run: curl https://domain.com:25 -vkI --resolve domain.com:25:192.168.1.1
may be smtps:// ?  ;)

LOL, yeah that helps with the command... but still error:
*  SSL certificate verify ok.
* TLSv1.2 (IN), TLS alert, close notify (256):
* response reading failed
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (56) response reading failed

and the nginx log:
*1 SSL_do_handshake() failed (SSL: error:1408F10B:SSL routines:ssl3_get_record:wrong version number) while SSL handshaking to upstream, client: 192.168.1.46, server: 0.0.0.0:25, upstream: "192.168.1.50:25", bytes from/to client:0/0, bytes from/to upstream:0/0
Deciso DEC850v2

Quotewhile SSL handshaking to upstream
first part is working now )
upstream connection fails now. is tls enabled on backend's tcp 25?
can you try without "tls enabled" in "upstream" settings?

January 01, 2022, 04:26:33 PM #13 Last Edit: January 01, 2022, 04:32:26 PM by RamSense
Oh indeed. port 25 is not TLS enabled en for server to server communications.
When I remove tls I get another error in the nginx log:

*21 kevent() reported about an closed connection (54: Connection reset by peer) while proxying and reading from client, client: 192.168.1.46, server: 0.0.0.0:25, upstream: "192.168.1.50:25", bytes from/to client:214/124, bytes from/to upstream:124/214

and with curl smtps://domain.xom:25 -vkI --resolve domain.com:25:192.168.1.1

*   Trying 192.168.1.1:25...
* Connected to domain.com (192.168.1.1) port 25 (#0)
* successfully set certificate verify locations:
*  CAfile: /etc/ssl/cert.pem
*  CApath: none
* TLSv1.2 (OUT), TLS handshake, Client hello (1):
* error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
* Closing connection 0
curl: (35) error:1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number

when I only add in stream server TLS certificate: domain.com
I get in the error log: *45 upstream disconnected, bytes from/to client:34/215, bytes from/to upstream:215/34

en with curl smtps://domain.xom:25 -vkI --resolve domain.com:25:192.168.1.1:
*  SSL certificate verify ok.
< 220 domain.com
> EHLO MBP
< 250-domain.com
< 250-PIPELINING
< 250-SIZE 36700160
< 250-ETRN
< 250-STARTTLS
< 250-ENHANCEDSTATUSCODES
< 250-8BITMIME
< 250-DSN
< 250 SMTPUTF8
> HELP
< 502 5.5.2 Error: command not recognized
* Command failed: 502
> QUIT
< 221 2.0.0 Bye
* Closing connection 0
* TLSv1.2 (OUT), TLS alert, close notify (256):
curl: (56) Command failed: 502
Deciso DEC850v2

January 01, 2022, 04:57:21 PM #14 Last Edit: January 01, 2022, 04:59:26 PM by Fright
Quote1400410B:SSL routines:CONNECT_CR_SRVR_HELLO:wrong version number
its again looks like tls connection on non-tls port

Quotewith curl smtps://domain.xom:25 -vkI --resolve domain.com:25:192.168.1.1:
*  SSL certificate verify ok.
< 220 domain.com
> EHLO MBP
< 250-domain.com
< 250-PIPELINING
< 250-SIZE 36700160
< 250-ETRN
and thats looks like smtp session )

so it works now?

(but if you use this server for receiving external mail (MTA) (not for client access only) i would recommend not to use TLS on external connection in this case... and it is even better to use a full-value MTA (eg postfix) for mail relay)