Welcome! Log In Create A New Profile

Advanced

Nginx mail proxy LDAP iRedMail

Posted by shiver25 
shiver25
Nginx mail proxy LDAP iRedMail
August 01, 2018 11:00AM
Hi there,

I try configure a little mail infrastructure but i have problem with this.
So i have exacly three servers. One is MX (frontend) there is nginx with
configuration:

user nginx;
worker_processes 2;
error_log /var/log/nginx/error.log info;
pid /var/run/nginx.pid;
load_module /usr/lib64/nginx/modules/ngx_http_perl_module.so;
load_module /usr/lib64/nginx/modules/ngx_mail_module.so;


events {
worker_connections 1024;
multi_accept on;
}

http {
perl_modules perl/lib;
perl_require mailauth.pm;

server {
location /auth {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
perl mailauth::handler;
}
}
}

mail {
auth_http 127.0.0.1:80/auth;

pop3_capabilities "TOP" "USER";
imap_capabilities "IMAP4rev1" "UIDPLUS";

server {
listen 110;
protocol pop3;
proxy on;
}

server {
listen 143;
protocol imap;
proxy on;
}

server {
listen 25;
protocol smtp;
proxy on;
}
}

And i try write auth script in perl, look like:

package mailauth;

use strict;
use warnings;
use nginx;
use Net::LDAP;

my $mail_server1 = "10.12.1.109";
my $mail_server2 = "10.12.1.109";

our $mail_server_ip={};
our $protocol_ports={};
$mail_server-ip->{'mailhost01'}="10.12.1.109";
$mail_server_ip->{'mailhost02'}="192.168.1.33";
$protocol_ports->{'pop3'}=110;
$protocol_ports->{'imap'}=143;

my $ldapconnect = Net::LDAP->new( "10.12.1.109",
version => 3,
port => 389 ) or die [email protected];


my $bind = $ldapconnect->bind( "cn=vmail,dc=poczta,dc=coml",
password => "PPkRSNeYtIDm7QXAq7Dr" );
if ( $bind->code ) {
LDAPerror( "Bind: ", $bind);
}


sub handler {

my $r = shift;


our $mail_server;
my $auth_user->execute($r->header_in("Auth-User"));
if ($auth_user =~ m/^[abcdefghijklmp]/) {
$mail_server = $mail_server1;
} else {
$mail_server = $mail_server2;
}



my $search = $ldapconnect->search(
base => "o=domains,dc=poczta,dc=com",
filter => '(&(mail=' . $r->header_in("Auth-User") . '))'
);


my $goto = $search->entry(0)->get_value('mail');
$r->header_out( "Auth-Status", "OK" );
$r->header_out( "Auth-Server", $mail_server);
$r->header_out( "Auth-Port",
$protocol_ports->{$r->header_in("Auth-Protocol")});
$r->send_http_header("text/html");



return OK;
}
1;

$ldapconnect->unbind;

__END__


Two backend servers installed with LDAP form iRedMail package. I want have
two servers backend with half and half users. So i add to script logic
like:

our $mail_server;
my $auth_user->execute($r->header_in("Auth-User"));
if ($auth_user =~ m/^[abcdefghijklmp]/) {
$mail_server = $mail_server1;
} else {
$mail_server = $mail_server2;
}

Check with curl:
curl -i -H 'Auth-User: [email protected]' -H 'Auth-Pass: supersecret' -H
'Auth-Protocol: imap' 10.12.1.128:80/auth

and ive got:

HTTP/1.0 200 OK
Server: nginx/1.12.2
Date: Wed, 01 Aug 2018 08:40:49 GMT
Content-Type: text/html
Auth-Status: OK
Auth-Server:
Auth-Port: 143


telnet 10.12.1.128 143
Trying 10.12.1.128...
Connected to 10.12.1.128.
Escape character is '^]'.
* OK IMAP4 ready
LOGIN [email protected] supersecret
LOGIN BAD invalid command
Connection closed by foreign host.

Posted at Nginx Forum: https://forum.nginx.org/read.php?2,280741,280741#msg-280741

_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Maxim Dounin
Re: Nginx mail proxy LDAP iRedMail
August 01, 2018 03:10PM
Hello!

On Wed, Aug 01, 2018 at 04:50:27AM -0400, shiver25 wrote:

> Hi there,
>
> I try configure a little mail infrastructure but i have problem with this.
> So i have exacly three servers. One is MX (frontend) there is nginx with
> configuration:
>
> user nginx;
> worker_processes 2;
> error_log /var/log/nginx/error.log info;
> pid /var/run/nginx.pid;
> load_module /usr/lib64/nginx/modules/ngx_http_perl_module.so;
> load_module /usr/lib64/nginx/modules/ngx_mail_module.so;
>
>
> events {
> worker_connections 1024;
> multi_accept on;
> }
>
> http {
> perl_modules perl/lib;
> perl_require mailauth.pm;
>
> server {
> location /auth {
> proxy_set_header Host $host;
> proxy_set_header X-Real-IP $remote_addr;
> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Just a side note: these proxy_set_header directives are useless.

> perl mailauth::handler;
> }
> }
> }

[...]

> And i try write auth script in perl, look like:
>
> package mailauth;
>
> use strict;
> use warnings;
> use nginx;
> use Net::LDAP;
>
> my $mail_server1 = "10.12.1.109";
> my $mail_server2 = "10.12.1.109";
>
> our $mail_server_ip={};
> our $protocol_ports={};
> $mail_server-ip->{'mailhost01'}="10.12.1.109";

With "-" here, loading the configuration is expected to fail with
an error like:

nginx: [emerg] require_pv("mailauth.pm") failed: "Can't use bareword ("ip") as a HASH ref while "strict refs" in use at /path/to/mailauth.pm line 13.

If the code provided exactly as used, likely you are testing with
some older version which does not have this bug.

In no particular order:

- make sure to reload nginx configuration after changing the perl
module;

- try looking into nginx error logs, it might have helpful information.

Note well that using embedded perl for potentially blocking
lookups in the LDAP database might not be a good idea. Quoting
http://nginx.org/en/docs/http/ngx_http_perl_module.html:

: While the Perl module is performing a long-running operation, such
: as resolving a domain name, connecting to another server, or
: querying a database, other requests assigned to the current worker
: process will not be processed. It is thus recommended to perform
: only such operations that have predictable and short execution
: time, such as accessing the local file system.

[...]

--
Maxim Dounin
http://mdounin.ru/
_______________________________________________
nginx mailing list
nginx@nginx.org
http://mailman.nginx.org/mailman/listinfo/nginx
Sorry, only registered users may post in this forum.

Click here to login