Differences between revisions 1 and 10 (spanning 9 versions)
Revision 1 as of 2013-08-27 17:14:53
Size: 3555
Editor: libertechaa
Comment:
Revision 10 as of 2014-03-18 13:05:51
Size: 10864
Editor: gutefrage
Comment: more typos fixed; english corrected; hint for using DNS name for database access on both servers instead of xinetd
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:

#language en
Line 8: Line 6:
Often companies want to restrict the access to their groupware from the external (public side) and allow just few users or named users.
We will do that by setting a proxy who will check if the user who try to access to the groupware is in a specific group.
Often companies want to restrict the access to their groupware from the external/public/internet side, and allow access for just few users or named users.
We will do that by setting a proxy who will check if the user who tries to access the groupware is in a specific group.
Line 11: Line 9:
there are a server (called SOGOSERVER ) who sogo is already configurated and running. Internal users access directly on this server without restriction. In this study case Sogo's database is Postgresql but could be adapted to another Database. The authentication is made to an LDAP server (in this study case openldap) but could be ported on another ldap server, even Microsoft Active Directory. The users who are in the public side will access to Sogo by a Proxy Frontend (called PROXYSOGO).This proxy will verify if the user belongs to a group, if yes the user could connect, if not it couldn't. PROXYSOGO could be in a DMZ and SERVERSOGO in the trusted network.

users coming from the internal zone will log on SOGOSERVER and who come from the public side will be redirected on PROXYSOGO

In this study case the Proxy is set on a debian 7.x and there are already a Sogo server who is set with LDAP as authentication.

{{drawing:proxyarchitecture.adraw}}
There is a server called SOGOSERVER, on which sogo is already configured and running. Internal users access this server directly without restrictions. In this study case SOGo's database is Postgresql but could be adapted to another Database Management System (like MySQL or Oracle). The authentication is made trough an openLDAP server but could be ported to another ldap server, even Microsoft Active Directory.
The users who are on the public side will access SOGo through a proxy frontend called SOGOPROXY. This proxy will verify if the user belongs to a group. Only if the user is a member of the group she can connect to SOGo. SOGOPROXY can be in a DMZ and SOGOSERVER in the internal/private/trusted network.

Users coming from the private zone will directly log on at SOGOSERVER and those who come from the public side will be redirected to SOGOPROXY.

In this study case the SOGOPROXY server is set on a debian 7.x and there is already a SOGo server who is set with LDAP as authentication.

Line 21: Line 20:
First we must to install Sogo in the proxy (SOGOPROXY) but without the database First install SOGo at the proxy (SOGOPROXY) with database connectivity, but without the database itself.
Line 24: Line 23:
'''1. Install Sogo (only sogo not the database part)''' '''1. Install SOGo (only sogo not the database part)'''
Line 30: Line 29:
'''2. Install Xinetd ( Sogo don t know to access other another IP than the loopback to the database) it will serve at forwarder ''' '''2. Install Xinetd it will serve at forwarder for database access'''

SOGo stores database access URLs in its database itself. Therefore you have to use the same URLs on SOGOPROXY, as you use on SOGOSERVER!
In the standard configuration this is a localhost URL. Because of that you need a forwarder on SOGOPROXY, in order to reach the database on SOGOSERVER.

Hint:
This can be done in the sogo.conf on SOGOPROXY, if you use a non localhost DNS name for database access on SOGOSERVER too.
Line 46: Line 51:
cn=external access,dc=example,dc=com

cn=external

member: uid=alain dupont,dc=example,dc=com

objectclass: groupOfNames
{{{#!wiki yellow/solid
cn=external access,dc=example,dc=com <<BR>>
cn=external access <<BR>>
member: uid=alain dupont,ou=people,dc=example,dc=com <<BR>>
objectclass: groupOfNames <<BR>>
}}}
Line 56: Line 60:
create a file in /etc/xinetd.d called postgres (change SOGOSERVER by the IP or the hostname of your sogoserver) create a file in /etc/xinetd.d/ called postgres (replace SOGOSERVER with the IP or the hostname of your SOGOSERVER)
Line 59: Line 63:
service postgresql

{

socket_type =stream

wait =no

user = root

redirect = SOGOSERVER 5432

bind = 127.0.0.1
service postgresql <<BR>>
{ <<BR>>
 socket_type =stream <<BR>>
 wait =no <<BR>>
 user = root <<BR>>
 redirect = SOGOSERVER 5432 <<BR>>
 bind = 127.0.0.1 <<BR>>
} <<BR>>
}}}

'''3 Copy /etc/sogo/sogo.conf from SOGOSERVER'''

add in the sogo.conf the restriction by group in the user source section

'''filter="memberOf='cn=external access,dc=example,dc=com'";'''

You must add another user source with '''canAuthenticate = No;''' and '''isAddressBook = YES;''', if you want to search all users for autocompletion, sharing and invitations:

{{{

 SOGoUserSources = (
    {
      type = ldap;
      CNFieldName = cn;
      IDFieldName = uid;
      UIDFieldName = uid;
      baseDN = "dc=example,dc=com";
      bindDN = "cn=nobody,cn=internal,dc=example,dc=com";
      bindPassword = "password";
      canAuthenticate = YES;
      bindFields=(uid);
      hostname = ldap://myldapserver:389;
      SearchFieldNames=(uid,cn,sn,givenname,mail);
      filter="memberOf='cn=WEBMAIL,ou=FR,dc=example,dc=com'";
      id = auth;
      isAddressBook = NO;
      userPasswordAlgorithm = SSHA;
    },
 {
      type = ldap;
      CNFieldName = cn;
      IDFieldName = uid;
      UIDFieldName = uid;
      baseDN = "dc=example,dc=com";
      bindDN = "cn=nobody,cn=internal,dc=example,dc=com";
      bindPassword = "password";
      canAuthenticate = NO;
      hostname = ldap://myldapserver:389;
      SearchFieldNames=(uid,cn,sn,givenname,mail);
      id = public;
      displayName = "GLOBAL";
      isAddressBook = YES;
    }

}}}

Modify the values of the hosts to reflect the reality.
LDAP server, Imap server, Sieve Server must be set to SOGOSERVER.

In this way we will redirect all request made for the loopback to the SOGOSERVER

'''4 Nginx configuration on SOGOPROXY'''

This is the same as on SOGOSERVER see :

 [[ nginxSettings| See the configuration file ]]



'''5 On SOGOSERVER set the ACL on the database for allowing SOGOPROXY to connect'''

Modify the file : '''/etc/postgresql/8.4/main/postgresql.conf'''

replace listen_addresses = 'localhost' by listen_addresses = '*'

Modify file : '''/etc/postgresql/8.4/main/pg_hba.conf'''

Add the line : host sogo sogo SOGOPROXY/32 md5

Restart postgres

Restart ALL

You should now be able to access to SOGo web interface if you are in the group.

 

== Restricting external access to the Imap and Smtp services ==

We will use nginx too to restrict the access to IMAPS/SMTPS.

'''Authentication service'''

We need a service who will verify in LDAP if the user belongs to the access group. This little code in PHP will connect LDAP and will verify if the user is member of the access group.

Put this file in /var/lib/mailauth/auth.php

{{{
<?
    include "settings.php";
    $username=$_SERVER["HTTP_AUTH_USER"] ;
    $userpass=$_SERVER["HTTP_AUTH_PASS"] ;
    $protocol=$_SERVER["HTTP_AUTH_PROTOCOL"] ;
    $backend_port=110;
    if ($protocol=="imap") {
        $backend_port=143;
    }
    if ($protocol=="smtp") {
        $backend_port=25;
    }

    if (!authuser($username,$userpass)) {
        fail($username);
        exit;
    }

    $userserver=getmailserver($username,$protocol);
    pass($username,$userserver, $backend_port);

    // Authentication block
    function authuser($user,$pass)
    {
        global $ldap_baseDN,$ldap_bindDN,$ldap_bindpwd,$ldap_filter,$ldap_server;
        $conn=ldap_connect($ldap_server);
        if (! $conn)
        {
            flog("LDAP fail to connect server");
            return false;
        }
        $bind=ldap_bind($conn,$ldap_bindDN,$ldap_bindpwd);
        if (! $bind)
        {
            flog("LDAP fail to bind server");
            return false;
        }
        $query=sprintf($ldap_filter,$user);
        $result=ldap_search($conn, $ldap_baseDN, $query);
        if ($result == false)
        {
            flog("LDAP $query false");
            return false;
        }
        $info = ldap_get_entries($conn, $result);
        if ($info["count"] == 1)
        {
            return true;
        }
        return false;
    }


    function getmailserver($user,$protocol){
            global $imap_server,$smtp_server;
            if ($protocol == "smtp")
            {
                return $smtp_server;
            }
            else
            {
                return "$imap_server";
            }

    }

    function fail($user){
        flog("Auth FAIL : $user IP:". $_SERVER["HTTP_CLIENT_IP"]." p:".$_SERVER["HTTP_AUTH_PROTOCOL"]);
        header("Auth-Status: Invalid login or password");
        header("Auth-Server: 127.0.0.1");
        header("Auth-Port: 143");
        header("Auth-Wait: 5");
        exit;
    }

    function pass($user,$server,$port){
        flog("Auth OK : $user IP:". $_SERVER["HTTP_CLIENT_IP"]." p:".$_SERVER["HTTP_AUTH_PROTOCOL"]);
        header("Auth-Status: OK");
        header("Auth-Server: $server");
        header("Auth-Port: $port");
        exit;
    }
    function flog($message)
    {
        global $logfile;
        if ( $logfile != false)
        {
                $date = date("Y-m-d H:i");
                file_put_contents($logfile,$date." ".$message."\n", FILE_APPEND);
        }
    }
?>
}}}

I made a settings.php to put the parameters in a configfile.
Put this file in /var/lib/mailhauth/settings.php

{{{
<?
    //base DN , put here the DN Base of your LDAP server
    $ldap_baseDN="dc=example,dc=com";
    //User who is used to connect in the LDAP
    $ldap_bindDN="cn=nobody,cn=internal,dc=example,dc=com";
    // the password of this account
    $ldap_bindpwd="xyzabcedef";
    //the LDAP server
    $ldap_server="192.168.1.1";
    //the LDAP group who restrict access
    $ldap_group="cn=EXTERNALACL,dc=example,dc=com";
    //the LDAP filter to find the if the user belongs to the group
    $ldap_filter="(&(uid=%s)(memberof=$ldap_group))";
    //the Imap server where to redirect the request
    $imap_server="192.168.1.1";
    //same for SMTP
    $smtp_server="192.168.1.1";
    //logfile
    $logfile="/tmp/auth.log";
?>
}}}

'''Settings for nginx and php'''

On Debian install these packages (consult the documentation about your distribution and how to make nginx and php work together)

#apt-get install php5-cgi spawn-fcgi php5-ldap php5-xcache

Add in /etc/nginx/fastcgi_params

{{{
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}}}

Add in /etc/nginx/nginx.conf

{{{
mail {
 auth_http localhost:81/auth.php;
 # pop3_capabilities "TOP" "USER";
 # imap_capabilities "IMAP4rev1" "UIDPLUS";
 ssl_prefer_server_ciphers on;
 ssl_protocols TLSv1 SSLv3;
 ssl_ciphers HIGH:!ADH:!MD5:@STRENGTH;
 ssl_session_cache shared:TLSSL:16m;
 ssl_session_timeout 10m;
 #Adapt to you configuration certificate names
 ssl_certificate sslcerts/mycert.crt;
 ssl_certificate_key sslcerts/mykey.key;
 #Note : port 143 is redirected for Test only , deactivate it when the server is set in production
 server {
  listen 143;
  protocol imap;
  proxy on;
 }
 server {
  listen 993;
  protocol imap;
  proxy on;
  ssl on;
 }
 server {
  listen 465;
  protocol smtp;
  proxy on;
  ssl on;
  xclient off;
 }
Line 74: Line 331:
}}}

'''3 Copy /etc/sogo/sogo.conf from SOGOSERVER'''

add in the soho.conf the restrition by group in the source section

'''filter="memberOf='cn=external access,dc=example,dc=com'";'''

Modify the values of the hosts to reflect the configuration (ldap server, Imap server, Sieve Server) must set to SOGOSERVER.

In this way we will redirect all request made for the loopback to the SOGOSERVER

'''4 Nginx configuration on SOGOPROXY'''

This is the same as a server see :

 [[ nginxSettings ]]



'''5 On SOGOSERVER set the ACL on the database for allowing SOGOPROXY to connect'''

Modify the file : '''/etc/postgresql/8.4/main/postgresql.conf'''

replace isten_addresses = 'localhost' by listen_addresses = '*'

Modify file : '''/etc/postgresql/8.4/main/pg_hba.conf'''

Add the line : host sogo sogo SOGOPROXY/32 md5

Restart postgres

 

== More far by restricting external access to the Imap and Smtp services ==


Coming soon ...

}}}

Add in /etc/nginx/sites-enabled the file auth

{{{
server {
 listen 81;
 server_name localhost;
 root /var/lib/mailauth;
 index index.php index.html;
 access_log /var/log/nginx/mailauth.access.log;
 location ~ ^(.+\.php)(/.*)?$ {
 fastcgi_pass localhost:9000;
 include /etc/nginx/fastcgi_params;
}
}

}}}

Restart all services
If you are lucky and understood all it must run now :-)
Line 115: Line 355:
CategoryCategory

Proxy for controlling user acces to Sogo

Introduction

Often companies want to restrict the access to their groupware from the external/public/internet side, and allow access for just few users or named users. We will do that by setting a proxy who will check if the user who tries to access the groupware is in a specific group.

Architecture Overview

There is a server called SOGOSERVER, on which sogo is already configured and running. Internal users access this server directly without restrictions. In this study case SOGo's database is Postgresql but could be adapted to another Database Management System (like MySQL or Oracle). The authentication is made trough an openLDAP server but could be ported to another ldap server, even Microsoft Active Directory. The users who are on the public side will access SOGo through a proxy frontend called SOGOPROXY. This proxy will verify if the user belongs to a group. Only if the user is a member of the group she can connect to SOGo. SOGOPROXY can be in a DMZ and SOGOSERVER in the internal/private/trusted network.

Users coming from the private zone will directly log on at SOGOSERVER and those who come from the public side will be redirected to SOGOPROXY.

In this study case the SOGOPROXY server is set on a debian 7.x and there is already a SOGo server who is set with LDAP as authentication.

Installation of the needed packages

First install SOGo at the proxy (SOGOPROXY) with database connectivity, but without the database itself.

1. Install SOGo (only sogo not the database part)

  • apt-get install sogo

    apt-get install sope4.9-gdl1-postgresql ( in case of postgresql as database)

2. Install Xinetd it will serve at forwarder for database access

SOGo stores database access URLs in its database itself. Therefore you have to use the same URLs on SOGOPROXY, as you use on SOGOSERVER! In the standard configuration this is a localhost URL. Because of that you need a forwarder on SOGOPROXY, in order to reach the database on SOGOSERVER.

Hint: This can be done in the sogo.conf on SOGOPROXY, if you use a non localhost DNS name for database access on SOGOSERVER too.

  • apt-get install xinetd

3. Install Nginx (or Apache)

  • apt-get install nginx

Sogo's Settings

1. Create a LDAP group in your LDAP server

In this documentation the LDAP group who will filter the user will be called cn=external access,dc=example,dc=com

LDIF entry :

cn=external access,dc=example,dc=com
cn=external access
member: uid=alain dupont,ou=people,dc=example,dc=com
objectclass: groupOfNames

2 Settings for Xinetd

create a file in /etc/xinetd.d/ called postgres (replace SOGOSERVER with the IP or the hostname of your SOGOSERVER)

service postgresql
{

  • socket_type =stream
    wait =no
    user = root
    redirect = SOGOSERVER 5432
    bind = 127.0.0.1

}

3 Copy /etc/sogo/sogo.conf from SOGOSERVER

add in the sogo.conf the restriction by group in the user source section

filter="memberOf='cn=external access,dc=example,dc=com'";

You must add another user source with canAuthenticate = No; and isAddressBook = YES;, if you want to search all users for autocompletion, sharing and invitations:

 SOGoUserSources = (
    {
      type = ldap;
      CNFieldName = cn;
      IDFieldName = uid;
      UIDFieldName = uid;
      baseDN = "dc=example,dc=com";
      bindDN = "cn=nobody,cn=internal,dc=example,dc=com";
      bindPassword = "password";
      canAuthenticate = YES;
      bindFields=(uid);
      hostname = ldap://myldapserver:389;
      SearchFieldNames=(uid,cn,sn,givenname,mail);
      filter="memberOf='cn=WEBMAIL,ou=FR,dc=example,dc=com'";
      id = auth;
      isAddressBook = NO;
      userPasswordAlgorithm = SSHA;
    },
 {
      type = ldap;
      CNFieldName = cn;
      IDFieldName = uid;
      UIDFieldName = uid;
      baseDN = "dc=example,dc=com";
      bindDN = "cn=nobody,cn=internal,dc=example,dc=com";
      bindPassword = "password";
      canAuthenticate = NO;
      hostname = ldap://myldapserver:389;
      SearchFieldNames=(uid,cn,sn,givenname,mail);
      id = public;
      displayName = "GLOBAL";
      isAddressBook = YES;
    }

Modify the values of the hosts to reflect the reality. LDAP server, Imap server, Sieve Server must be set to SOGOSERVER.

In this way we will redirect all request made for the loopback to the SOGOSERVER

4 Nginx configuration on SOGOPROXY

This is the same as on SOGOSERVER see :

5 On SOGOSERVER set the ACL on the database for allowing SOGOPROXY to connect

Modify the file : /etc/postgresql/8.4/main/postgresql.conf

replace listen_addresses = 'localhost' by listen_addresses = '*'

Modify file : /etc/postgresql/8.4/main/pg_hba.conf

Add the line : host sogo sogo SOGOPROXY/32 md5

Restart postgres

Restart ALL

You should now be able to access to SOGo web interface if you are in the group.

Restricting external access to the Imap and Smtp services

We will use nginx too to restrict the access to IMAPS/SMTPS.

Authentication service

We need a service who will verify in LDAP if the user belongs to the access group. This little code in PHP will connect LDAP and will verify if the user is member of the access group.

Put this file in /var/lib/mailauth/auth.php

<?
    include "settings.php";
    $username=$_SERVER["HTTP_AUTH_USER"] ;
    $userpass=$_SERVER["HTTP_AUTH_PASS"] ;
    $protocol=$_SERVER["HTTP_AUTH_PROTOCOL"] ;
    $backend_port=110;
    if ($protocol=="imap") {
        $backend_port=143;
    }
    if ($protocol=="smtp") {
        $backend_port=25;
    }

    if (!authuser($username,$userpass)) {
        fail($username);
        exit;
    }

    $userserver=getmailserver($username,$protocol);
    pass($username,$userserver, $backend_port);

    // Authentication block
    function authuser($user,$pass)
    {
        global $ldap_baseDN,$ldap_bindDN,$ldap_bindpwd,$ldap_filter,$ldap_server;
        $conn=ldap_connect($ldap_server);
        if (! $conn)
        {
            flog("LDAP fail to connect server");
            return false;
        }
        $bind=ldap_bind($conn,$ldap_bindDN,$ldap_bindpwd);
        if (! $bind)
        {
            flog("LDAP fail to bind server");
            return false;
        }
        $query=sprintf($ldap_filter,$user);
        $result=ldap_search($conn, $ldap_baseDN, $query);
        if ($result == false)
        {
            flog("LDAP $query false");
            return false;
        }
        $info = ldap_get_entries($conn, $result);
        if ($info["count"] == 1)
        {
            return true;
        }
        return false;
    }


    function getmailserver($user,$protocol){
            global $imap_server,$smtp_server;
            if ($protocol == "smtp")
            {
                return $smtp_server;
            }
            else
            {
                return "$imap_server";
            }

    }

    function fail($user){
        flog("Auth FAIL : $user  IP:". $_SERVER["HTTP_CLIENT_IP"]." p:".$_SERVER["HTTP_AUTH_PROTOCOL"]);
        header("Auth-Status: Invalid login or password");
        header("Auth-Server: 127.0.0.1");
        header("Auth-Port: 143");
        header("Auth-Wait: 5");
        exit;
    }

    function pass($user,$server,$port){
        flog("Auth OK : $user  IP:". $_SERVER["HTTP_CLIENT_IP"]." p:".$_SERVER["HTTP_AUTH_PROTOCOL"]);
        header("Auth-Status: OK");
        header("Auth-Server: $server");
        header("Auth-Port: $port");
        exit;
    }
    function flog($message)
    {
        global $logfile;
        if ( $logfile != false)
        {
                $date = date("Y-m-d H:i");
                file_put_contents($logfile,$date." ".$message."\n", FILE_APPEND);
        }
    }
?>

I made a settings.php to put the parameters in a configfile. Put this file in /var/lib/mailhauth/settings.php

<?
    //base DN , put here the DN Base of your LDAP server
    $ldap_baseDN="dc=example,dc=com";
    //User who is used to connect in the LDAP 
    $ldap_bindDN="cn=nobody,cn=internal,dc=example,dc=com";
    // the password of this account
    $ldap_bindpwd="xyzabcedef";
    //the LDAP server
    $ldap_server="192.168.1.1";
    //the LDAP group who restrict access
    $ldap_group="cn=EXTERNALACL,dc=example,dc=com";
    //the LDAP filter to find the if the user belongs to the group
    $ldap_filter="(&(uid=%s)(memberof=$ldap_group))";
    //the Imap server where to redirect the request
    $imap_server="192.168.1.1";
    //same for SMTP
    $smtp_server="192.168.1.1";
    //logfile
    $logfile="/tmp/auth.log";
?>

Settings for nginx and php

On Debian install these packages (consult the documentation about your distribution and how to make nginx and php work together)

#apt-get install php5-cgi spawn-fcgi php5-ldap php5-xcache

Add in /etc/nginx/fastcgi_params

fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

Add in /etc/nginx/nginx.conf

mail {
 auth_http localhost:81/auth.php;
 # pop3_capabilities "TOP" "USER";
 # imap_capabilities "IMAP4rev1" "UIDPLUS";
 ssl_prefer_server_ciphers on;
 ssl_protocols TLSv1 SSLv3;
 ssl_ciphers HIGH:!ADH:!MD5:@STRENGTH;
 ssl_session_cache shared:TLSSL:16m;
 ssl_session_timeout 10m;
 #Adapt to you configuration certificate names
 ssl_certificate sslcerts/mycert.crt;
 ssl_certificate_key sslcerts/mykey.key;
 #Note : port 143 is redirected for Test only , deactivate it when the server is set in production 
 server {
  listen 143;
  protocol imap;
  proxy on;
 }
 server {
  listen 993;
  protocol imap;
  proxy on;
  ssl on;
 }
 server {
  listen 465;
  protocol smtp;
  proxy on;
  ssl on;
  xclient off;
 }
}

Add in /etc/nginx/sites-enabled the file auth

server {
 listen 81;
 server_name localhost;
 root /var/lib/mailauth;
 index index.php index.html;
 access_log /var/log/nginx/mailauth.access.log;
 location ~ ^(.+\.php)(/.*)?$ {
 fastcgi_pass localhost:9000;
 include /etc/nginx/fastcgi_params;
}
}

Restart all services If you are lucky and understood all it must run now :-)


ProxyForControllingExternalAcces (last edited 2015-03-12 04:48:08 by 4va54-8-83-155-94-6)