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. мерси!
on 2012-10-24 16:28
on 2012-10-24 16:42
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
on 2012-10-24 16:54
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
on 2012-10-24 17:50
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;
}
}
on 2012-10-24 18:27
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
on 2012-10-24 18:36
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
on 2012-10-24 23:39
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;
}
}
on 2012-10-25 00:55
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
on 2012-10-25 03:34
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
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)?
on 2012-11-03 01:11
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
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
Log in with Google account | Log in with Yahoo account
No account? Register here.