Mail-proxy, ssl and line termination

Good morning,

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

any pointers appreciated :slight_smile:

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/

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 D.

On Thu, Oct 25, 2012 at 12:04:54PM +0400, Maxim D. 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/

On Thu, Oct 25, 2012 at 02:25:49PM +0400, Maxim D. 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. :slight_smile:


Igor “CacoDem0n” Grabin, http://violent.death.kiev.ua/

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 D.