Postfix Kerberos Authentication with Active Directory

This post is meant to be my build doc for configuring the Postfix smtpd to authenticate smtp clients using Cyrus SASL with the Kerberos (GSSAPI) mechanism against Active Directory on a CentOS 6 installation using packages from the distribution. I’m not an expert on this subject. This is from my experience using a lot of reading, trial, and error to get the necessary parts working together.

These are some of relevant steps I took to get there:

  1. Minimal CentOS 6 install
  2. yum –y update
  3. Restart
  4. yum -y install cyrus-sasl-gssapi cyrus-sasl-ntlm pam_krb5 net-snmp ntp openssh-clients vim-enhanced man bind-utils samba krb5-workstation sssd cyrus-sasl-plain cyrus-sasl-ldap wget gcc gcc-c++ krb5-devel openldap-clients cyrus-sasl-devel
  5. Configure ntpd for getting time from internal ntp service
  6. restart
  7. edit /etc/krb5.conf

default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log

default_realm =
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
renew_lifetime = 7d
forwardable = true

[domain_realm] = EXAMPLE.COM = EXAMPLE.COM

8. Edit postfix settings

postconf -e inet_interfaces=all inet_protocols=ipv4 broken_sasl_auth_client=yes line_length_limit=6144 smtpd_recipient_restrictions=permit_sasl_authenticated,reject_unauth_destination smtpd_sasl_auth_enable=yes import_environment=

a. postconf –n contains after (plus the OoB non-defaults)

inet_interfaces = all
inet_protocols = ipv4
line_length_limit = 6144
myhostname =
smtpd_recipient_restrictions = permit_sasl_authenticated,reject_unauth_destination
smtpd_sasl_auth_enable = yes

9. Restart postfix service

10. /etc/sasl2/smtpd.conf

a. Used by Postfix to configure its use of sasl

pwcheck_method: saslauthd
mech_list: gssapi plain login
log_level: 7

11. /etc/sysconfig/saslauthd

# Directory in which to place saslauthd’s listening socket, pid file, and so
# on. This directory must already exist.

# Mechanism to use when checking passwords. Run “saslauthd -v” to get a list
# of which mechanism your installation was compiled with the ablity to use.

# Options sent to the saslauthd. If the MECH is other than “pam” uncomment the next line.
# DAEMONOPTS=–user saslauth

# Additional flags to pass to saslauthd on the command line. See saslauthd(8)
# for the list of accepted flags.

12. Create a user account with the name matching the local part of the hostname from $myhostname (srvsbsmtp05 in this case). Set the password to not expire and not be changeable by the user.

13. From a domain controller run the following on the cmd line:


b. The @REALM part is case sensitive. It must be in caps to match what’s in the krb5.conf file on the Linux box or it won’t work.


d. This is all one line

e. Protect this file like you would any private key file. If stolen it’s effectively like a user’s password was stolen, and in this case, it a user running a service that could be impersonated.

C:\>ktpass /princ smtp/ /mapuser srvsbsmtp05 /pass mpi4Ever /out srvsbsmtp05.smtp.keytab /crypto all /ptype KRB5_NT_PRINCIPAL /mapop set

14. Copy the keytab file to the Linux box

15. Add the keytab data to a keytab file on the Linux box.

# ktutil
ktutil: rkt srvsbsmtp05.smtp.keytab
ktutil: wkt /etc/postfix/krb5.keytab
ktutil: q

16. The user running either one of the Postfix services, or the saslauthd service, (not sure which without testing things) need to be able to read the keytab file. I set the permissions to 644 for the keytab file. Without this service user being able to read the keytab file, it won’t work.  There’s probably a more secure way to do this.

17. Turn on saslauthd and start the service

# chkconfig saslauthd on; service saslauthd start

18. Add a SPN for the service account using the URL the SMTP service is being accessed. This shouldn’t be necessary if accessing the SMTP service with as the server name instead of

C:\>setspn -A smtp/ EXAMPLE\srvsbsmtp05
Registering ServicePrincipalNames for CN=srvsbsmtp05,OU=Dev,OU=Servers,OU=LasVegas,OU=_Corporate,DC=example,DC=com
Updated object

19. Test to see that Kerberos authentication for smtp from Thunderbird is working now.

Troubleshooting and information

I’ve learned that it’s important to compartmentalize and verify that each link in the chain works correctly along the way. Your Kerberos settings need to be correct. Postfix needs to be configured to use cyrus sasl and other smtpd settings need to be correct. Saslauthd needs to be set and working for Kerberos use. You need the correct principles set in Active Directory. As with every other interdependent system, if one piece isn’t working correctly, you’re not likely to get the result you’re after.

You need to have some understanding of Kerberos to dissect things when they don’t work. Wireshark is the best way to watch what’s happening with ticket requests. Klist and kinit are two commands you’ll need to understand how to use some.

The Postfix configuration part of this is pretty simple. For the most part, you turn on sasl authentication and that’s it. Once you have plain text sasl authentication working with Postfix, which is pretty easy, getting the GSSAPI mechanism working is all about the Cyrus sasl configuration (and making sure Postfix can access the keytab file).

Does plain text authentication work with saslauthd?  Test it with testsaslauthd. If it doesn’t work here, it won’t work with Postfix.

$ testsaslauthd -u myusername -p mypassword -r MYDOMAIN.COM -s smtp
0: OK “Success.”

Run saslauthd in your console window so you can watch what it’s doing:

# saslauthd -m /var/run/saslauthd -a kerberos5 -d
saslauthd[1790] :main : num_procs : 5
saslauthd[1790] :main : mech_option: NULL
saslauthd[1790] :main : run_path : /var/run/saslauthd
saslauthd[1790] :main : auth_mech : kerberos5
saslauthd[1790] :ipc_init : using accept lock file: /var/run/saslauthd/mux.accept
saslauthd[1790] :detach_tty : master pid is: 0
saslauthd[1790] :ipc_init : listening on socket: /var/run/saslauthd/mux
saslauthd[1790] :main : using process model
saslauthd[1790] :have_baby : forked child: 1791
saslauthd[1790] :have_baby : forked child: 1792
saslauthd[1791] :get_accept_lock : acquired accept lock
saslauthd[1790] :have_baby : forked child: 1793
saslauthd[1790] :have_baby : forked child: 1794
saslauthd[1791] :rel_accept_lock : released accept lock
saslauthd[1793] :get_accept_lock : acquired accept lock
saslauthd[1791] :do_auth : auth success: [user=myusername] [service=smtp] [realm=MYDOMAIN.COM] [mech=kerberos5]
saslauthd[1791] :do_request : response: OK

Sasl2-sample-server and sasl2-sample-client tools from the cyrus-sasl-devel package:

These are handy tools to see if you have Kerberos and saslauthd configured correctly.
You’d need to add the keytab file mentioned above to the /etc/krb5.keytab file for the system for this to work (unless there’s a way to specify the keytab file for the sample server).

# klist -ke /etc/postfix/krb5.keytab
Keytab name: FILE:/etc/postfix/krb5.keytab
KVNO Principal
—- ————————————————————————–
3 smtp/ (des-cbc-crc)
3 smtp/ (des-cbc-md5)
3 smtp/ (arcfour-hmac)
3 smtp/ (aes256-cts-hmac-sha1-96)
3 smtp/ (aes128-cts-hmac-sha1-96)

$ kinit myusername@EXAMPLE.COM
Password for myusername@EXAMPLE.COM:
$ klist
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: myusername@EXAMPLE.COM

Valid starting Expires Service principal
06/14/13 14:04:50 06/15/13 00:04:54 krbtgt/EXAMPLE.COM@EXAMPLE.COM
renew until 06/21/13 14:04:50

/// sasl2-sample-server output ///
/// in a separate terminal session ///

$ sudo sasl2-sample-server -s smtp -m GSSAPI
trying 2, 1, 6
trying 10, 1, 6
bind: Address already in use
accepted new connection
send: {6}
recv: {6}
recv: {1}
recv: {3306}
`[82][C][E6] [… snip …] c)[18][97]
send: {152}
`[81][95][6][… snip …][0]&[AC][A1]
recv: {0}

send: {32}
[5][4][5][… snip …][13][CA]’v
recv: {39}
[5][4][4][… snip …]Q[DB][AA]
successful authentication ‘myusername’
closing connection

/// from the same terminal session you ran kinit from ///

$ sasl2-sample-client -s smtp -m GSSAPI
receiving capability list… recv: {6}
please enter an authorization id: myusername
send: {6}
send: {1}
send: {3306}
`[82][C][E6] [… snip …] &[AC][A1]
send: {0}

recv: {32}
[5][4][5][… snip …][13][CA]’v
send: {39}
[5][4][4][… snip …][DB][AA]
successful authentication
closing connection

Postfinger and saslfinger are great tools for summarizing configuration data to look for problems.