# SMTP AUTH with XCLIENT - impossible or just difficult?

**URL:** <https://www.ruby-forum.com/t/smtp-auth-with-xclient-impossible-or-just-difficult/192728>\
**Category:** NGINX\
**Created:** [August 4, 2010, 3:03pm UTC](https://www.ruby-forum.com/t/smtp-auth-with-xclient-impossible-or-just-difficult/192728 "2010-08-04T15:03:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Karl\_Kraft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f17d59/32.png) [@Karl\_Kraft](https://www.ruby-forum.com/u/Karl_Kraft)\
**Post date:** [August 4, 2010, 3:03pm UTC](https://www.ruby-forum.com/t/smtp-auth-with-xclient-impossible-or-just-difficult/192728/1 "2010-08-04T15:03:45Z")

</div>

I have been successful at using nginx as a front end to POP and IMAP  
servers to keep mailboxes spread across multiple machines. It also  
provided the added benefit of enabling SSL for privacy. I wrote a custom  
HTTP based authentication agent to direct to the proper mailbox, and  
everything seems to work great. Now I would like to do the same for SMTP  
connections, using nginx as both an SSL front end and director to my  
SMTP daemons.

However, after implementing XCLIENT in the SMTP daemon, and adding a  
simple configuration to nginx, all is not well. After working my way  
through the mailing list and trying several configurations, I am left  
thinking that XCLIENT with authentication simply does not work. Has  
anyone ever managed to get this to work?

Very simple sample configuration:

…  
smtp\_auth plain cram-md5;

server {  
listen 10.10.10.104:1466;  
server\_name [veyron.karlkraft.com](http://veyron.karlkraft.com);  
protocol smtp;  
proxy on;  
}  
…

This is an example of a session:

CN - client to nginx  
NC - nginx to client  
NS - nginx to smtp server  
SN - smtp server to nginx

NC: 220 [veyron.karlkraft.com](http://veyron.karlkraft.com) ESMTP ready  
CN: EHLO [client.karlkraft.com](http://client.karlkraft.com)  
NC: 250 AUTH PLAIN CRAM-MD5  
CN: AUTH PLAIN xxxxxxxxxxxxxxxxxxxxxxx

At this point, nginx contacts the authentication agent over HTTP, and is  
told to contact explorer on port 1125 as the actual SMTP back end  
daemon. Once the connection is successful, it passes back the 235  
code for passing authentication:

NS: [Connects to back end SMTP server]

NC: 235 2.0.0 OK

And then nginx proceeds to negotiate with the back end server:

SN: 220 [explorer.karlkraft.com](http://explorer.karlkraft.com). - [explorer.karlkraft.com](http://explorer.karlkraft.com)  
(NFSmtp/2006q2.1) Authorized network 10.10.0.0/255.255.0.0  
NS: EHLO [veyron.karlkraft.com](http://veyron.karlkraft.com)  
SN: 250-/10.10.10.104  
SN: 250-EXPN  
SN: 250-NAME ADDR PROTO HELO  
SN: 250-SIZE  
SN: 250-AUTH CRAM-MD5 PLAIN  
SN: 250 HELP

nginx then sends the XCLIENT command. The back end server needs the  
information in order to be able to provide the proper routing and QOS  
based on the login, as well as performing SPF and DNSBL checks against  
the original IP.

NS: XCLIENT ADDR=10.10.10.2 LOGIN=removed\_email\_address@domain.invalid NAME=[UNAVAILABLE]  
SN: 220 Authenticated via XCLIENT

And here is where it all falls apart, because the response to XCLIENT is  
then passed back to the original client, which confuses the client  
because it hand’t sent any commands yet.

NC: 220 Authenticated via XCLIENT

Nginx then sends the second EHLO to the server:

NS: EHLO client

The server then responds, and nginx forwards all this response to the  
original client as well, leaving the client even more confused:

SN: 250-/10.10.10.104  
SN: 250-EXPN  
SN: 250-NAME ADDR PROTO HELO  
SN: 250-SIZE  
SN: 250-AUTH CRAM-MD5 PLAIN  
SN: 250 HELP

NC: 250-/10.10.10.104  
NC: 250-EXPN  
NC: 250-NAME ADDR PROTO HELO  
NC: 250-SIZE  
NC: 250-AUTH CRAM-MD5 PLAIN  
NC: 250 HELP

Since the client has no idea about XCLIENT and the second EHLO, it is  
horribly confused. The session from the clients perspective looks like  
this:

NC: 220 [veyron.karlkraft.com](http://veyron.karlkraft.com) ESMTP ready  
CN: EHLO [client.karlkraft.com](http://client.karlkraft.com)  
NC: 250 AUTH PLAIN CRAM-MD5  
CN: AUTH PLAIN xxxxxxxxxxxxxxxxxxxxxxx  
NC: 235 2.0.0 OK  
NC: 220 Authenticated via XCLIENT  
NC: 250-/10.10.10.104  
NC: 250-EXPN  
NC: 250-NAME ADDR PROTO HELO  
NC: 250-SIZE  
NC: 250-AUTH CRAM-MD5 PLAIN  
NC: 250 HELP

The only way I am able to get close to a working connection is with the  
following two conditions:

Turn XCLIENT off - this of course makes it impossible for the back end  
server to know the authenticated username or source IP address.

Client must send HELO instead of EHLO - controlling all the clients is  
out of the question.

–  
Karl Kraft

---

<div class="post-metadata">

**Author:** ![Karl\_Kraft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f17d59/32.png) [@Karl\_Kraft](https://www.ruby-forum.com/u/Karl_Kraft)\
**Post date:** [August 6, 2010, 3:57am UTC](https://www.ruby-forum.com/t/smtp-auth-with-xclient-impossible-or-just-difficult/192728/2 "2010-08-06T03:57:59Z")

</div>

Hello!

On Wed, Aug 04, 2010 at 08:02:29AM -0500, Karl Kraft wrote:

> working my way through the mailing list and trying several  
> configurations, I am left thinking that XCLIENT with  
> authentication simply does not work. Has anyone ever managed to  
> get this to work?

[…]

> SN: 220 [explorer.karlkraft.com](http://explorer.karlkraft.com). - [explorer.karlkraft.com](http://explorer.karlkraft.com)  
> (NFSmtp/2006q2.1) Authorized network 10.10.0.0/255.255.0.0  
> NS: EHLO [veyron.karlkraft.com](http://veyron.karlkraft.com)  
> SN: 250-/10.10.10.104  
> SN: 250-EXPN  
> SN: 250-NAME ADDR PROTO HELO  
> SN: 250-SIZE  
> SN: 250-AUTH CRAM-MD5 PLAIN  
> SN: 250 HELP

Here actual problem happens. nginx doesn’t really understand  
multiline smtp replies, but usually handles them nicely once they  
happen to be in single tcp packet.

Most likely your tcp daemon sends ehlo reply in multiple packets.  
This isn’t good from performance point of view but anyway should  
be supported. Try the attached patch.

[…]

> The only way I am able to get close to a working connection is  
> with the following two conditions:
> 
> Turn XCLIENT off - this of course makes it impossible for the  
> back end server to know the authenticated username or source IP  
> address.
> 
> Client must send HELO instead of EHLO - controlling all the  
> clients is out of the question.

While XCLIENT is mostly unrelated - it forces nginx to use ESMTP  
with backend, i.e. use EHLO. In your case EHLO reply is multiline  
one and split across multiple packets. This in turn causes all  
the troubles (and the same thing happens if client itself uses  
ESMTP).

Maxim D.

---

<div class="post-metadata">

**Author:** ![Karl\_Kraft](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/f17d59/32.png) [@Karl\_Kraft](https://www.ruby-forum.com/u/Karl_Kraft)\
**Post date:** [August 6, 2010, 3:59am UTC](https://www.ruby-forum.com/t/smtp-auth-with-xclient-impossible-or-just-difficult/192728/3 "2010-08-06T03:59:44Z")

</div>

Hello!

On Fri, Aug 06, 2010 at 05:56:36AM +0400, Maxim D. wrote:

[…]

> Here actual problem happens. nginx doesn’t really understand  
> multiline smtp replies, but usually handles them nicely once they  
> happen to be in single tcp packet.
> 
> Most likely your tcp daemon sends ehlo reply in multiple packets.  
> This isn’t good from performance point of view but anyway should  
> be supported. Try the attached patch.

Oops, sorry, forgot to attach the patch. Next try… 🙂

Maxim D.
