Forum: NGINX Configuring nginx as mail proxy

98ea802a522c50e47ff6339f8782d161?d=identicon&s=25 Laurent Bonetto (Guest)
on 2012-10-24 16:28
(Received via mailing list)
I need to use nginx as a mail proxy. I am completely new to nginx and
need some help with the configuration.

Here is what I did:

First I built a service that mocks the authentication services described
here: http://wiki.nginx.org/NginxMailCoreModule. For example,

curl -v -H "Host:auth.server.hostname" -H "Auth-Method:plain" -H
"Auth-User:user" -H "Auth-pass:123" -H "Auth-Protocol:imap" -H
"Auth-Login-Attempt:1" -H "Client-IP: 192.168.1.1"
http://localhost:8080/authorize
returns the following response header (no matter what Auth-User,
Auth-Protocol, and Client-IP are for now):

< HTTP/1.1 200 OK
< Content-Type: text/html;charset=ISO-8859-1
< Auth-Status: OK
< Auth-Server: <my mail server here>
< Auth-Port: 110
Second I installed nginx on my mac after installing macports:

$ sudo port -d selfupdate
$ sudo port install nginx
Third I created an nginx.conf with the following:

  worker_processes  1;

  error_log  /var/log/nginx/error.log info;

  mail {
    # not needed because returned in Auth-Server actually?
    server_name  <my mail server here>;

    auth_http    http://localhost:8080/authorize;

    pop3_auth         plain apop cram-md5;
    pop3_capabilities "LAST" "TOP" "USER" "PIPELINING" "UIDL";

    xclient off;

    server {
          listen     110;
          protocol   pop3;
          proxy      on;
          proxy_pass_error_message  on;
    }
  }
Here is what I got running nginx:

$ nginx -V nginx version: nginx/1.2.4 configure arguments:
--prefix=/opt/local --with-cc-opt='-I/opt/local/include -O2'
--with-ld-opt=-L/opt/local/lib
--conf-path=/opt/local/etc/nginx/nginx.conf
--error-log-path=/opt/local/var/log/nginx/error.log
--http-log-path=/opt/local/var/log/nginx/access.log
--pid-path=/opt/local/var/run/nginx/nginx.pid
--lock-path=/opt/local/var/run/nginx/nginx.lock
--http-client-body-temp-path=/opt/local/var/run/nginx/client_body_temp
--http-proxy-temp-path=/opt/local/var/run/nginx/proxy_temp
--http-fastcgi-temp-path=/opt/local/var/run/nginx/fastcgi_temp
--http-uwsgi-temp-path=/opt/local/var/run/nginx/uwsgi_temp --with-ipv6

$ nginx nginx: [emerg] unknown directive "mail" in
/opt/local/etc/nginx/nginx.conf:6

The only mention of that error on the web brings up a discussion in
Russian and the translation is "This question is no longer relevant"

My questions:

Why am I getting this unknow directive?

Does my config look correct at first sight or am I missing some key
component for the mail proxy to work using the authentication approach
described here: http://wiki.nginx.org/NginxMailCoreModule?


Thanks a lot. мерси!
96321bb7fd6f712aa7785ce2d58388f2?d=identicon&s=25 Anton Yuzhaninov (Guest)
on 2012-10-24 16:42
(Received via mailing list)
On 10/24/12 18:27, Laurent Bonetto wrote:
> --error-log-path=/opt/local/var/log/nginx/error.log
> --http-log-path=/opt/local/var/log/nginx/access.log
> --pid-path=/opt/local/var/run/nginx/nginx.pid
> --lock-path=/opt/local/var/run/nginx/nginx.lock
> --http-client-body-temp-path=/opt/local/var/run/nginx/client_body_temp
> --http-proxy-temp-path=/opt/local/var/run/nginx/proxy_temp
> --http-fastcgi-temp-path=/opt/local/var/run/nginx/fastcgi_temp
> --http-uwsgi-temp-path=/opt/local/var/run/nginx/uwsgi_temp --with-ipv6
>
> $ nginx nginx: [emerg] unknown directive "mail" in
/opt/local/etc/nginx/nginx.conf:6
>

nginx -V show, that there is no mail module is build.

--with-mail should be added to configure porameters.

Try to see
port variants nginx
my be it is possible to build nginx with mail module via mac ports.

--
  Anton Yuzhaninov
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2012-10-24 16:54
(Received via mailing list)
Hello!

On Wed, Oct 24, 2012 at 10:27:33AM -0400, Laurent Bonetto wrote:

> I need to use nginx as a mail proxy. I am completely new to
> nginx and need some help with the configuration.

[...]

> --http-fastcgi-temp-path=/opt/local/var/run/nginx/fastcgi_temp
>
> My questions:
>
> Why am I getting this unknow directive?

To use nginx mail proxy module, you have to enable it during
compilation using the --with-mail configure argument.  From the
"nginx -V" output you've provided it's clear that nginx binary you
are using doesn't have mail module compiled in.

See here for more details:
http://nginx.org/en/docs/mail/ngx_mail_core_module.html

[...]

--
Maxim Dounin
http://nginx.com/support.html
98ea802a522c50e47ff6339f8782d161?d=identicon&s=25 Laurent Bonetto (Guest)
on 2012-10-24 17:50
(Received via mailing list)
Thanks. That was indeed my first issue. I did sudo port edit nginx,
added --with-mail to the config options, reinstalled, and now I am
passed that error.

I then got an error that no events was present so I just added
 events {
 worker_connections 1;
 }

Now nginx is starting but I never see any hit to my mock service despite
it being specified in auth_http
    auth_http    http://localhost:8080/authorize;
No errors reported in the error log.

When is nginx expected to hit the url specified in nginx? When it gets
launched? When an event occurs on the ports 110 and 2525 with the
protocols I specified?

I tried sending emails to/from my mail server that uses POP3 on port 110
and SMTP on port 2525 and never saw any hit to the authorize url. Am I
missing another component in my config?

Again, here is my current config:

   worker_processes  1;

  error_log  /var/log/nginx/error.log info;

 events {
 worker_connections 1;
 }

  mail {
    server_name       <my mail server>;
    auth_http    http://localhost:8080/authorize;

    pop3_auth         plain apop cram-md5;
    pop3_capabilities "LAST" "TOP" "USER" "PIPELINING" "UIDL";

    smtp_auth         login plain cram-md5;
    smtp_capabilities "SIZE 10485760" ENHANCEDSTATUSCODES 8BITMIME DSN;

   xclient           off;

    server {
  # SMTP on port 2525 not 25
        listen   2525;
        protocol smtp;
    }
    server {
          listen     110;
          protocol   pop3;
#          proxy      on;
          proxy_pass_error_message  on;
    }
 }
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2012-10-24 18:27
(Received via mailing list)
Hello!

On Wed, Oct 24, 2012 at 11:49:43AM -0400, Laurent Bonetto wrote:

> Thanks. That was indeed my first issue. I did sudo port edit
> nginx, added --with-mail to the config options, reinstalled, and
> now I am passed that error.
>
> I then got an error that no events was present so I just added
> events {
>  worker_connections 1;
>  }

This isn't going to work.  With such a low number of worker
connections nginx won't be able to start worker processes properly
(unless you have no listening sockets configured).

Try looking into error log, you should see something like:

2012/10/24 20:17:53 [alert] 58202#0: 1 worker_connections are not enough
2012/10/24 20:17:53 [notice] 58201#0: signal 20 (SIGCHLD) received
2012/10/24 20:17:53 [notice] 58201#0: worker process 58202 exited with
code 2
2012/10/24 20:17:53 [alert] 58201#0: worker process 58202 exited with
fatal code 2 and cannot be respawned

You have to set worker_processes to something reasonable.
Something like 512 as by default is usually a good choice for a
small test server.

> Now nginx is starting but I never see any hit to my mock service
> despite it being specified in auth_http
>     auth_http    http://localhost:8080/authorize;
> No errors reported in the error log.
>
> When is nginx expected to hit the url specified in nginx? When
> it gets launched? When an event occurs on the ports 110 and 2525
> with the protocols I specified?

The auth service is requested when nginx needs to authenticate a
client and to find out a backend server address to proxy the
client to.

--
Maxim Dounin
http://nginx.com/support.html
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2012-10-24 18:36
(Received via mailing list)
Hello!

On Wed, Oct 24, 2012 at 08:26:52PM +0400, Maxim Dounin wrote:

[...]

> You have to set worker_processes to something reasonable.

Ops, I meant to write "worker_connections" here.

> Something like 512 as by default is usually a good choice for a
> small test server.

[...]

--
Maxim Dounin
http://nginx.com/support.html
98ea802a522c50e47ff6339f8782d161?d=identicon&s=25 Laurent Bonetto (Guest)
on 2012-10-24 23:39
(Received via mailing list)
Hi Maxim,

Thank you for sticking with me on this. I appreciate very much.

I did understand you meant to change the number of worker_connections.
The only reason why I had lowered it was that I got a warning:
nginx: [warn] 1024 worker_connections exceed open file resource limit:
256

After pointing my mail client to localhost, I was finally able to see
nginx hit my mock for an authentication request so there is definitely
some progress! Unfortunately, the proxying is still not working. More
precisely:

nginx hits my authenticate mock server with:
Host: localhost
Auth-User: <my user name>
Auth-Pass: <my password>
Auth-Protocol: pop3
Auth-Login-Attempt: 1
Client-IP: 192.168.1.104
- If my mock responds with
< HTTP/1.1 200 OK
< Content-Type: text/html
< Auth-Status: Invalid login or password
< Auth-Wait: 3
< Content-Length: 0
Then my mail client tells me that I have the incorrect username or
password, as expected.

- However, if my mock responds with:
< Auth-Status: OK
< Auth-Server: <my mail server>
< Auth-Port: 110
The the mail client responds with an internal server error.
I added the Auth-Pass (which should not be needed anyway) in the
response and that didn't help.


Since I didn't see any error in the error.log from nginx I used
wireshark to monitor traffic. I filtered on tcp.port eq 110 and compared
side by side the traffic coming from an account using a direct
connection to my mail server, and an account going through the nginx
proxy. In the second case (through proxy), I do not see any traffic
going out to my mail server, suggesting it does not get the info it was
expecting from my authentication service.

- Can you think of something I am missing?
- How do I even go about debugging what's happening here apart from what
I am already doing (using wireshark)?

Again, for info, here is my current config:


 worker_processes  1;

  error_log  /var/log/nginx/error.log info;

 events {
 worker_connections 1024;
 }

  mail {
  # I assume server_name comes from Auth-Server so I tried commenting
out. Same behavior.
    server_name       <my mail server>;
    auth_http   localhost:8080/authorize;

    pop3_auth         plain;
    pop3_capabilities "TOP" "USER" "UIDL";

    smtp_auth         login plain cram-md5;
    smtp_capabilities "SIZE 10485760" ENHANCEDSTATUSCODES 8BITMIME DSN;

   xclient           off;

    server {
        listen   2525;
        protocol smtp;
    }
    server {
          listen     110;
          protocol   pop3;
          proxy      on;
          proxy_pass_error_message  on;
    }
 }
A8108a0961c6087c43cda32c8616dcba?d=identicon&s=25 Maxim Dounin (Guest)
on 2012-10-25 00:55
(Received via mailing list)
Hello!

On Wed, Oct 24, 2012 at 05:38:29PM -0400, Laurent Bonetto wrote:

> I did understand you meant to change the number of
> worker_connections. The only reason why I had lowered it was
> that I got a warning:
> nginx: [warn] 1024 worker_connections exceed open file resource limit: 256

This indicate that you have very low open file resource limit set.
Easiest way to fix this is to use worker_limit_nofile nginx
configuration directive, see here:

http://nginx.org/r/worker_limit_nofile

Of course tuning your OS and/or using ulimit will do the trick as
well.  Using worker_connections set to something like 128 will
help as well, but it's just to low for any real work and may be
only used for testing.

> Auth-Login-Attempt: 1
> < Auth-Status: OK
> < Auth-Server: <my mail server>
> < Auth-Port: 110
> The the mail client responds with an internal server error.
> I added the Auth-Pass (which should not be needed anyway) in the
> response and that didn't help.

Do you return response without http response line, i.e.
"HTTP/1.1 200 OK"?

What's exactly in the Auth-Server header returned?  Note that this
must be an IP address, not a hostname.

> - How do I even go about debugging what's happening here apart
> from what I am already doing (using wireshark)?

Appropriate errors should be logged by nginx into error log.  I
would suggests there should be something like

2012/10/25 02:29:10 [error] 64793#0: *1 auth http server 127.0.0.1:8081
sent invalid server address:"foobar" while in http auth state ...

this time.  It's strange you don't see anything.

Detailed debug information may be obtained using debug log, see
http://nginx.org/en/docs/debugging_log.html.

[...]

>   mail {
>   # I assume server_name comes from Auth-Server so I tried commenting out. Same
behavior.
>     server_name       <my mail server>;

Just a side note: server_name is needed mostly to present
something to a client when it connects, see here:

http://nginx.org/en/docs/mail/ngx_mail_core_module...

It can't be from Auth-Server as it's only available later, after
auth http service request.  It should be safe to omit it though,
machine hostname will be used by default.

[...]

--
Maxim Dounin
http://nginx.com/support.html
98ea802a522c50e47ff6339f8782d161?d=identicon&s=25 Laurent Bonetto (Guest)
on 2012-10-25 03:34
(Received via mailing list)
Maxime,

Thanks so much. This was the key:
> Note that this must be an IP address, not a hostname.
My mail server was passing me a hostname, which nginx passed to the
authenticate service. I had assumed it was fine to return a hostname.
Returning the IP instead did the trick.

I have now the proxy working inbound and outbound.

Much appreciated also your clarifications regarding the low open file
resource and server_name.

You were of a big help today.

Laurent
A695033078699ab6874a9f48c753f5a2?d=identicon&s=25 Yanfeng L. (yanfeng_l)
on 2012-11-01 11:45
Laurent Bonetto wrote in post #1081041:
> Maxime,
>
> Thanks so much. This was the key:
>> Note that this must be an IP address, not a hostname.
> My mail server was passing me a hostname, which nginx passed to the
> authenticate service. I had assumed it was fine to return a hostname.
> Returning the IP instead did the trick.
>
> I have now the proxy working inbound and outbound.
>
> Much appreciated also your clarifications regarding the low open file
> resource and server_name.
>
> You were of a big help today.
>
> Laurent

Thanks for sharing the info.

Can the SMTP/IMAP service behind the mail proxy be SSL based ones like
smtp.gmail.com/imap.gmail.com (of course use IP address instead of DNS
name for Auth-Server here)?
2974d09ac2541e892966b762aad84943?d=identicon&s=25 useopenid (Guest)
on 2012-11-03 01:11
(Received via mailing list)
I am looking at proxying to google as well, and thus need SSL on the
backside (and would like it on general principles for other cases as
well),
however it does not appear that nginx supports this.  I would expect
this to
be the default if an incoming connection is using ssl, or, at the very
least, specified in the protocol parameter in the server {} block (e.g.
pop3s, imaps, smtps or smtp-starttls).  Neither appears to be the case,
nor
do I see any options that suggest the ability to enable it in some other
way...

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,232147,232466#msg-232466
2974d09ac2541e892966b762aad84943?d=identicon&s=25 dukzcry (Guest)
on 2014-02-24 20:11
(Received via mailing list)
useopenid Wrote:
-------------------------------------------------------
> I am looking at proxying to google as well, and thus need SSL on the
> backside (and would like it on general principles for other cases as
> well)

Here you go: http://forum.nginx.org/read.php?2,219069,247910#msg-247910

Posted at Nginx Forum:
http://forum.nginx.org/read.php?2,232147,247911#msg-247911
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.