(sssd-with-ldap-and-kerberos)= # How to set up SSSD with LDAP and Kerberos With SSSD we can create a setup that is very similar to Active Directory in terms of the technologies used: using LDAP for users and groups, and Kerberos for authentication. ## Prerequisites and assumptions For this setup, we will need: - An existing {ref}`OpenLDAP server ` using the RFC2307 schema for users and groups. SSL support is recommended, but not strictly necessary because authentication in this setup is being done via Kerberos, and not LDAP. - A {ref}`Kerberos server `. It doesn't have to be {ref}`using the OpenLDAP backend `. - A client host where we will install and configure SSSD. ## Install necessary software On the client host, install the following packages: ```bash sudo apt install sssd-ldap sssd-krb5 ldap-utils krb5-user ``` You may be asked about the default Kerberos realm. For this guide, we are using `EXAMPLE.COM`. At this point, you should already be able to obtain tickets from your Kerberos server, assuming DNS records point at it: ```bash $ kinit ubuntu Password for ubuntu@EXAMPLE.COM: ubuntu@ldap-krb-client:~$ klist Ticket cache: FILE:/tmp/krb5cc_1000 Default principal: ubuntu@EXAMPLE.COM Valid starting Expires Service principal 04/17/20 19:51:06 04/18/20 05:51:06 krbtgt/EXAMPLE.COM@EXAMPLE.COM renew until 04/18/20 19:51:05 ``` But we want to be able to login as an LDAP user, authenticated via Kerberos. Let's continue with the configuration. ## Configure SSSD Create the `/etc/sssd/sssd.conf` configuration file, with permissions `0600` and ownership `root:root`, and add the following content: ```bash [sssd] config_file_version = 2 domains = example.com [domain/example.com] id_provider = ldap ldap_uri = ldap://ldap01.example.com ldap_search_base = dc=example,dc=com auth_provider = krb5 krb5_server = kdc01.example.com,kdc02.example.com krb5_kpasswd = kdc01.example.com krb5_realm = EXAMPLE.COM cache_credentials = True ``` This example uses two KDCs, which made it necessary to also specify the `krb5_kpasswd` server because the second KDC is a replica and is not running the admin server. Start the `sssd` service: ```bash sudo systemctl start sssd.service ``` ## Automatic home directory creation To enable automatic home directory creation, run the following command: ```bash sudo pam-auth-update --enable mkhomedir ``` ## Final verification In this example, the LDAP server has the following user and group entry we are going to use for testing: ``` dn: uid=john,ou=People,dc=example,dc=com uid: john objectClass: inetOrgPerson objectClass: posixAccount cn: John Smith sn: Smith givenName: John mail: john@example.com uidNumber: 10001 gidNumber: 10001 loginShell: /bin/bash homeDirectory: /home/john dn: cn=john,ou=Group,dc=example,dc=com cn: john objectClass: posixGroup gidNumber: 10001 memberUid: john dn: cn=Engineering,ou=Group,dc=example,dc=com cn: Engineering objectClass: posixGroup gidNumber: 10100 memberUid: john ``` Note how the user `john` has no `userPassword` attribute. The user `john` should be known to the system: ```bash ubuntu@ldap-client:~$ getent passwd john john:*:10001:10001:John Smith:/home/john:/bin/bash ubuntu@ldap-client:~$ id john uid=10001(john) gid=10001(john) groups=10001(john),10100(Engineering) ``` Let's try a login as this user: ```bash ubuntu@ldap-krb-client:~$ sudo login ldap-krb-client login: john Password: Welcome to Ubuntu 20.04 LTS (GNU/Linux 5.4.0-24-generic x86_64) (...) Creating directory '/home/john'. john@ldap-krb-client:~$ klist Ticket cache: FILE:/tmp/krb5cc_10001_BOrxWr Default principal: john@EXAMPLE.COM Valid starting Expires Service principal 04/17/20 20:29:50 04/18/20 06:29:50 krbtgt/EXAMPLE.COM@EXAMPLE.COM renew until 04/18/20 20:29:50 john@ldap-krb-client:~$ ``` We logged in using the Kerberos password, and user/group information from the LDAP server. ## SSSD and KDC spoofing When using SSSD to manage Kerberos logins on a Linux host, there is an attack scenario you should be aware of: KDC spoofing. The objective of the attacker is to login on a workstation that is using Kerberos authentication. Let's say they know `john` is a valid user on that machine. The attacker first deploys a rogue Key Distribution Center (KDC) server in the network, and creates the `john` principal there with a password of the attacker's choosing. What they must do now is have their rogue KDC respond to the login request from the workstation, before (or instead of) the real KDC. If the workstation isn't authenticating the KDC, it will accept the reply from the rogue server and let `john` in. There is a configuration parameter that can be set to protect the workstation from this type of attack. It will have SSSD authenticate the KDC, and block the login if the KDC cannot be verified. This option is called `krb5_validate`, and it's `false` by default. To enable it, edit `/etc/sssd/sssd.conf` and add this line to the domain section: ```text [sssd] config_file_version = 2 domains = example.com [domain/example.com] id_provider = ldap ... krb5_validate = True ``` The second step is to create a `host` principal on the KDC for this workstation. This is how the KDC's authenticity is verified. It's like a "machine account", with a shared secret that the attacker cannot control and replicate in the rogue KDC. The `host` principal has the format `host/@REALM`. After the host principal is created, its keytab needs to be stored on the workstation. This two step process can be easily done on the workstation itself via `kadmin` (not `kadmin.local`) to contact the KDC remotely: ```bash $ sudo kadmin -p ubuntu/admin kadmin: addprinc -randkey host/ldap-krb-client.example.com@EXAMPLE.COM WARNING: no policy specified for host/ldap-krb-client.example.com@EXAMPLE.COM; defaulting to no policy Principal "host/ldap-krb-client.example.com@EXAMPLE.COM" created. kadmin: ktadd -k /etc/krb5.keytab host/ldap-krb-client.example.com Entry for principal host/ldap-krb-client.example.com with kvno 6, encryption type aes256-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab. Entry for principal host/ldap-krb-client.example.com with kvno 6, encryption type aes128-cts-hmac-sha1-96 added to keytab WRFILE:/etc/krb5.keytab. ``` Then exit the tool and make sure the permissions on the keytab file are tight: ```bash sudo chmod 0600 /etc/krb5.keytab sudo chown root:root /etc/krb5.keytab ``` You can also do it on the KDC itself using `kadmin.local`, but you will have to store the keytab temporarily in another file and securely copy it over to the workstation. Once these steps are complete, you can restart SSSD on the workstation and perform the login. If the rogue KDC notices the attempt and replies, it will fail the host verification. With debugging we can see this happening on the workstation: ``` ==> /var/log/sssd/krb5_child.log <== (Mon Apr 20 19:43:58 2020) [[sssd[krb5_child[2102]]]] [validate_tgt] (0x0020): TGT failed verification using key for [host/ldap-krb-client.example.com@EXAMPLE.COM]. (Mon Apr 20 19:43:58 2020) [[sssd[krb5_child[2102]]]] [get_and_save_tgt] (0x0020): 1741: [-1765328377][Server host/ldap-krb-client.example.com@EXAMPLE.COM not found in Kerberos database] ``` And the login is denied. If the real KDC picks it up, however, the host verification succeeds: ``` ==> /var/log/sssd/krb5_child.log <== (Mon Apr 20 19:46:22 2020) [[sssd[krb5_child[2268]]]] [validate_tgt] (0x0400): TGT verified using key for [host/ldap-krb-client.example.com@EXAMPLE.COM]. ``` And the login is accepted.