Authentication through Apache
A good sources of what is not going well is the apache logs, see /var/log/httpd/error_log if you cannot acces to your share
mod_authnz_external
https://code.google.com/p/mod-auth-external/
Mod_authnz_external and mod_auth_external are flexible tools for building custom basic authentication systems for the Apache HTTP Daemon. “Basic Authentication” is a type of authentication built into the HTTP protocol, in which the browser automatically pops up a login box when the user requests a protected resource, and the login ids and passwords entered are checked by Apache. Mod_auth*_external allows the password checking normally done inside Apache to be done by an separate external program running outside of Apache.
you must install some rpm from epel (already imported in nethforge)
yum install pwauth mod_authnz_external --enablerepo=epel
Use case only users authentication
you can create a virtual host for example in /etc/httpd/conf.d
AddExternalAuth pwauth /usr/bin/pwauth
SetExternalAuthMethod pwauth pipe
<Directory /path/2/the/web/app>
AuthName 'plop'
AuthBasicProvider external
AuthType Basic
AuthExternal pwauth
order deny,allow
deny from all
allow from all # you can restrict to the local network
Require user user1 user2 user3
#Instead of above you can use the valid-user (all valid users) directive
#Require valid-user
Satisfy all
</Directory>
Use case authentication of groups and users
you can create a virtual host for example in /etc/httpd/conf.d
AddExternalAuth pwauth /usr/bin/pwauth
SetExternalAuthMethod pwauth pipe
AddExternalGroup unixgroup /usr/bin/unixgroup
SetExternalGroupMethod unixgroup environment
<Directory /path/2/the/web/app>
AuthName 'plop'
AuthBasicProvider external
AuthType Basic
AuthExternal pwauth
GroupExternal unixgroup
AuthzUserAuthoritative off
order deny,allow
deny from all
allow from all # you can restrict to the local network
Require user user1 user2 user3
Require group group1 group2 group3
Satisfy all
</Directory>
Code example of /etc/e-smith/templates/httpd/ibay-default/70UserMODDAV and /etc/e-smith/templates/httpd/ibay-default/35pwauth
allow users to write or read the webdav share (if enabled) or access to the webshare
* /etc/e-smith/templates/httpd/ibay-default/35pwauth
{
use esmith::AccountsDB;
my $a = esmith::AccountsDB->open;
my $WebDav = $a->get_prop("$Name","HttpWebDav") || 'disabled';
my $UserAccess = $a->get_prop("$Name",'HttpUserAccess') || 'disabled';
if ($PasswordStatus eq 'UserGroup') {
$OUT .= qq(
#Set the path to pwauth/unixgroup for user/group authentication
AddExternalAuth pwauth /usr/bin/pwauth
SetExternalAuthMethod pwauth pipe
AddExternalGroup unixgroup /usr/bin/unixgroup
SetExternalGroupMethod unixgroup environment);
}
}
* /etc/e-smith/templates/httpd/ibay-default/70UserMODDAV
{
use esmith::AccountsDB;
my $a = esmith::AccountsDB->open_ro;
my @Writers = split (/[,]/, $AclWrite);
my @Readers = split (/[,]/, $AclRead);
#we retrieve the key name of user/group
my @users = map { $_->key } $a->users();
my @groups = map { $_->key } $a->groups();
my @readuser = 'admin';
my @readgroup = ($GroupAccess eq 'r') ? $OwningGroup : '';
my @writeuser = 'admin';
my @writegroup = ($GroupAccess eq 'rw') ? $OwningGroup : '';
#we separate user and group
foreach my $Reader (@Readers) {
push @readuser, $Reader if (grep /$Reader/,@users);
push @readgroup, $Reader if (grep /$Reader/, @groups);
}
foreach my $Writer (@Writers) {
push @writeuser, $Writer if (grep /$Writer/,@users);
push @writegroup, $Writer if (grep /$Writer/, @groups);
}
#we just want unique name, write access are also read access automatically
my %seen = ();
@readuser = sort (grep { ! $seen{ $_ }++ } (@readuser,@writeuser));
%seen = ();
@writeuser = sort (grep { ! $seen{ $_ }++ } (@writeuser));
%seen = ();
@readgroup = sort (grep { ! $seen{ $_ }++ } (@readgroup,@writegroup));
%seen = ();
@writegroup = sort (grep { ! $seen{ $_ }++ } (@writegroup));
#we delimit the allow permissions
my $webaccess;
if ($Access eq 'private') {
$webaccess = join(" \\\n ", split(' ', $PrivateAllow));
}
else {
$webaccess = 'all';
}
#enable DAV if requested
my $DAVOn = ($WebDav eq 'enabled') ? 'DAV On':'';
if ($PasswordStatus eq 'UserGroup') {
$OUT .= qq (
$DAVOn
AuthName $Name
AuthBasicProvider external
AuthType Basic
AuthExternal pwauth
GroupExternal unixgroup
AuthzUserAuthoritative off
# Read only access
<Limit GET PROPFIND OPTIONS LOCK UNLOCK REPORT>
order deny,allow
deny from all
allow from $webaccess
Require user @readuser
Require group @readgroup
</Limit>
# Write access
<LimitExcept GET PROPFIND OPTIONS LOCK UNLOCK REPORT>
order deny,allow
deny from all
allow from $webaccess
Require user @writeuser
Require group @writegroup
</LimitExcept>);
}
}
LDAP Authentication
Here we don't need to install some apache module, they are already loaded in apache, I'm talking about
LoadModule ldap_module /path/to/mod_ldap.so LoadModule authnz_ldap_module /path/to/mod_authnz_ldap.so
You have an excellent howTo on ldap authentication → http://archive09.linux.com/feature/120050
Use case user authentication
you can create a virtual host for example in /etc/httpd/conf.d
Alias /cygwin /usr/share/BackupPC/cygwin
<Directory /usr/share/BackupPC/cygwin>
Options -Indexes
AllowOverride None
Order Deny,Allow
Deny from All
allow from all
AuthName "cygwin-rsyncd setup"
AuthType Basic
AuthBasicProvider ldap
AuthLDAPBindDN cn=libuser,dc=directory,dc=nh
AuthLDAPBindPassword **PASSWORDVALUE** # see 'cat /var/lib/nethserver/secrets/libuser' to retrieve the password
AuthLDAPURL "ldap://localhost/ou=People,dc=directory,dc=nh?uid?sub?(objectClass=posixAccount)"
require user admin user1 user2
#Instead of above you can use the valid-user (all valid users) directive
#Require valid-user
Satisfy all
</Directory>
Use case Group and user authentications
you can create a virtual host for example in /etc/httpd/conf.d
Alias /cygwin /usr/share/BackupPC/cygwin
<Directory /usr/share/BackupPC/cygwin>
Options -Indexes
AllowOverride None
Order Deny,Allow
Deny from All
allow from all
AuthName "cygwin-rsyncd setup"
AuthType Basic
AuthzLDAPAuthoritative on #Could be omitted since the default setting is "on," but is left here for clarity.
AuthLDAPGroupAttribute memberUid #indicates which attribute in the LDAP group record to match with the Uid
AuthLDAPGroupAttributeIsDN off #tells Apache to use the distinguished name of the client. Otherwise, the username will be used.
AuthBasicProvider ldap
AuthLDAPBindDN cn=libuser,dc=directory,dc=nh
AuthLDAPBindPassword **PASSWORDVALUE** # see 'cat /var/lib/nethserver/secrets/libuser' to retrieve the password
AuthLDAPURL "ldap://localhost/ou=People,dc=directory,dc=nh?uid?sub?(objectClass=posixAccount)"
Require ldap-user user1 user2 user3 user4
Require ldap-group cn=group1,ou=Groups,dc=directory,dc=nh #grants access to members of the group. For multiple groups, add an additional directive for each.
Require ldap-attribute gidNumber=420 #handles the primary users of gid 420, For multiple groups, add an additional directive for each.
Satisfy all
</Directory>
Code example of /etc/e-smith/templates/httpd/ibay-default/70UserMODDAV
allow users to write or read the webdav share (if enabled) or access to the webshare
{
use esmith::AccountsDB;
use NethServer::Password;
return '' unless ($PasswordStatus eq 'UserGroup');
my $a = esmith::AccountsDB->open_ro;
my $HttpPass = NethServer::Password::store('libuser');
#admin RW permissions, we retrieve permissions of the owning group
my @readuser = 'admin';
my @readgroup = ($GroupAccess eq 'r') ? $OwningGroup : '';
my @writeuser = 'admin';
my @writegroup = ($GroupAccess eq 'rw') ? $OwningGroup : '';
#we separate user and group
my @users = map { $_->key } $a->users();
my @groups = map { $_->key } $a->groups();
foreach my $Reader (split (/[,]/, $AclRead)) {
push @readuser, $Reader if (grep /$Reader/,@users);
push @readgroup, $Reader if (grep /$Reader/, @groups);
}
foreach my $Writer (split (/[,]/, $AclWrite)) {
push @writeuser, $Writer if (grep /$Writer/,@users);
push @writegroup, $Writer if (grep /$Writer/, @groups);
}
#we just want unique name, write access are also read access automatically
my %seen = ();
@readuser = sort (grep { ! $seen{ $_ }++ } (@readuser,@writeuser));
%seen = ();
@writeuser = sort (grep { ! $seen{ $_ }++ } (@writeuser));
%seen = ();
@readgroup = sort (grep { ! $seen{ $_ }++ } (@readgroup,@writegroup));
%seen = ();
@writegroup = sort (grep { ! $seen{ $_ }++ } (@writegroup));
#we delimit the allow permissions
my $webaccess;
if ($Access eq 'private') {
$webaccess = join(" \\\n ", split(' ', $PrivateAllow));
}
else {
$webaccess = 'all';
}
#enable DAV if requested
my $DAVOn = ($WebDav eq 'enabled') ? 'DAV On':'';
$OUT .= qq (
#
## User and group authentification
#
$DAVOn
AuthName $Name
AuthType Basic
AuthBasicProvider ldap
AuthzLDAPAuthoritative on
AuthLDAPGroupAttribute memberUid
AuthLDAPGroupAttributeIsDN off
AuthLDAPBindDN cn=libuser,dc=directory,dc=nh
AuthLDAPBindPassword $HttpPass
AuthLDAPURL "ldap://localhost/ou=People,dc=directory,dc=nh?uid?sub?(objectClass=posixAccount)"
# Read only access
<Limit GET PROPFIND OPTIONS LOCK UNLOCK REPORT>
order deny,allow
deny from all
allow from $webaccess
Require ldap-user @readuser
);
foreach my $rgroup (@readgroup) {
$OUT .= " Require ldap-group cn=$rgroup,ou=Groups,dc=directory,dc=nh\n" if ($rgroup);
}
$OUT .= qq ( Satisfy all
</Limit>
# Write access
<LimitExcept GET PROPFIND OPTIONS LOCK UNLOCK REPORT>
order deny,allow
deny from all
allow from $webaccess
Require ldap-user @writeuser
);
foreach my $wgroup (@writegroup) {
$OUT .= " Require ldap-group cn=$wgroup,ou=Groups,dc=directory,dc=nh\n" if ($wgroup);
}
$OUT .= qq ( Satisfy all
</LimitExcept>);
}
Debug and deploy
Testing LDAP authentication from a Web browser can be frustrating, because the only thing you know is whether access was granted or not. You don't get any kind of feedback on why something did not work. For verbose information on each step in the process, set the LogLevel debug option in Apache. With debugging active, Apache will record the connection status to the LDAP server, what attributes and values were requested, what was returned, and why conditions were met or not met. This information can be invaluable in fine-tuning LDAP access controls.
mod_authnz_pam
Here we will use the pam authentication needed specially for NS7 since we can have two LDAP (openldap or SAMBA4)
First you need to install mod_authnz_pam
yum install mod_authnz_pam
- then you must uncomment the apache module
vim /etc/httpd/conf.modules.d/55-authnz_pam.conf
#LoadModule authnz_pam_module modules/mod_authnz_pam.so
to
LoadModule authnz_pam_module modules/mod_authnz_pam.so
- or add after the 'Alias'
<IfModule !authnz_pam_module> LoadModule authnz_pam_module modules/mod_authnz_pam.so </IfModule>
For example this is the apache configuration I made to authenticate a user in ttrss
cat /etc/httpd/conf.d/tt-rss.conf
Alias /tt-rss /usr/share/tt-rss
<IfModule !authnz_pam_module>
LoadModule authnz_pam_module modules/mod_authnz_pam.so
</IfModule>
<Location /tt-rss>
AuthName "Tiny Tiny RSS"
AuthType Basic
AuthBasicProvider PAM
AuthPAMService ttrss
Require valid-user
</Location>
<Directory /usr/share/tt-rss>
AddType application/x-httpd-php .php
php_admin_value open_basedir /usr/share/tt-rss:/var/lock/tt-rss:/var/cache/tt-rss:/tmp
php_admin_value memory_limit 256M
php_admin_flag allow_url_fopen on
SSLRequireSSL on
Require ip 127.0.0.1 192.168.12.0/255.255.255.0
</Directory>
<Directory /usr/share/tt-rss/schema>
Require all denied
</Directory>
<Directory /usr/share/tt-rss/install>
Require all denied
</Directory>
Then you must set pam to use the service ttrss you created
vim /etc/pam.d/ttrss
auth required pam_sss.so account required pam_sss.so
Restart apache
systemctl restart httpd