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