Integrate Dovecot IMAP with (Free)IPA using Kerberos SSO

Dovecot can make use of Kerberos authentication and enjoying Single-Sign-On when checking emails via IMAP. This post shows you how you enable this feature. With IPA its rather simple to do so.

First enroll your mail server to the IPA domain with ipa-client-install as described in various previously posted articles.

Creating a Kerberos Service Priciple

Ensure you have a Kerberos ticket as admin user

ipa1:~# kinit admin
Password for admin@EXAMPLE.COM: 
ipa1:~#
ipa1:~# ipa service-add imap/mail.example.com
---------------------------------------------
Added service "imap/mail.example.com@EXAMPLE.COM"
---------------------------------------------
  Principal name: imap/mail.example.com@EXAMPLE.CCOM
  Principal alias: imap/mail.example.com@EXAMPLE.COM
  Managed by: mail.example.com
ipa1:~# 

Fetch and install the Kerberos Keytab for Dovecot

Log in to your mailserver and get a Kerberos ticket as well:

mail:~# kinit admin
Password for admin@EXAMPLE.COM: 
mail:~#

Fetch the Keytab:

mail:~# ipa-getkeytab -s ipa1.example.com -p imap/mail.example.com -k /etc/dovecot/dovecot-krb5.keytab
Keytab successfully retrieved and stored in: /etc/dovecot/dovecot-krb5.keytab
mail:~# 

A common mistake is to have the wrong ownership and access rights on the keytab file.

mail:~# chown dovecot:dovecot /etc/dovecot/dovecot-krb5.keytab
mail:~# chmod 600 /etc/dovecot/dovecot-krb5.keytab

Edit the following lines in /etc/dovecot/conf.d/10-auth.conf

auth_krb5_keytab = /etc/dovecot/dovecot-krb5.keytab
auth_mechanisms = plain gssapi login
auth_gssapi_hostname = mail.example.com
auth_realms = EXAMPLE.COM
auth_default_realm = EXAMPLE.COM

A note about auth_mechanisms: Usually you dont want to use Kerberos only authentication but plain (over TLS/SSL) as well.

Testing

In /var/log/maillog check if you see messages similar to this:

Feb 19 11:43:25 mail dovecot: imap-login: Login: user=, method=GSSAPI, rip=10.10.10.10, lip=192.168.0.10, mpid=5195, TLS, session=<asdfasdfasdf>

How about LDAP?

Since identity lookup is done with sssd, LDAP integration is not needed in such a case, there is not benefit using LDAP.

Using IPA for user authentication and RBAC in Ansible Tower

Ansible is a great orchestration tool. Ansible Tower is the enterprise version of Ansible adding features like a WebUI, RestAPI and others.

Tower has also some features like role-based access control allowing to control which user is allowed to run which playbooks on which infrastructure, servers and so on.

In larger environments, this is not done manually but using a centrally managed Identity Management System such as Redhat IdM with IPA or Microsoft Active Directory.

This post covers how to set up Ansible Tower to leverage the use of IPA features in a simple way. Its going to use one Organizaion.

License needed

Unfortunately Tower is not yet an open source with an upstream project, this will still take some time, please be patient. Please ensure you got a license for the “standard” or “premium” edition of Ansible Tower since this is a requirement for LDAP integration, please see https://www.ansible.com/tower-editions.

Preparation in IPA

Create a bind user for Ansible

ldapmodify -x -D 'cn=Directory Manager' -W <<EOF
dn: uid=ansible,cn=sysaccounts,cn=etc,dc=example,dc=com
changetype: add
objectclass: account
objectclass: simplesecurityobject
uid: system
userPassword: supersecret
passwordExpirationTime: 20380119031407Z
nsIdleTimeout: 0
EOF

Lets create the group in IPA

ipa2:~# ipa group-add --nonposix ansible
ipa2:~# ipa group-add-member ansible --users=jdoe

The default behavior is that every user in IPA/LDAP can log in to Tower, if not assigned to a Team, the user has no privileges, however, this is not something you want. Therefore the group “ansible” is used to restrict logins to users of that group.

LDAP tree

Non-Kerberized Web application usually query the compat LDAP tree for authentication. However, the compat tree does not expose all the required LDAP attributes (yet) I.e sn or mail are missing. There is a request for enhancement pending, see also https://bugzilla.redhat.com/show_bug.cgi?id=1362272.

We are going to customize the LDAP queries for the “normal” LDAP tree in IPA. Unfortunately this means it only works with with users created in IPA. If you are using a cross domain trust with Microsoft Active directory, the AD users are not able to log in in Ansible Tower. In such a case, set up Ansible Tower to query AD directly.

Configuring Ansible Tower

Edit the file /etc/tower/conf.d/ldap.py and add/edit the following lines to be able to look up users and groups:

AUTH_LDAP_SERVER_URI = 'ldap://ipa2.example.com:389'
AUTH_LDAP_BIND_DN = 'uid=ansible,cn=sysaccounts,cn=etc,dc=example,dc=com'
AUTH_LDAP_BIND_PASSWORD = 'supersecret'
AUTH_LDAP_USER_SEARCH = LDAPSearch(
    'cn=users,cn=accounts,dc=example,dc=com',
    ldap.SCOPE_SUBTREE,
    '(uid=%(user)s)',
AUTH_LDAP_USER_ATTR_MAP = {
    'first_name': 'givenName',
    'last_name': 'sn',
    'email': 'mail',
}
AUTH_LDAP_GROUP_SEARCH = LDAPSearch(
    'cn=groups,cn=accounts,dc=example,dc=com',    # Base DN
    ldap.SCOPE_SUBTREE,
    '(objectClass=group)',
)

If you want to prevent any user to login to Ansible Tower, you can restrict it to one group, in this example a user must be member of the group ansible to be able to log in. This is strongly recommended

AUTH_LDAP_REQUIRE_GROUP = 'cn=ansible,cn=groups,cn=accounts,dc=example,dc=com'

You can also define a ipa group which gets automatically the superuser role assigned.

AUTH_LDAP_USER_FLAGS_BY_GROUP = {
    'is_superuser': 'cn=admins,cn=groups,cn=accounts,dc=example,dc=com',
}

Next will be how to auto assign users to teams, this will be done later in a separate post.

Have fun 🙂

FreeIPA and Selective 2FA with Kerberos Authentication Indicators

One of the major new features in FreeIPA 4.4 is the introduction of Authentication Indicators in Kerberos tickets. This allows you to selectively enforce 2FA.

Usecases

Usually a Linux environment consists on a lot of different services. Some of them are security sensitive such as payroll systems while others are more relaxed such as simple Intranet Webservers.

Some services do not nicely play with 2FA, see https://blog.delouw.ch/2015/04/09/2fa-with-free-ipa-the-good-the-bad-and-the-ugly/. With Authentication Indicators you can allow users accessing this services without 2FA while deploying 2FA on all other services.

One of the obstacles for 2FA is user acceptance. With selective 2FA you can enforce it on the critical servers and/or services only.

Limitations

At the moment, selective 2FA with Authentication Indicators is only working with Fedora 24 and 25. There is no support (yet) for RHEL and its EL clones such as CentOS. Support for Authentication was added in SSSD 1.14, please also see the Release notes for SSSD 1.14.

At the moment, users on RHEL clients always need to provide the second factor. This probably will change for RHEL 7.3. Please also see Bugzilla #1290381. It is already included in public Beta.

Testing the new release

FreeIPA 4.4.2 is available in Fedora 25 Beta. SSSD 1.14 is available on Fedora 24 and newer and in RHEL 7.3 Beta.

Installing FreeIPA 4.4

Get Fedora 25 Beta and install four servers with it. (two replicas, two clients). Fedora 25 Beta can be downloaded here.

[root@ipa1 ~]# dnf -y install freeipa-server freeipa-server-dns

Dependencies will be resolved automatically.

Configure FreeIPA

For tests only, you can disable firewalld to avoid connectivity problems.

[root@ipa2 ~]# systemctl stop firewalld
[root@ipa2 ~]# systemctl disable firewalld

Note: the –allow-zone-overlap is only needed if you make tests with existing DNS domains such as example.com. Usually you should not use this parameter to not violate the highlander principle.

[root@ipa1 ~]# ipa-server-install --subject="O=EXAMPLE.COM 2016101501" --allow-zone-overlap --setup-dns --forwarder=8.8.8.8 --forwarder=8.8.4.4 

Install a replica

The second replica is first set up as a normal IPA Client and will then be promoted to be a replica.

Be sure you point your DNS to the first replica to allow detection of SRV DNS entries to correctly setup the client.

[root@ipa2 ~]# dnf -y install freeipa-server freeipa-server-dns 

Now setup the replica as a client

[root@ipa2 ~]# ipa-client-install

Get a Kerberos Ticket as admin user

[root@ipa2 ~]# kinit admin

Promote to be a replica

[root@ipa2 ~]# ipa-replica-install --setup-dns --setup-ca --forwarder=8.8.8.8 --forwarder=8.8.4.4

Enroll two or more clients

For our tests we need some clients, enroll some

Enable 2FA Authentication

As a default, 2FA is not enabled, lets change that

[root@ipa2 ~]# ipa config-mod --user-auth-type={password,otp}

Add some users

Add one or more users and set a password. Log in and set a new valid password

To be able to authenticate with both, Password only and 2FA, we need to provide that information when creating a new user. You also need to set an initial password.

[root@ipa2 ~]# ipa user-add --user-auth-type={password,otp} --first Joe --last Doe --shell=/bin/bash jdoe
[root@ipa2 ~]# ipa passwd jdoe

Get a Kerberos Ticket for jdoe, you will be promted to set a new password.

[root@ipa2 ~]# kinit jdoe
Password for jdoe@EXAMPLE.COM: 
Password expired.  You must change it now.
Enter new password: 
Enter it again: 
[root@ipa2 ~]# 

Add a 2FA Soft token

You can assign yourself a soft token with the CLI or WebUI.

[root@ipa2 ~]# ipa otptoken-add jdoe
----------------------
Added OTP token "jdoe"
----------------------
  Unique ID: jdoe
  Type: TOTP
  Owner: jdoe
  Manager: jdoe
  Algorithm: sha1
  Digits: 6
  Clock interval: 30
  URI: otpauth://totp/jdoe@EXAMPLE.COM:jdoe?digits=6&secret=NOBAETXGLCVEW7BSINC6II4XLSPTFPDK&period=30&algorithm=SHA1&issuer=jdoe%40EXAMPLE.COM


█████████████████████████████████████████████████████████
█████████████████████████████████████████████████████████
████ ▄▄▄▄▄ ██  ▀▄▄▀▄▄█▄█ ▀█ ▄▀█▀█▀ ▄█▄█▄  ▀▀ █ ▄▄▄▄▄ ████
████ █   █ █  ▄▀▄█▀ ▄▀█▀██▄▄ ▀▀ ▀█▄ ▀   ▀▀█ ▄█ █   █ ████
████ █▄▄▄█ █  ▀▀▀  ▀█▄ ▀█▄ ▄▄▄ ▄▄▀▀▀▄▀▀▀▀ ▀███ █▄▄▄█ ████
████▄▄▄▄▄▄▄█ ▀▄▀ █ █ █ █▄▀ █▄█ ▀ ▀ ▀▄▀▄█▄▀ █ █▄▄▄▄▄▄▄████
████▄▀▄▄ ▄▄██▀▀███▄▄▄▀▄▀██    ▄█▀ ▀ ▄ ▀█ ▀██▄█ ▄▄ ▄██████
████ ▀  ▄▄▄▄ ▀▀█▄▀▄█ ▀▀ ▀▄▄█▄█▀  ▄▀▄ ▄█▄▄█▄█▄ ▀█▀██▄▀████
████▄▀ ▄▀▄▄▄████▄ ██ ▄█▀▀▄ ▄▄██ █ █▄█▄  ▄▄▄█▀▀ ▀▀█▀ █████
████  ▄▀▀█▄▄██▀▄██▀▄▄▀▄▀ ▄ ▄▀█▄ █ ▄███ ▄▀  ▀▄▀▀▄▀ ▀ ▄████
█████▄ █▀▀▄▄▄▄ █  ▀▄█▄▀█ ▄▀█▄▄▀▀ ▀█▄ ▄ ▄█    ▀█▀ ▄▄▄█████
████  ▄   ▄▀▄ █▀█ █▀██  ▄ ▀▄█▀▀▀▄▀ ▄▄▄█▄▀ █▄▀▀  ▀▄█ ▀████
████ ▀▀ ▄▀▄▀▄█▄ ▄  ▀▀ █▀ ▄███▀ ▄ ▄▀█ ▄█▄█▀█ ▄██ ██ ▄▀████
████▀▀   ▄▄▄  ▀ ▀  ██▀  ██ ▄▄▄  █▄█ █▄▄▄▄▀ █ ▄▄▄ ▀█  ████
████▀▀▀▄ █▄█ █▄██▄▄▄ ▀█▀ ▀ █▄█  ▀ ▀ ▄▄█▀█▀▄█ █▄█  ▄▄█████
█████▄█▄▄ ▄  █▀▀█     ▄ ▄▄ ▄ ▄▄▄▄█▀█ ▄▄▄▄███    ▄▄▄▀ ████
████▄███▀█▄ ▀ ▄▄▀▄▀▀ ▄█▄██▄▀▄█▄███▀██▀▄█ ▄▄▄ ██▀█▄▄▄█████
████ ▄▀▄██▄▄▄▄██▄▀▀   ▀▄█▀█▀█▀█▄▄█ ▀█ ▄█ █▀▀▀▄█▀▄ █▄ ████
████▀█▄█▀▄▄█▄▀ ▀ ▀█▄▄▄▀▀█ ▀█▀█▄▄█▄ ▀█▀██ ▄ ▄▀█▀ █ █▄ ████
████▀█▀█▀▄▄▄██ ▀▀██▀ ▀▀▀ ▄▀ ▄█▄▄█▄▄███▀▀ ▀ ▄▀▀▄▀▄▄██▀████
████▀▄██ ▀▄█▀█ ▀   ▀▀█▄▄▀▄ ▄▄▄██ ▄▀ ▀█▄█▄ ▄▄▀▄ ▀▄▄  ▀████
█████ ▀▀█▄▄▀ █  ▄▄█▄█▀ ███▄▄▄▄▄█ ▄ ▄█▄▄▄   ██▄▀▀   ▄▄████
████▄▄▄███▄▄▀█   ███▄▀▀█ ▄ ▄▄▄ ▄█▀  ██ ███▀  ▄▄▄ ▄██ ████
████ ▄▄▄▄▄ █▀█▄▄▄ ▄▀▄██▀▀▀ █▄█ ▀ █▀▄█▄▄ ██▄▀ █▄█ ▀▄█▀████
████ █   █ █ ▄█▀▄  █▄▄▄▀▀  ▄ ▄▄█▄▀▀ █  ▄ ▀▄█     ▄▀ ▀████
████ █▄▄▄█ █▄▀▄▀█▄  █ ▀▀ ▀▄█▀▄█ █▀▄▄██▀ ▄█▄▄ ▀█ █▄ █ ████
████▄▄▄▄▄▄▄█▄▄█▄▄▄▄█▄███▄▄▄▄▄▄██▄██▄▄▄▄▄▄█▄▄▄▄█████▄▄████
█████████████████████████████████████████████████████████
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀


[root@ipa2 ~]# 

You can add this QR code with the FreeOTP or Google Authenticator

Enforcing 2FA on a host principal

To enforce 2FA on a host, alter the host configuration as follows:

[root@ipa2 ~]# ipa host-mod  --auth-ind=otp ipaclient44-fedora24.example.com

You now can try to log in with one and two factors on that host and on some other hosts to see the difference.

Enforcing 2FA on a service

Enforcing of 2FA can also be done on a single (Kerberized) service.

[root@ipa2 ~]# ipa service-mod --auth-ind=otp http/ipaclient.example.com

Further reading

There are plenty of documents available on the internet, here is a choice:

Have fun 🙂

Using (Free)IPA ID-Views with LDAP for your legacy servers

Having pain with user authentication on your old legacy Unix servers? Here comes the solution: ID-Views via LDAP.

If you need to preserve UID/GID or other stuff like shell on some legacy servers but want to have the benefits of a centrally managed identity management, then ID-Views is the answer. Since legacy servers usually do not have SSSD on board, such as traditional Unix Systems, you can also use LDAP to authenticate such users.

Use cases

You have different users with the same login ID but with different UID, GID shell, password etc. you can create User ID overrides and map them to your legacy users.

You can override the Shell. I.e. in AIX the Bash is in /usr/bin/bash and not like in Linux /bin/bash. Or you can set the Shell to /bin/ksh for AIX servers.

Be aware

On the long term you should clean up messy old environments as ID-views adds some complexity to your identity management. As those old kind of servers tend to be replaced with newer Linux distributions, they will die over the next years. At the end, ID-views can greatly help you during a transition period.

Test lab setup

  • Your IPA server is called ipa1.example.com
  • The example client is called ldap-view.example.com
  • The ID-View is called oldstuff
  • Example is named jdoe

What are ID-Views

Basically ID-Views are mappings of user credentials stored in a different LDAP base DN. This is: cn=myview,cn=views,cn=compat,dc=example,dc=com
where myview is replaced by the particular ID-View in this example “oldstuff”.

Underneath there are users and groups, so a complete ID-View DN for users would be cn=users,cn=oldstuff,cn=views,cn=compat,dc=example,dc=com.

Creating an ID-View

Log in to you IPA server and ensure you have a valid Kerberos Ticket for the admin user.

[root@ipa1 ~]# ipa idview-add --desc="Our old Unix Servers" oldstuff
------------------------
Added ID View "oldstuff"
------------------------
  ID View Name: oldstuff
  Description: Our old Unix Servers
[root@ipa1 ~]#

Next lets map a user. Lets assume that user jdoe need to have a login name of joe, a Korn shell, must be in the group with GIG 1002, has the UID of 1001 and has a home directory of /export/home instead of the standard values.

[root@ipa1 ~]# ipa idoverrideuser-add --desc="Overrides for Joe Doe" --shell=/bin/ksh --homedir=/export/home --uid=1001 --gidnumber=1002 oldstuff jdoe
-----------------------------
Added User ID override "jdoe"
-----------------------------
  Anchor to override: jdoe
  Description: Overrides for Joe Doe
  UID: 1001
  GID: 1002
  Home directory: /export/home
  Login shell: /bin/ksh
[root@ipa1 ~]# 

If you want to use this ID-view with SSSD and ipa-client enabled machines, you can assign hosts and host groups to the ID-view. As this article is just taking care of legacy LDAP clients, this is out-of-scope.

Client Configuration

This varies from Linux distribution to another, traditional Unix servers are even more different. If in doubt, please consult your vendors manual.

For some Linux distributions, IPA can give you some hints how to configure your client.

[root@ipa1 ~]# ipa-advise 
----------------------------------------------------------------------
List of available advices
----------------------------------------------------------------------
    config-fedora-authconfig             : Authconfig instructions for
                                           configuring Fedora 18/19 client with
                                           IPA server without use of SSSD.
    config-freebsd-nss-pam-ldapd         : Instructions for configuring a
                                           FreeBSD system with nss-pam-ldapd.
    config-generic-linux-nss-pam-ldapd   : Instructions for configuring a system
                                           with nss-pam-ldapd. This set of
                                           instructions is targeted for linux
                                           systems that do not include the
                                           authconfig utility.

<More output omitted>

Select the systems that match best for your system to configure. In my example I’ll use config-redhat-nss-pam-ldapd

[root@ipa1 ~]# ipa-advise config-redhat-nss-pam-ldapd
#!/bin/sh
# ----------------------------------------------------------------------
# Instructions for configuring a system with nss-pam-ldapd as a IPA
# client. This set of instructions is targeted for platforms that
# include the authconfig utility, which are all Red Hat based platforms.
# ----------------------------------------------------------------------
# Schema Compatibility plugin has not been configured on this server. To
# configure it, run "ipa-adtrust-install --enable-compat"
# Install required packages via yum
yum install -y wget openssl nss-pam-ldapd pam_ldap authconfig

# NOTE: IPA certificate uses the SHA-256 hash function. SHA-256 was
# introduced in RHEL5.2. Therefore, clients older than RHEL5.2 will not
# be able to interoperate with IPA server 3.x.
# Please note that this script assumes /etc/openldap/cacerts as the
# default CA certificate location. If this value is different on your
# system the script needs to be modified accordingly.
# Download the CA certificate of the IPA server
mkdir -p -m 755 /etc/openldap/cacerts
wget http://ipa1.example.com/ipa/config/ca.crt -O /etc/openldap/cacerts/ipa.crt

# Generate hashes for the openldap library
command -v cacertdir_rehash
if [ $? -ne 0 ] ; then
 wget "https://fedorahosted.org/authconfig/browser/cacertdir_rehash?format=txt" -O cacertdir_rehash ;
 chmod 755 ./cacertdir_rehash ;
 ./cacertdir_rehash /etc/openldap/cacerts/ ;
else
 cacertdir_rehash /etc/openldap/cacerts/ ;
fi

# Use the authconfig to configure nsswitch.conf and the PAM stack
authconfig --updateall --enableldap --enableldapauth --ldapserver=ldap://ipa1.example.com --ldapbasedn=cn=compat,dc=example,dc=com

Since this ipa-advice command is normally used for “standard” LDAP authentication, not for ID-Views. So we need to adjust the base DN to match the DN for the ID-View in question. The correct base DN for the example created above is cn=oldstuff,cn=views,cn=compat,dc=example,dc=com.

[root@ldap-view ~]# authconfig --updateall --enableldap --enableldapauth --ldapserver=ldap://ipa1.example.com --ldapbasedn=cn=oldstuff,cn=views,cn=compat,dc=example,dc=com -disablesssd --disablesssdauth
[root@ldap-view ~]# 

Optionally, you can also enable Kerberos:

[root@ldap-view ~]# authconfig --updateall --enableldap --enableldapauth --ldapserver=ldap://ipa1.example.com --ldapbasedn=cn=oldstuff,cn=views,cn=compat,dc=example,dc=com --disablesssd --disablesssdauth --enablekrb5 --enablekrb5kdcdns --enablekrb5realmdns
[root@ldap-view ~]# 

The script configures /etc/openldap/ldap.conf and /etc/nslcd.conf (and optionally /etc/krb5.conf) with the correct LDAP URI and base DN. On other systems, please consult your vendors manual on how to set those parameters.

Check the result

There are basically two methods to look up the user credentials: id and getent.

[root@ldap-view ~]# getent passwd jdoe
jdoe:*:1001:1002:John Doe:/export/home:/bin/ksh
[root@ldap-view ~]# 

Lets switch to that user

[root@ldap-view ~]# su - jdoe
Last login: Mon Nov 16 19:47:04 CET 2015 on pts/0
-ksh-4.2$ id
uid=1001(jdoe) gid=1002 groups=1002 context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
-ksh-4.2$

Pitfalls

UID and GID Ranges

A decade ago it was the fashion that numeric UIDs begin with 500. Modern Linux systems start at 1000 and this is also a restriction in PAM. Check every file in /etc/pam.d/ for uid >= 1000 and uid < 1000. Change them to the value you need for your legacy system.

HBAC (Host Based Access Control)

There is one problematic issue with Non-SSSD authentication: There is no centrally managed HBAC possible. You can achieve this in two ways: LDAP filtering and sshd configuration.

If you are using PAM only fro ssh access, then configuring sshd is less complex. Just add AllowGroups oldstuff
to /etc/ssh/sshd_config and restart the daemon.

However, there is pam_hbac which is currently being developed. PLease have a look at https://github.com/jhrozek/pam_hbac for more information.

Have fun? No, definitively not with old stuff dinosaur style computing. But at least its less painful 😉