Using WUR Authentication

From LUG
Revision as of 08:39, 17 August 2018 by Lith010 (talk | contribs) (→‎Winbind)
Jump to navigation Jump to search

At WUR we have a centrally administered Microsoft Active Directory server that provides authentication details for all internally registered users. Conveniently, it is presented via a semi-standard LDAP interface, allowing it to be used to provide identification and other information about users to anyone that can reach and authenticate against it.

The Basics

If you're intending to use the LDAP interface, you'll need the following command to work at all. Start by getting hold of ldapsearch, usually provided as part of package ldap-utils. This tool allows you to make requests to the LDAP.

Try the following command (using your own login details, e,g, user001):

ldapsearch -x -H ldaps://ldap.wurnet.nl -D <your_id>@wurnet.nl -W "(samaccountname=<your_id>)" -b "dc=wurnet,dc=nl"

Once you enter your password at the prompt, if all went well you should now be able to see your LDAP entry. You'll notice that your WUR ID is the sAMAccountName field, which is what we were searching for.

If that's working, then you're allowed to communicate with the AD. At this point you'll want to start writing down passwords in places to be able to use them, so you'll probably want to request a service account for whatever it is you're trying to authenticate to. Send a mail to servicedesk detailing what you're doing, and you should get a specific login you can use.

The reason for this is elementary - by setting up many small service accounts, if something becomes compromised then only the services that are using that login are affected. The more services using one service account, the harder it is to change it without causing unexpected issues. Both from an AD administration and a service administration perspective, this has benefits.

Apache

Apache (2.2+) has a filter associated with it to be able to use an LDAP backend. However, there's a couple of tweaks needed to make it work perfectly in a way that the AD expects. Forst, check that you have the following two modules loaded:

LoadModule ldap_module modules/mod_ldap.so
LoadModule authnz_ldap_module modules/mod_authnz_ldap.so

You may need to install these - check your package manager. Next, you need to configure AuthLDAP to know how to communicate with the LDAP server. Here, we do this in the base directory to ensure it's applied to all sites on this apache instance; of course, pick what's best for you.

<Directory />
   AuthLDAPURL "ldaps://ldap.wurnet.nl:3269/dc=wurnet,dc=nl?userPrincipalName?sub?(objectClass=*)"
   AuthzLDAPAuthoritative on
   AuthBasicProvider ldap
   AuthLDAPBindDN  "CN=your_service_account,DC=wurnet,DC=nl"
   AuthLDAPBindPassword "your_impressively_secure_password"
   AuthLDAPGroupAttribute member
</Directory>

Now, you should be able to add an ldap-filter to BasicAuth to be able to select users from the LDAP:

<Directory "/var/www/my_awesome_site">
    SSLRequireSSL
    AuthType Basic
    Require valid-user
</Directory>

You *must* do this over SSL, otherwise you risk exposing all users passwords across the network. This will allow _all_ valid WUR users to log in.

If you want to filter down to a specific group of users, then you'll need a group in the LDAP. This can also be requested, within good reason, from Servicedesk. There's a reasonable chance that the group you need already exists, though. Either way, to filter for a group of users, use this instead:

<Directory "/var/www/my_awesome_site">
    SSLRequireSSL
    AuthType Basic
    Require ldap-filter memberof:1.2.840.113556.1.4.1941:=CN=mygroup,DC=wurnet,DC=nl
</Directory>


The funky-looking memberof string comes from this document: https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx

Basically, it's a request that allows members of groups in your group to be correctly picked up. Without it, only the direct members of your LDAP group will be allowed, but child groups won't. Further fields can be found on the apache config page: https://httpd.apache.org/docs/2.4/mod/mod_authnz_ldap.html#requser

Winbind

So, you want users from the LDAP to be valid for login, and you want their passwords to be centrally administered? Traditionally, winbind is the way to go about this. Winbind requires several more complex setup steps - firstly, you have to have a valid machine account, and you have to be able to 'join' (update the password on your machine account, and get a Kerberos ticket) the domain using this.

If you're going to do this, you'll need someone with admin rights to help you out getting this set up - this is currently locked down to disallow arbitrary machine joining without permission. If you have a WUR laptop, there's a chance you already have a computer object - you merely need someone to grant you the ability to update and administer this.

Once you're set up, you need several configuration steps. Firstly, install the prerequisite packages:

sudo apt-get install winbind libpam-winbind libnss-winbind samba smbclient krb5-user libpam-krb5 samba-common samba-common-bin

Next, get Kerberos set right in /etc/krb5.conf (might not actually be necessary):

includedir /etc/krb5.conf.d/

includedir /var/lib/sss/pubconf/krb5.include.d/
[logging]
 default = FILE:/var/log/krb5libs.log
 kdc = FILE:/var/log/krb5kdc.log
 admin_server = FILE:/var/log/kadmind.log

[libdefaults]
 dns_lookup_realm = false
 ticket_lifetime = 24h
 renew_lifetime = 7d
 forwardable = true
 rdns = false
 default_ccache_name = KEYRING:persistent:%{uid}

 default_realm = WURNET.NL
 dns_lookup_kdc = true
[realms]
 WURNET.NL = {
  kdc = wurdc1.wurnet.nl
  admin_server = wurdc1.wurnet.nl
  kdc = wurdc2.wurnet.nl
  kdc = wurdc1.wurnet.nl
  kdc = wurdc3.wurnet.nl
 }

[domain_realm]
 wurnet.nl = WURNET.NL
 .wurnet.nl = WURNET.NL 

Next, make sure these lines are in /etc/nsswitch.conf:

passwd:       compat winbind
group:        compat winbind
shadow:       compat

So that the Name Service understands to ask Winbind for users and passwords that don't exist locally. Lastly, configure /etc/samba/smb.conf using the correct setup:

[global]
   workgroup = WUR
   netbios name = <your computer object name>
   server string =  My Linux Server
   realm = WURNET.NL
   security = ADS
   encrypt passwords = Yes
   socket options = TCP_NODELAY IPTOS_LOWDELAY SO_RCVBUF=65536 SO_SNDBUF=65536
   domain master = no
   local master = no 
   preferred master = no
   os level = 65
   dns proxy = No
   wins support  = No
   server signing = auto
   client signing = auto
   idmap config * : backend        = tdb
   idmap config * : range          = 16777216 - 116777216
   idmap config WUR:backend = rid
   idmap config WUR:range = 16777216 - 116777216
   idmap config WUR:base_rid = 0
   idmap config WUR:default = yes
   template shell = /bin/bash
   template homedir = /home/%D/%U
   winbind use default domain = yes
   winbind offline logon = false
   winbind refresh tickets = true
   winbind enum users = no
   winbind enum groups = no
   winbind nested groups = yes
   winbind separator = +
   winbind cache time = 180
   log file = /var/log/samba/%m.log
   syslog = 0
   max log size = 50
   veto files = /.*/
   delete veto files = no
   restrict anonymous = 2

There's a lot of stuff going on here. The smb.conf manual pages ( https://www.samba.org/samba/docs/man/manpages/smb.conf.5.html ) are pretty detailed on most of them. This uses the older compatibility configuration of the id mapping configuration - mapping the AD Relative IDs (rid) onto Unix UIDs starting from 16777216. This configuration provides a uniform user-to-UID mapping across machines, and prevents issues with e.g. NFS, where UIDs are important.

The final steps are:

service winbind start
service samba restart
update-rc.d winbind defaults
update-rc.d samba defaults
net ads join -U <my_id>

Assuming this succeeded, you may see an error message about DNS updates. Don't worry about this - it's a Windows thing that doesn't work fully inside WUR. You can see if your bind has succeeded with:

net ads testjoin

Or:

net ads status -U <my_id>

If you want to know which computer object your machine has joined as.

By this point you should be able to do:

id <my_id>

And see WUR groups popping up in the list. If not, then something's wrong. You should now be able to adjust PAM to be able to request passwords as well, e.g. in etc/pam.d/common-auth:

auth	[success=1 default=ignore]      pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass

(Put this above the pam_deny line)

To filter to a group (you probably want this), try:

auth	[success=1 default=ignore]      pam_winbind.so require_membership_of=my_group krb5_auth krb5_ccache_type=FILE cached_login try_first_pass

You can also filter at the service (e.g. SSH) level, by searching for group membership.

Whilst you're at it, you probably want to create homedirectories automatically when a new user logs in. This is done with this line in common-session, at the end:

session required                        pam_mkhomedir.so umask=0077 skel=/etc/skel

This will create directories based on the contents of /etc/skel . This can be used to great effect to, for instance, build default shell constants for new users.