Difference between revisions of "Using WUR Authentication"
(Created page with "At WUR we have a centrally administered Microsoft Active Directory server that provides authentication details for all internally registered users. Conveniently, it is present...") |
|||
Line 52: | Line 52: | ||
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 | 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, get Kerberos set right in /etc/krb5.conf (might not actually be necessary): | ||
+ | <nowiki>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 </nowiki> | ||
+ | |||
+ | Next, make sure these lines are in /etc/nsswitch.conf: | ||
+ | <nowiki>passwd: compat winbind | ||
+ | group: compat winbind | ||
+ | shadow: compat</nowiki> | ||
+ | |||
+ | 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: | ||
+ | <nowiki>[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</nowiki> | ||
+ | |||
+ | 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: | ||
+ | <nowiki>service winbind start | ||
+ | service samba restart | ||
+ | net ads join -U <my_id></nowiki> | ||
+ | |||
+ | 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: | ||
+ | <nowiki>net ads testjoin</nowiki> | ||
+ | Or: | ||
+ | <nowiki>net ads status -U <my_id></nowiki> | ||
+ | If you want to know which computer object your machine has joined as. | ||
+ | |||
+ | By this point you should be able to do: | ||
+ | <nowiki>id <my_id></nowiki> | ||
+ | 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: | ||
+ | <nowiki>auth [success=1 default=ignore] pam_winbind.so krb5_auth krb5_ccache_type=FILE cached_login try_first_pass</nowiki> | ||
+ | (Put this above the pam_deny line) | ||
+ | |||
+ | To filter to a group (you probably want this), try: | ||
+ | <nowiki>auth [success=1 default=ignore] pam_winbind.so require_membership_of=my_group krb5_auth krb5_ccache_type=FILE cached_login try_first_pass</nowiki> | ||
+ | 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: | ||
+ | <nowiki>session required pam_mkhomedir.so umask=0077 skel=/etc/skel</nowiki> | ||
+ | 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. |
Revision as of 15:32, 1 May 2017
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, 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 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.