Running Kerberos with Zimbra Collaboration Suite: Difference between revisions
No edit summary |
|||
(3 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
{{ | {{BC|Community Sandbox}} | ||
__FORCETOC__ | |||
<div class="col-md-12 ibox-content"> | |||
=Running Kerberos with Zimbra Collaboration= | |||
{{KB|{{Unsupported}}|{{ZCS 6.0}}|{{ZCS 5.0}}|}} | |||
{{Archive}}{{WIP}} | |||
This guide contains instructions for installing, configuring, running, and troubleshooting Kerberos with Zimbra Collaboration Suite. The concepts and descriptions might be not precise, just for general understanding of the mechanisms, steps and usages. For a more detailed reference of Kerberos, consult [http://http://web.mit.edu/kerberos/krb5-1.8/krb5-1.8.3/doc/krb5-admin.html MIT's Kerberos V5 Admin Guide]. | |||
=Introduction= | =Introduction= | ||
Line 158: | Line 164: | ||
===Creating a Local Keytab File for the Principal=== | ===Creating a Local Keytab File for the Principal=== | ||
After adding the principals, you need to generate the corresponding keytab files. This is also done by the command "kadmin.local". If users decide to authenticate with keytab, user keytab is also necessary. Here take IMAP and user1 as the | After adding the principals, you need to generate the corresponding keytab files. This is also done by the command "kadmin.local". If users decide to authenticate with keytab, user keytab is also necessary. Here take IMAP and user1 as the example. NOTE: A keytab file can contain multiple principals. The '''krb5-zcs.keytab''' file should contain the principals for all services that Kerberos support is desired for. I.e., imap, smtp, pop, etc. | ||
$ kadmin.local | $ kadmin.local | ||
Line 283: | Line 289: | ||
See also [http://wiki.zimbra.com/wiki/NGINX_Configuration_Directive_Reference#mail.sasl_host_from_ip NGINX Interface identity with Kerberos] | See also [http://wiki.zimbra.com/wiki/NGINX_Configuration_Directive_Reference#mail.sasl_host_from_ip NGINX Interface identity with Kerberos] | ||
==Configuring ZCS MTA | ==Configuring ZCS MTA: Postfix and Cyrus-SASL== | ||
It is possible to configure the MTA (Postfix) to use Kerberos authentication as well. | It is possible to configure the MTA (Postfix) to use Kerberos authentication as well. |
Latest revision as of 21:06, 12 July 2015
Running Kerberos with Zimbra Collaboration
This guide contains instructions for installing, configuring, running, and troubleshooting Kerberos with Zimbra Collaboration Suite. The concepts and descriptions might be not precise, just for general understanding of the mechanisms, steps and usages. For a more detailed reference of Kerberos, consult MIT's Kerberos V5 Admin Guide.
Introduction
General Knowledge of Kerberos Authentication
You may try to authenticate yourself into some service server via simply username/password login or other similar manner such as PLAIN or CRAM-MD5. In these cases you prove to the service server your identity. The server confirms this and authorize you with the requested services. However, in Kerberos protocol, a trusted third party is introduced, which generates "tickets", which hold credentials to both the user and service server. After gaining the credentials, both the user and service server can prove he is who he claims to be. Then they exchange some messages and finish the mutual authentication. This is the general steps of Kerberos authentication protocol.
In implementation, the trusted third party is the KDC (Kerberos Distribution Center) server. It holds a database (comprised of several regular files) of principals and keys.In the Kerberos world, everyone, including users, services, hosts, etc, has a principle associated with it. Principals should be global unique. Each principal has several components, which can be a username, service name, host name or realm. For example, imap/example.com@EXAMPLE.COM is a valid principal, in which "imap" is the service name, "example.com" is the host name who provides this service, and "EXAMPLE.COM" is the realm. Principal is case sensitive. Traditionally, realm is a capitalized domain name like string. Meanwhile, each principal is associated with a key.
A key is a string generated by the password. You can get a ticket contain a principal by giving that password. Also, you can write the keys into the keytab files and authenticate with them. A keytab file can contain multiple principals' keys with various encryption types. For example, if you have M principals and N encryption types, you may have M*N entries in a keytab file. Therefore you can consider keytab files and password equivalent. However, it's rather noteworthy that if a key is written into keytabfile, the password is no longer effective.
After authenticating to KDC, the corresponding credential is retrieved and cached locally. In MIT Kerberos implementation, it's cached in a regular file called /tmp/krb5cc_<uid>.Other implementations may cache it in the memory. Each credential has an expired time, commonly several hours or 1 day. Before that you can get it from cache without sending request to KDC. Note the UNIX user you used to get and use the credential. If you get it by root (e.g. sudo), and then use it with a normal user with uid 1000, it will fail because the credential you want to use is in krb5cc_0 rather than krb5cc_1000.
KDC reads the configure file "kdc.conf" to setup itself. This config tells which ports to listen, where the database files located, what encryption types should be supported and so on. KDC also reads "krb5.conf" to decide what the default realm is, how to write logs, ... The client and service server are all clients of KDC. They need to read krb5.conf to decide what the default realm is and where KDC is (address and port). Here you can set KDC for each realm. krb5.conf used by Kerberos server and client are often same.So you can config a valid krb5.conf and copy it to everywhere.
Kerberos Executives
Here are the executives of Kerberos implementation.
Name | Description |
---|---|
krb5kdc | KDC server. Default listen on 88, 750 ports |
kadmin.local | Manage principal database by directly manipulate database files. Only work in the machine where those files locate. |
kadmin | Remotely manage principal database, require kadmind. |
kadmind | Kerberos managment server. Default listen on 749 port. |
kdb5_util | Kerberos database maintainance utility. Can create, destroy, load a database. |
kinit | Authenticate to KDC, get the credential. |
klist | Show the entries in the credential cache or keytab files |
There are some other executives for advanced functions, not necessary to introduce here.
Configuration Overview
The picture in the right shows the overview of ZCS with Kerberos authentication support. There are 3 hosts in logic. "kerberos.example.com" holds KDC server, principal database and configs; "client.example.com" holds the client applications which initiates the authentication; "zcs.example.com" runs ZCS servers. Although they are in logic 3 separated hosts, you can choose to install all of them in the same host like what most developers do.In the rest of this article, I'll use these host names to illustrate the examples.
Install Kerberos
MIT Kerberos
Download Kerberos from Massachusetts Institute of Technology (MIT) at http://web.mit.edu/Kerberos/. Install Kerberos, following the instructions provided in MIT's Kerberos V5 Installation Guide. Normally you just run the command "./configure && make && make install". The build process might report some missing dependency such as "bison (yacc)". The Kerberos executive will be generated in /usr/local/bin and /usr/local/sbin. The most important one is /usr/local/sbin/krb5kdc. It's the KDC server.
After that, you need to copy sample krb5.conf and kdc.conf from <krb-source-root>/src/config-files by yourself. Copy krb5.conf to /etc/krb5.conf; then copy kdc.conf to /usr/local/var/krb5kdc/kdc.conf. /usr/local/var/krb5kdc is also the default location of principal database files.
MIT Kerberos Packages from Ubuntu
If using Ubuntu, you can choose to apt-get install the following packages: krb5-admin-server, krb5-kdc, krb5-config, krb5-user, krb5-clients. For Kerberos clients, no need to install admin server and KDC. In this way, the default location of kdc.conf is /etc/krb5kdc; the default location of principal database files is /var/lib/krb5kdc. Meanwhile, the KDC executive name is /etc/init.d/krb5-kdc.
Heimdal
TODO
Other Related Packages
If KDC and Kerberos clients are planed to run in different hosts, it's necessary to install NTP (Network Time Protocol) packages to make time synchronized. Kerberos protocol requires that time synchronization to improve security and convenience. But if all are going to be installed in the same host, no need to do this.
If want to do some test, you can install gsasl (GNU SASL). It contains APIs and sample client/server to use Kerberos authentication.
Configuration
Prepare Valid Host Name
One of the most important thing to configure a valid kerberos environment is to configure the correct host name. This is because ZCS will generate a request for service principal, which contains a component of host name (e.g. imap/zcs.exmaple.com@EXAMPLE.COM). Then KDC will try to find this principal in its local database. Therefore, what the client requests and what is held in KDC database have to be exactly match.
Commonly, Kerberos suggests to use the FQDN (full qualified domain name) to make the principal. However in the reality, ZCS always uses the local config "zimbra_server_hostname" for this purpose. You can see this config by typing (assuming pwd is /opt/zimbra):
$bin/zmlocalconfig | grep zimbra_server_hostname
and change this config by:
$bin/zmlocalconfig -e zimbra_server_hostname=<new host name> $bin/zmlocalconfig -l
where "-l" is to make this change effective for ZCS.
Besides, if ZCS is built from source, this config is coming from the value of environment variable "ZIMBRA_HOSTNAME". If this variable unset, the result of command "hostname" is used. I suggest to set ZIMBRA_HOST to match the principals to be defined.
Another worthy noting is to make hostname's forward and reverse lookup is correct. This is the issue of network administrator if you are using a DNS service. Consult them to define your FQDN and static IP. If you just want to try in your host without bothering others, you can use /etc/hosts file to achieve this. Just add a line like this:
<ip> <FQDN> <hostname>
For example, in the host "zcs.example.com", you need to add this line:
179.16.143.20 zcs.example.com zcs
A common mistake is to add the FQDN to the ip "127.0.0.1" or "127.0.1.1", which might be resolved as hostname "localhost". In this case,the reverse lookup result is different with the forward one, which might incur some confusing error report.
In the following sections, 3 FQDN ("kdc.example.com","client.example.com" and "zcs.example.com") are employed.
Configure Kerberos
For the Kerberos client side, install the /etc/krb5.conf file on any client machines using Kerberos, including all of the Zimbra Mailbox servers. The content of krb5.conf should be like this:
[libdefaults] default_realm = EXAMPLE.COM [realms] EXAMPLE.COM = { kdc = kdc.example.com:88 admin_server = kdc.example.com:749 default_domain = example.com } [domain_realm] example.com = EXAMPLE.COM .example.com = EXAMPLE.COM
The key point of this config is defining the map between realms and KDC servers. The [realms] section indicates where a request for a specified realm (here is EXAMPLE.COM) should be sent to. [domain_realm] illustrates the map between domain names and realm names.default_realm will be appended if no realm is specified. For example, if you request a credential with principal "user1" with kinit command, it will ask for "user1@EXAMPLE.COM".
In the Kerberos server side (where KDC located),"/etc/krb5.conf" is also necessary. For example, if you want to add or get a principal but without specifying the realm, the default_realm will be appended. Meanwhile, I suggest to add the logging section to detect errors.
[logging] kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmin.log default = FILE:/var/log/krb5lib.log
Of course, you can write all of these in one krb5.conf and copy it to any machine you want to deploy kerberos. The kerberos commands will load the necessary config from this file and ignore they don't need.
KDC server also needs "kdc.conf", which looks like this:
[kdcdefaults] kdc_ports = 88,750 [realms] EXAMPLE.COM = { database_name = /usr/local/var/krb5kdc/principal admin_keytab = /usr/local/var/krb5kdc/kadm5.keytab acl_file = /usr/local/var/krb5kdc/kadm5.acl dict_file = /usr/local/var/krb5kdc/kadm5.dict key_stash_file = /usr/local/var/krb5kdc/.k5.EXAMPLE.COM kadmind_port = 749 max_life = 10h 0m 0s max_renewable_life = 7d 0h 0m 0s master_key_type = des3-hmac-sha1 supported_enctypes = des3-hmac-sha1:normal des-cbc-crc:normal }
It controls which ports to be listened and where the local database related files locate. Just make sure these locations are valid. These files are generated by "kdb5_util". Type this command:
$sudo kdb5_util create -s
If not specify a realm, the database files of default realm "EXAMPLE.COM" are generated. A password is required to access these files. "-s" means to generate a stash file to avoid manually input password when start KDC server. It's like the keytab file, the equivalent of password.
Finally, start KDC server:
$sudo /usr/local/sbin/krb5kdc
If nothing is output to the bash, it means KDC starts successfully. Otherwise, check the log of KDC to figure out what's wrong.
Add Principals and Keytabs
Creating Principals
For each ZCS server, create a service principal for the Zimbra services. Here IMAP is the example. This should be in the form of imap/<FQDN>@<realm> where <FQDN> is the value of ZCS local config "zimbra_server_hostname". Meanwhile, create principal for each user.
You can use the command "kadmin.local" to add these principals. This command can only be used in the host where principal database files locate (here, should be "kdc.example.com"). If want to manage the principals in remote hosts, start "kadmind" server and use command kadmin to do it. Here only shows the example of kadmin.local:
$ kadmin.local Authenticating as principal root/admin@EXAMPLE.COM kadmin.local: addprinc -randkey imap/zcs.example.com@EXAMPLE.COM WARNING: no policy specified for imap/zcs.example.com@EXAMPLE.COM; defaulting to no policy Principal "imap/zcs.example.com@EXAMPLE.COM" created. kadmin.local: addprinc user1@EXAMPLE.COM WARNING: no policy specified for user1@EXAMPLE.COM; defaulting to no policy Enter password for principal "user1@EXAMPLE.COM": Re-enter password for principal "user1@EXAMPLE.COM": Principal "user1@EXAMPLE.COM" created.
When type "kadmin.local", the shell enters an interaction mode. Then use the sub command "addprinc" to add a new principal. The parameter "-randkey" allows generating a random key. Without it, you have to type password for the principals added. But as ZCS does the authentication with the keytab file, so the content of key is not important at all. For user principal, here we use the password to generate key.This password should match the one for its ZCS account's password. You can also generate keytab file for user principal. But remember, once keytab files are generated, the password will lose effect.
Besides "addprinc", you can use sub command "listprincs" show the list of existing principals, "getprinc" to get the detailed information of a specified princal, and "delprinc" to delete some of them.
Policy is not important here.It's useful to batch generate principals of the same kind. Just ignore it for now.
Creating a Local Keytab File for the Principal
After adding the principals, you need to generate the corresponding keytab files. This is also done by the command "kadmin.local". If users decide to authenticate with keytab, user keytab is also necessary. Here take IMAP and user1 as the example. NOTE: A keytab file can contain multiple principals. The krb5-zcs.keytab file should contain the principals for all services that Kerberos support is desired for. I.e., imap, smtp, pop, etc.
$ kadmin.local Authenticating as principal root/admin@EXAMPLE.COM with password. kadmin: ktadd -keytab ~/krb5-zcs.keytab imap/zcs.example.com@EXAMPLE.COM Entry for principal imap/zcs.example.com@EXAMPLE.COM with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/home/jxing/krb5-zcs.keytab. Entry for principal imap/zcs.example.com@EXAMPLE.COM with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/home/jxing/krb5-zcs.keytab kadmin: ktadd -keytab ~/krb5-usr.keytab user1@EXAMPLE.COM Entry for principal imap/zcs.example.com@EXAMPLE.COM with kvno 3, encryption type Triple DES cbc mode with HMAC/sha1 added to keytab WRFILE:/home/jxing/krb5-usr.keytab. Entry for principal imap/zcs.example.com@EXAMPLE.COM with kvno 3, encryption type DES cbc mode with CRC-32 added to keytab WRFILE:/home/jxing/krb5-usr.keytab.
Copy the krb5-zcs.keytab to defaultly is "/opt/zimbra/conf/krb5.keytab" in each ZCS server. Keytab files are commonly generated by root (sudo), and has the permission 600. So use "chown" and "chmod" to change it to make sure this file can be read by ZCS. Otherwise, ZCS may report it can't find this file. In the production scenario, this keytab file's owner user and group should be zimbra:zimbra. In the dev environment, it depends on the user who starts ZCS.
Similarly, copy krb5-usr.keytab to "/etc/krb5.keytab" in each host user1 can authenticate himself, and adjust its permission as need. /etc/krb5.keytab is the default location of Kerberos client to find keytab file. If want to specify other location, use the environment variable "KRB5_KTNAME" (By the way, ZCS proxy employs this way to specify the location).
Now you can test this by the two sample utilities, sserver and sclient. In the zcs.example.com, you can start sserver in this way:
$sserver -p 12345 -s imap -S /opt/zimbra/conf/krb5.keytab
In the client.example.com, first get the user1's credential by "kinit" and take authentication to sserver by sclient:
$kinit -k user1 $sclient zcs.example.com 12345 imap sendauth succeeded, reply is: reply len 25, contents: You are user1@EXAMPLE.COM
"kinit -k" means to use keytab file in the default location to authenticate user1. After successful getting user1's credential, it will ask imap service to zcs.example.com:12345 as specified by sclient. If you see something errors reported, check and make sure the steps mentioned above are done correctly.
Additional Notes
The following principals might be necessary:
- imap/zcs.example.com@EXAMPLE.COM
- pop/zcs.example.com@EXAMPLE.COM
- host/zcs.example.com@EXAMPLE.COM
- smtp/zcs.example.com@EXAMPLE.COM
- user1@EXAMPLE.COM
- user2@EXAMPLE.COM
- user3@EXAMPLE.COM
...
Preparing Zimbra for Kerberos Authentication
When you have installed and configured Kerberos, you must prepare a domain for Kerberos5 Authentication and then provision Zimbra accounts. Here I assume this domain is zcs.example.com. If not, please set it with "zmprov cd" command.
Configure ZCS
The authentication mechanism is set in the domain level. So first, set domain authentication mechanism to kerberos5
zmprov md zcs.example.com zimbraAuthMech kerberos5
Then set the default realm to use.
zmprov md zcs.example.com zimbraAuthKerberos5Realm EXAMPLE.COM
Finally, enable Kerberos authentication for IMAP and POP3.
zmprov ms zcs.example.com zimbraImapSaslGssapiEnabled TRUE zmprov ms zcs.example.com zimbraPop3SaslGssapiEnabled TRUE
Provision Zimbra Accounts
When a user attempts to login to Zimbra as user/password, and when the domain's zimbraAuthMech is kerberos5, the system will authenticate to KDC instead of LDAP.
The Kerberos credential for the user is:
- Password. This is the user's password.
- Principal. The Kerberos principal for a user can be resolved by either of the following methods.
Principal Resolution Method 1
One method of resolving a user's Kerberos principal is to enter the user's address in the form of <local part of Zimbra email address>@<zimbraAuthKerberos5Realm>.
For example, for user1@example.com, the Kerberos principal will be user1@EXAMPLE.COM.
Principal Resolution Method 2
Kerberos principal can also be resolved on a per account basis, instead of using the realm defined in zimbraAuthKerberos5Realm. This allows accounts in the same Zimbra domain to be mapped to different Kerberos Realms.
To use this method, set the account's zimbraForiegnPrincipal as kerberos5:<kerberos5-principal>. If the zimbraForeignPrincipal of the account starts with kerberos5:, the system will authenticate to Kerberos using as the principal the text appearing after the kerberos5: in the zimbraForeignPrincipal.
For example:
zmprov ma user1@example.com +zimbraForeignPrincipal kerberos5:user1@EXAMPLE.COM
In the above example, for user1@example.com, the Kerberos principal will be user1@EXAMPLE.COM.
Note: Method 2 will overwrite Method 1. If the account has a zimbraForeignPrincipal in the form of kerberos5:<kerberos5-principal>, the system will resolve the Kerberos principal using Method 2.
Now, you can authenticate to ZCS by Kerberos protocol. You can test by this way (assume ZCS IMAP port is 7143):
$gsasl --connect zcs.example.com:7143 -a user1@zcs.example.com -d
If authentication fails, try to use "kinit" to get the user credential in client.example.com and imap service credential in zcs.example.com.
Configure ZCS Proxy (Nginx)
Architecture
Currently, ZCS employs Nginx (see http://wiki.nginx.org/Main) as the reverse proxy to take load balance and throttle control. Zimbra has extended official Nginx to complement its weak support for mail authentication, including Kerberos5.
The architecture of ZCS including Nginx with Kerberos5 support is shown in the figure on the right . Clients and Nginx take the interaction of Kerberos5 authentication by GSSAPI. Then Nginx can confirm the identity of the client and finally authenticate to ZCS in the protocol called "X-Zimbra". It looks like SASL PLAIN but require Nginx sends authorize user name, authenticate user name and Auth Token to ZCS. The request is the base64 encoded string with form "<authz_username>\0<auth_username>\0<auth_token>. The auth token is a 3 parts string separated by underscore "_". For example,0_5348091d5a42e658b625e3eb369966e6c96c5310_69643d33363a37343764396 363382d326435372d346633662d613162362d3839393434613532616230373b6 578703d31333a313230383239333739383337383b747970653d363a7a696d6272 613b6d61696c686f73743d32303a3139322e3136382e3135392e3132383a373037 303b
This token is given by route lookup servlet when Nginx lookup route for a client trying to log in. Only when auth_method="gssapi", the servlet will return this token.
Configuration Steps
Before setting up Nginx, you should first deploy Route Lookup Servlet and make it work correctly.
The configuration of Nginx is generated by zmproxyconfgen command. In the production environment, you should use zmproxyctl rather than directly generate the configuration. The values of nginx configuration comes from LDAP attrs or local config. Here are the attrs you need to set:
zmprov ms <server_name> zimbraReverseProxyImapSaslGssapiEnabled TRUE # will generate "imap_auth gssapi;" zmprov ms <server_name> zimbraReverseProxyPop3SaslGssapiEnabled TRUE # will generate "pop3_auth gssapi;" zmprov ms <server_name> zimbraReverseProxyDefaultRealm <REALM> # will generate "default_realm <REALM>;" for example, EXAMPLE.COM zmprov mcf +zimbraReverseProxyAdminIPAddress <nginx's host ip>
zimbraReverseProxyAdminIPAddress is very important. Without it, route lookup servlet will consider the requests from the nginx with that IP is invalid and directly return "login failed".
See also NGINX Interface identity with Kerberos
Configuring ZCS MTA: Postfix and Cyrus-SASL
It is possible to configure the MTA (Postfix) to use Kerberos authentication as well.
Configuration steps
Add GSSAPI to the Cyrus-SASL supported mechanisms:
zmlocalconfig -e sasl_smtpd_mech_list="GSSAPI PLAIN LOGIN"
Disable plaintext login for postfix:
zmlocalconfig -e postfix_smtpd_sasl_security_options="noanonymous, noplaintext"
Tell postfix how and where to find the KRB5 Keytab containing the smtp/FQDN principal. If load balancing is used, it should also have an smtp/LBNAME principal as well Note: This keytab must be readable by the postfix group.
zmlocalconfig -e postfix_import_environment="KRB5_KTNAME=/opt/zimbra/conf/krb5.keytab"
If load balancing is being used between MTAs, you need to configure the hostname value presented by the MTAs:
zmprov mcf zimbraMtaMyHostname lbname.example.com
Troubleshooting
If you find some wrong, please check the log of kdc, ZCS and nginx (if nginx is configured for kerberos authentication). These messages are valuable to detect what's the problem.
Encryption Type Unsupported
javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: Failure unspecified at GSS-API level (Mechanism level: AES256 CTS mode with HMAC SHA1- 96 encryption type not in permitted_enctypes list)]
This is because KDC use some strong encryption type that ZCS's java runtime doesn't support (such as AES256). This is related to the export restrictive policy of U.S. And JCE (Java Cryptography Extension) follows this, except you are using JCE Unlimited Strength Jurisdiction Policy Files from Sun Microsystems' Java SE Downloads page, and install JCE on your Zimbra servers. If not, just explicitly specify the supported encryption type in ZCS and client hosts' /etc/krb5.conf, for example :
default_tgs_enctypes = des3-hmac-sha1 default_tkt_enctypes = des3-hmac-sha1 permitted_enctypes = des3-hmac-sha1
If your kerberos is at the latest level, and you have a DES key in your keytab, you will see errors in /var/log/zimbra.log that contain statements like:
"SASL authentication failure: GSSAPI Error: Miscellaneous failure (see text) (encryption type 1 not supported)"
Fix this by adding the following to the libdefaults portion of your krb5.conf file:
allow_weak_crypto = true
No Valid Credential Found
The gsasl might report an error with an amphibolous message:
gsasl: mechanism error: GSSAPI error in client while negotiating security context in gss_init_sec_context() in SASL library. This is most likely due insufficient credentials or malicious interactions.
This error normally happens when you ask for some principal but KDC can't find the one in its database. For example, if you expect "imap/zcs.example.com@EXAMPLE.COM", maybe you really send a request for "imap/localhost@EXAMPLE.COM". This is a typical error if you didn't configure the hostname lookup correctly. Check KDC's log and if you find something like:
TGS_REQ (3 etypes {16 3 1}) 176.16.143.5(88): UNKNOWN_SERVER: authtime 1043800211, user1@EXAMPLE.COM for imap/localhost@EXAMPLE.COM, Server not found in Kerberos database
That's must be the reason for this. Check #Prepare Valid Host Name and fix it.
Another possibility is the credential is not retrieved yet or the one retrieved is expired. Use "klist" to check what status of the credentials cached locally are. If confirm, just use "kinit" command to get the credential first.
No Key Found
javax.security.sasl.SaslException: Failure to initialize security context [Caused by GSSException: No valid credentials provided (Mechanism level: Failed to find any Kerberos Key)]
If using nginx, nginx.log will report:
GSSAPI Error: No credentials were supplied, or the credentials were unavailable or inaccessible. (unknown mech-code 0 for mech unknown)
This error will happen if you didn't write the key into the keytab file, or the permission setting of keytab file reject the read access, or the key file is not the one you should access (for example, you want /opt/zimbra/conf/krb5.conf, but actually read /etc/krb5.conf, which has no that key).