Forum: NGINX mail-proxy, ssl and line termination

Posted by Igor Grabin (Guest)
on 2012-10-25 09:08
(Received via mailing list)
Good morning,

maybe, I'm posting this to the wrong place. nginx-devel@ rejected
this.

any pointers appreciated :-)

the setup...
 1 nginx frontend, pop3 / pop3s / imap / imaps
 2 backends, dovecot + ms-exchange.

the problem:
 pop3s / imaps connections being forwarded to exchange (in other
words, decapsulated from ssl) stall after login.
 otherwise, all types of connections work fine, i.e.
 nginx:pop3s -> dovecot:pop3, nginx:pop3 -> exchange:pop3

tested on 1.2.4 as bundled with ubuntu 10.10, and 1.3.7, compiled by
hand.

I did a bit of tracing and have an assumption. nginx doesn't put an
extra '\r' in a first statement of ssl-decapsulated session.
here's a sample (being captured between nginx and a backend). this may
upset redmond-based products ;-).

$ hexdump -c inflow.imap.good ( nginx:imap -> exchange:imap)
0000000   1       L   O   G   I   N       {   9   }  \r  \n   c   a c
0000010   o   d   e   m   o   n       {   7   }  \r  \n   X   X   X X
0000020   X   X   X  \r  \n   2       s   e   l   e   c   t       i n
0000030   b   o   x  \r  \n   3       l   o   g   o   u   t  \r  \n

$ hexdump -c inflow.imap.bad (nginx:imaps -> exchange:imap)
0000000   1       L   O   G   I   N       {   9   }  \r  \n   c   a c
0000010   o   d   e   m   o   n       {   7   }  \r  \n   X   X   X X
0000020   X   X   X  \r  \n   2       s   e   l   e   c   t       i n
0000030   b   o   x  \n

same goes for pop3 in the same direction - missing '\r' after 'list'
command.

unfortunately, my C skills suck, so I'm unable to propose a patch.

full config-file below
===
user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] 
"$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
}
                mail {
                  auth_http  127.0.0.1:80/mailauth.pl;
                  auth_http_header X-NGX-Auth-Key "censored :-)";
                 proxy on;
        ssl_certificate_key     /etc/nginx/ssl/cert.pem;
        ssl_certificate     /etc/nginx/ssl/cert.pem;
        ssl_session_timeout     5m;
                server {
                        protocol pop3;
                  ssl on;
                        listen 1.2.3.4:995;
                        listen 192.168.1.1:995;
                }

                server {
                        listen 1.2.3.4:993;
                        listen 192.168.1.1:993;
                        protocol imap;
                        ssl on;
                }
                  imap_auth plain login;
                  pop3_auth plain;
  }

tia for any pointers,
--
Igor "CacoDem0n" Grabin, http://violent.death.kiev.ua/
Posted by Maxim Dounin (Guest)
on 2012-10-25 10:05
(Received via mailing list)
Hello!

On Thu, Oct 25, 2012 at 10:07:38AM +0300, Igor Grabin wrote:

>
> extra '\r' in a first statement of ssl-decapsulated session.
> 0000000   1       L   O   G   I   N       {   9   }  \r  \n   c   a c
> 0000010   o   d   e   m   o   n       {   7   }  \r  \n   X   X   X X
> 0000020   X   X   X  \r  \n   2       s   e   l   e   c   t       i n
> 0000030   b   o   x  \n
>
> same goes for pop3 in the same direction - missing '\r' after 'list'
> command.

The "2 select ..." is not something nginx sent by itself, it's
client data it forwarded.  You may take a look at a client you use
instead.

--
Maxim Dounin
http://nginx.com/support.html
Posted by Igor Grabin (Guest)
on 2012-10-25 10:25
(Received via mailing list)
On Thu, Oct 25, 2012 at 12:04:54PM +0400, Maxim Dounin wrote:
> > same goes for pop3 in the same direction - missing '\r' after 'list'
> > command.
> The "2 select ..." is not something nginx sent by itself, it's
> client data it forwarded.  You may take a look at a client you use
> instead.

both testcases produced by me, using plain linux telnet and plain
linux openssl s_client.

I'd kinda expect no '\r' in that case, but it's there in the
beginning in both cases.

tia,
--
Igor "CacoDem0n" Grabin, http://violent.death.kiev.ua/
Posted by Maxim Dounin (Guest)
on 2012-10-25 12:26
(Received via mailing list)
Hello!

On Thu, Oct 25, 2012 at 11:24:58AM +0300, Igor Grabin wrote:

> > > 0000030   b   o   x  \n
> > > same goes for pop3 in the same direction - missing '\r' after 'list'
> > > command.
> > The "2 select ..." is not something nginx sent by itself, it's
> > client data it forwarded.  You may take a look at a client you use
> > instead.
>
> both testcases produced by me, using plain linux telnet and plain
> linux openssl s_client.

So the difference observed more or less comes from telnet vs.
openssl s_client.  Try "openssl s_client -crlf" instead, quote
from man s_client:

       -crlf
           this option translated a line feed from the terminal into 
CR+LF as
           required by some servers.

> I'd kinda expect no '\r' in that case, but it's there in the
> beginning in both cases.

The CRLF is correctly sent in the "LOGIN" command as it's sent by
nginx itself.

In case of telnet you don't get bare LF as it does LF -> CRLF
conversion by default.  I would recommend nc (aka netcat) if you
need raw tcp client without any conversions.

--
Maxim Dounin
http://nginx.com/support.html
Posted by Igor Grabin (Guest)
on 2012-10-26 06:56
(Received via mailing list)
On Thu, Oct 25, 2012 at 02:25:49PM +0400, Maxim Dounin wrote:
> > > The "2 select ..." is not something nginx sent by itself, it's
> > > client data it forwarded.  You may take a look at a client you use
> > > instead.
> > both testcases produced by me, using plain linux telnet and plain
> > linux openssl s_client.
> So the difference observed more or less comes from telnet vs.
> openssl s_client.  Try "openssl s_client -crlf" instead, quote
> from man s_client:
[...skip...]

> The CRLF is correctly sent in the "LOGIN" command as it's sent by
> nginx itself.
> In case of telnet you don't get bare LF as it does LF -> CRLF
> conversion by default.  I would recommend nc (aka netcat) if you
> need raw tcp client without any conversions.

my lame. thanks. :-)

--
Igor "CacoDem0n" Grabin, http://violent.death.kiev.ua/
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.