Kerberos ======== Presentation ------------ This documentation will explain how to use Active Directory as Kerberos server, and provide transparent authentication for one or multiple AD domains. You can use Kerberos in LL::NG with the following authentication modules: - :doc:`Kerberos` (recommended): use Perl GSSAPI module, compatible with Apache and Nginx - :doc:`Apache`: use mod_auth_kerb or mod_auth_gssapi in Apache Prerequisites ------------- Example values ~~~~~~~~~~~~~~ We will use the following values in our examples - **EXAMPLE.COM**: First AD domain - **ACME.COM**: Second AD domain - **auth.example.com**: DNS of the LL::NG portal - **KERB_AUTH**: AD account to generate the keytab for LL::NG server Server time ~~~~~~~~~~~ It is mandatory that LL::NG servers and AD servers have the same time. It is recommended to use NTP to do this. DNS ~~~ In our experience, we have observed the following limitations when using Kerberos for web applications in an Active Directory environment * ``auth.example.com`` must be registered in the DNS server as a ``A`` record. ``CNAME`` usually do not work * The reverse DNS (``PTR``) for ``auth.example.com``'s IP address MUST point back to ``auth.example.com`` .. tip:: If you have a SSO cluster, you must setup a Virtual IP in cluster and register this IP in DNS. .. tip:: If you cannot configure the PTR record to point to the portal's hostname, it may help to run the following command. Assuming that ``proxy.example.com`` is the PTR record of the portal's IP address :: setspn -s HTTP/proxy.example.com keytab-account SSL ~~~ SSL is not mandatory, but it is strongly recommended. Your portal URL should be https://auth.example.com. Web server configuration ~~~~~~~~~~~~~~~~~~~~~~~~ Apache ^^^^^^ Some Kerberos tickets, especially generated by Active Directory, can get too big for Apache's default header size limit Increase it in the global `httpd.conf` configuration :: LimitRequestFieldSize 16384 Nginx ^^^^^ Some Kerberos tickets, especially generated by Active Directory, can get too big for Apache's default header size limit Increase it in your `portal-nginx.conf` configuration :: large_client_header_buffers 4 16k; Web browser configuration ~~~~~~~~~~~~~~~~~~~~~~~~~ Firefox ^^^^^^^ Type ``about:config`` in a tab and search for ``trusted``. Then edit the property ``network.negotiate-auth.trusted-uris`` and set value ``example.com``. Internet Explorer / Edge / Chrome ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Add ``https://auth.example.com`` as trusted site. Check into security parameters that Kerberos authentication is allowed. Single AD domain ---------------- Client Kerberos configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ On LL::NG server, edit ``/etc/krb5.conf``: .. code-block:: ini [libdefaults] default_realm = EXAMPLE.COM dns_lookup_kdc = false dns_lookup_realm = no ticket_lifetime = 24h forwardable = yes renewable = true [realms] EXAMPLE.COM = { kdc = ad.example.com admin_server = ad.example.com } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM You can check that Kerberos is working by trying to get a ticket for a user of the domain (for example coudot): :: kinit coudot@EXAMPLE.COM You should be prompted to enter password. Then list the tickets: :: klist -e You should see a krbtgt ticket: :: Valid starting Expires Service principal 06/04/15 15:43:24 06/05/15 01:43:29 krbtgt/EXAMPLE.COM@EXAMPLE.COM renew until 06/05/15 15:43:24, Etype (skey, tkt): aes256-cts-hmac-sha1-96, aes256-cts-hmac-sha1-96 You can then close the Kerberos session: :: kdestroy Obtain keytab file ~~~~~~~~~~~~~~~~~~ You have to run this command on Active Directory: :: ktpass -princ HTTP/auth.example.com@EXAMPLE.COM -mapuser KERB_AUTH@EXAMPLE.COM -crypto All -ptype KRB5_NT_PRINCIPAL -mapOp set -pass -out c:\auth.keytab .. attention:: You must use the UPPERCASE value of the domain name when generating the keytab .. attention:: The values passed in -crypto and -ptype depend on the Active Directory version and the windows version of the workstations. You can for example use RC4-HMAC-NT as crypto protocol if DES is not supported by workstations (this the case by default for Window 8 for example). The file ``auth.keytab`` should then be copied (with a secure media) to the Linux server (for example in ``/etc/lemonldap-ng``). Change rights on keytab file: :: chown apache /etc/lemonldap-ng/auth.keytab chmod 600 /etc/lemonldap-ng/auth.keytab # If you use SELinux restorecon /etc/lemonldap-ng/auth.keytab You can check the validity of the keytab file by trying to request a service ticket, and compare the result with the keytab content. Open a Kerberos session (like done in the previous step): :: kinit coudot@example.com Request a service ticket: :: kvno HTTP/auth.example.com@EXAMPLE.COM The result of the command should be: :: HTTP/auth.example.com@EXAMPLE.COM: kvno = 3 Read the service ticket: :: klist -e You should see this kind of ticket: :: 06/04/15 16:28:49 06/05/15 02:28:11 HTTP/auth.example.com@EXAMPLE.COM renew until 06/05/15 16:28:07, Etype (skey, tkt): arcfour-hmac, arcfour-hmac You can close the Kerberos session: :: kdestroy Now you can compare the above result with the same request done through the keytab file: :: klist -e -k -t /etc/lemonldap-ng/auth.keytab The result of the command should be: :: Keytab name: FILE:/etc/lemonldap-ng/auth.keytab KVNO Timestamp Principal ---- ----------------- -------------------------------------------------------- 3 01/01/70 01:00:00 HTTP/auth.example.com@EXAMPLE.COM (arcfour-hmac) The important things to check are: - KVNO must be the same - Principal names must be the same - Encryption types must be the same Multiple AD domains ------------------- .. _client-kerberos-configuration-1: Client Kerberos configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The two domains must be defined in ``/etc/krb5.conf``: .. code-block:: ini [libdefaults] default_realm = EXAMPLE.COM dns_lookup_kdc = false dns_lookup_realm = no ticket_lifetime = 24h forwardable = yes renewable = true [realms] EXAMPLE.COM = { kdc = ad.example.com admin_server = ad.example.com default_domain = EXAMPLE.COM } ACME.COM = { kdc = ad.acme.com admin_server = ad.acme.com } [domain_realm] .example.com = EXAMPLE.COM example.com = EXAMPLE.COM .acme.com = ACME.COM acme.com = ACME.COM You should then be able to open a Kerberos session on each domain: :: kinit coudot@EXAMPLE.COM klist -e kdestroy :: kinit coudot@ACME.COM klist -e kdestroy .. _obtain-keytab-file-1: Obtain keytab file ~~~~~~~~~~~~~~~~~~ You need to obtain a keytab for each node on each domain. This means the ktpass commands should be run on both AD. Then you will have 2 keytab files for each node, for example: - node1-example.keytab - node1-acme.keytab You need to concatenate the keytab files, thanks to ``ktutil`` command: :: ktutil ktutil: read_kt node1-example.keytab ktutil: read_kt node1-acme.keytab ktutil: write_kt /etc/lemonldap-ng/auth.keytab ktutil: quit You can then remove the original keytab files and protect the final keytab file: :: chown apache /etc/lemonldap-ng/auth.keytab chmod 600 /etc/lemonldap-ng/auth.keytab Other resources --------------- You can check these documentations to get more information: - http://modauthkerb.sourceforge.net/configure.html - http://www.grolmsnet.de/kerbtut/