powered by Jive Software

Openfire on Ubuntu with SSO against AD

How do I enable Openfire to log my users in via Single Sign-On (SSO) and Username/Password?

I’m running Openfire 4.1.1 on Ubuntu 16.04

with Java Version 1.8.0_121 Oracle Corporation – Java HotSpot™ 64-Bit Server VM

Using Server 2012R2 Active Directory for SSO

Funny enough, I’ve done this once before and I don’t remember it being so damn hard…

I’ve referenced all the following articles:






I have basically followed this procedure (I say basically because I have started from scratch and troubleshooted this problem so much I’m not sure exactly what I did when)

AD Domain => i.domain.name

NetBIOS Name => i

IM Domain => im.domain.name

Kerberos Realm => I.DOMAIN.NAME

Kerberos KDC => I.DOMAIN.NAME (I think)

Domain Controller FQDN => dc1.i.domain.name

Openfire FQDN => server-im.i.domain.name (with CNAMEs im and openfire)

(also all DNS records in i.domain.name also have CNAMEs in domain.name)

Openfire Keytab file => /etc/openfire/security/openfire.keytab

GSS Principle => xmpp/xmpp-openfire@I.DOMAIN.NAME

Create a Domain account and ready Active Directory

I created a user: xmpp-openfire with a password PASSWORD

I then made sure that:

User cannot change password is checked

Password never expires is checked

Do not require Kerberos preauthentication is checked

User is a Domain Admin (overkill I think)

User is a Openfire Admin (also overkill)

I then created a load of Service Principal Names (SPN) for each and every possible domain name of the openfire server: (again probably overkill, but…) (might be the problem!!!)

setspn -A xmpp/im.i.domain.name@i.domain.name xmpp-openfire
setspn -A xmpp/openfire.i.domain.name@i.domain.name xmpp-openfire
setspn -A xmpp/server-im .i.domain.name@i.domain.name xmpp-openfire
setspn -A xmpp/im.i.domain.name xmpp-openfire
setspn -A xmpp/openfire.i.domain.name xmpp-openfire
setspn -A xmpp/server-im.i.domain.name xmpp-openfire
setspn -A xmpp/im.domain.name@i.domain.name xmpp-openfire
setspn -A xmpp/openfire.domain.name@i.domain.name xmpp-openfire
setspn -A xmpp/server-im.domain.name@i.domain.name xmpp-openfire
setspn -A xmpp/im.domain.name xmpp-openfire
setspn -A xmpp/openfire.domain.name xmpp-openfire
setspn -A xmpp/server-im.domain.name xmpp-openfire
setspn -A xmpp/xmpp-openfire@I.DOMAIN.NAME xmpp-openfire

I then mapped every SPN I created above to the account I created earlier:

ktpass -princ xmpp/im.i.domain.name@i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/openfire.i.domain.name@i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/server-im.i.domain.name@i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/im.i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/openfire.i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/server-im.i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/im.domain.name@i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/openfire.domain.name@i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/server-im.domain.name@i.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/im.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/openfire.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/server-im.domain.name -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL
ktpass -princ xmpp/xmpp-openfire@I.DOMAIN.NAME -mapuser xmpp-openfire@i.domain.name -SetPass -pass PASSWORD -ptype KRB5_NT_PRINCIPAL

I then verified this all worked (so far) with the command:

C:\Users\username>setspn -L xmpp-openfire
Registered ServicePrincipalNames for CN=xmpp-openfire,CN=Users,DC=i,DC=domain,DC=name:

Configure the Ubuntu server for Kerberos and Samba

Create a keytab file to be used with openfire

On Openfire server, create the keytab file:

ktutil <<EOF
rkt /etc/openfire/security/openfire.keytab
addent -password -p xmpp-openfire@I.DOMAIN.NAME -k 1 -e RC4-HMAC
wkt /etc/openfire/security/openfire.keytab
chown openfire:openfire /etc/openfire/security/openfire.keytab

Verify that the above was added properly:

root@server-im:~# klist -k /etc/openfire/security/openfire.keytab Keytab name: FILE:/etc/openfire/security/openfire.keytab KVNO Principal ---- --------------------------------------------------------------------------    1 xmpp-openfire@I.DOMAIN.NAME

Modify /etc/krb5.conf file:

root@server-im:~# echo """
default = FILE:/var/log/krb5libs.log
kdc = FILE:/var/log/krb5kdc.log
admin_server = FILE:/var/log/kadmind.log [libdefaults]
default_realm = I.DOMAIN.NAME
dns_lookup_realm = true
dns_lookup_kdc = true
ticket_lifetime = 24h
forwardable = yes
kdc_timesync = 1
ccache_type = 4
proxiable = true
default_tkt_enctypes = rc4-hmac des3-cbc-sha1 des-cbc-crc des-cbc-md5
default_tgs_enctypes = rc4-hmac des3-cbc-sha1 des-cbc-crc des-cbc-md5
permitted_enctypes = rc4-hmac des3-cbc-sha1 des-cbc-crc des-cbc-md5 v4_instance_resolve = false
v4_name_convert = {
host = {
rcmd = host
ftp = ftp
plain = {
something = something-else
fcc-mit-ticketflags = true [appdefaults]
pam = {
debug = false
ticket_lifetime = 36000
renew_lifetime = 36000
forwardable = true
krb4_convert = false
} [realms]
kdc = dc1.i.domain.name:88
admin_server = i.domain.name
default_domain = i.domain.name
} [domain_realm]
.i.domain.name = I.DOMAIN.NAME
i.domain.name = I.DOMAIN.NAME
.domain.name = I.DOMAIN.NAME
domain.name = I.DOMAIN.NAME [login]
krb4_convert = true
krb4_get_tickets = false
""" > /etc/krb5.conf

Verify that the server can log in via kerberos using the keytab file:

root@server-im:~# kinit -kt /etc/openfire/security/openfire.keytab xmpp-openfire@I.DOMAIN.NAME -V Using default cache: /tmp/krb5cc_0 Using principal: xmpp-openfire@I.DOMAIN.NAME
Using keytab: /etc/openfire/security/openfire.keytab Authenticated to Kerberos v5 root@server-im:~# klist Ticket cache: FILE:/tmp/krb5cc_0 Default principal: xmpp-openfire@I.DOMAIN.NAME
  Valid starting     Expires            Service principal 30/03/17 12:33:54  30/03/17 22:33:54  krbtgt/I.DOMAIN.NAME@I.DOMAIN.NAME
    renew until 30/03/17 22:33:54

Modify /etc/samba/smb.conf file:

echo """
workgroup = i
preferred master = no
server string = Openfire Instant Messaging Server
security = ADS
encrypt passwords = yes
log level = 3
log file = /var/log/samba/%m
max log size = 50
printcap name = cups
printing = cups
#winbind enum users = Yes
#winbind enum groups = Yes
#winbind use default domain = Yes
#winbind nested groups = Yes
#winbind separator = +
#idmap uid = 600-20000
#idmap gid = 600-20000
template shell = /bin/bash
dns proxy = no
max log size = 10000
""" > /etc/samba/smb.conf

Setup Samba and join the Domain:

service smbd stop
service nmbd stop
service winbind stop
net ads join -U administrator
service smbd start
service nmbd start
service winbind start

Verify that Samba is working properly:

wbinfo -u
wbinfo -g
net ads info
net ads user
net ads group

Configure the Openfire server for Kerberos and GSSAPI

Modify the Openfire GSS config file

echo """com.sun.security.jgss.accept {
};""" > /etc/openfire/gss.conf chown openfire:openfire /etc/openfire/gss.conf

Within Openfire Admin Console, modify the following System Properties:

sasl.gssapi.config /etc/openfire/gss.conf

sasl.gssapi.debug true

sasl.gssapi.useSubjectCredsOnly false


sasl.realm I.DOMAIN.NAME

Modify /etc/openfire/openfire.xml within add: (maybe provider.auth.className)

<authorization>       <classList>org.jivesoftware.openfire.sasl.LooseAuthorizationPolicy org.jivesoftware.openfire.sasl.DefaultAuthorizationProvider</classList>        <!-- other options: null, LdapAuthorizationProvider, UnixK5LoginProvider, Strict and Lazy-->     </authorization>

Kerberos will not work unless the client is within 5 minutes of the server. This also means the Time Zones must be correct as well!

echo “Europe/Dublin” > /etc/timezone

And within Openfire Admin Console, modify the following System Property:

locale.timeZone Europe/Dublin

It is VERY important to get the right Time Zone and it might not be straight-forward as Microsoft uses COMPLETELY different names!

Configure DNS Service Records (SRV)

Setup the following DNS Records

_xmpp-server.tcp.i.domain.name. IN SRV 0 0 5269 server-im.i.domain.name.

_xmpp-client.tcp.i.domain.name. IN SRV 0 0 5222 server-im.i.domain.name.

_jabber.tcp.i.domain.name. IN SRV 0 0 5222 server-im.i.domain.name.

_jabber-client.tcp.i.domain.name. IN SRV 0 0 5222 server-im.i.domain.name.

_xmpp-server.tcp.domain.name. IN SRV 0 0 5269 server-im.i.domain.name.

_xmpp-client.tcp.domain.name. IN SRV 0 0 5222 server-im.i.domain.name.

_jabber.tcp.domain.name. IN SRV 0 0 5222 server-im.i.domain.name.

_jabber-client.tcp.domain.name. IN SRV 0 0 5222 server-im.i.domain.name.

From what I’m read and seen, this should be working!!! But it is not!!!

I’ve tried every variation I can think of and NOTHING!!!

Please help!


So I wrote the above in a bit of a hurry (I wanted to get it up before end of work Friday)

After I make the above changes to the system properties in Openfire, I’m unable to login via SSO or Username/Password on either Windows or an Ubuntu workstation… But once I remove the “sasl.gssapi.config” I’m able to login using username/password again.


I think i would start over! Give the following a read and let me know if you have any questions



@speedy, thanks for those articles! They did help me find a few errors in my procedure:

  • SPNs are case sensitive.
  • I put an errant Carriage Return in my gss.conf

However it is still not working. I noticed that these instructions (like nearly all I’ve seen) are tailored for an Openfire installation on a Windows Box, I’m using Ubuntu.

Right away what I’ve found is that the SPN I use MUST be the same as the username in AD. When I try to use a SPN, like the hostname of the server or the IM Domain name, I get the following error:

root@im:~# kinit -kt /etc/openfire/security/openfire.keytab im.domain.name@I.DOMAIN.NAME -V

Using default cache: /tmp/krb5cc_0

Using principal: im.domain.name@I.DOMAIN.NAME

Using keytab: /etc/openfire/security/openfire.keytab

kinit: Keytab contains no suitable keys for im.domain.name@I.DOMAIN.NAME while getting initial credentials

Where is I use the username I get: (this works with the both keytab files I create and the keytab file from ktpass)

root@im:~# kinit -kt /etc/openfire/security/openfire.keytab xmpp/xmpp-openfire@I.DOMAIN.NAME -V

Using default cache: /tmp/krb5cc_0

Using principal: xmpp/xmpp-openfire@I.DOMAIN.NAME

Using keytab: /etc/openfire/security/openfire.keytab

Authenticated to Kerberos v5

root@im:~# klist

Ticket cache: FILE:/tmp/krb5cc_0

Default principal: xmpp/xmpp-openfire@I.DOMAIN.NAME

Valid starting Expires Service principal

05/04/17 13:36:59 05/04/17 23:36:59 krbtgt/I.DOMAIN.NAME@I.DOMAIN.NAME

renew until 05/04/17 23:36:59

I have also found that after fixing the GSS.CONF file is that I can still login via username/password, but SSO is still not working…

I have also found that my linux Spark 2.7.3 needed to be upgraded to version 2.8.2.

I can’t seem to find any log files to figure out exactly WHY the SSO isn’t working.



from your first post, it looks like your xmpp domain is im.domain.name. and your have a SRV record pointing to server-im.i.domain.name, Is this correct? if so, then try this.

create a system property call xmpp.fqdn with the property value of server-im.i.domain.name

then check your gss.conf. make the principle value xmpp/server-im.i.domain.name

final, make sure your you have the SPN has xmpp/server-im.i.domain.name and that is the one that shows in AD in the user logon field of your keytab user account. if not, do something like setspn -S xmpp/server-im.i.domain.name keytab

You are speedy! Thanks for the quick reply…

I was thinking along the same lines. I also noticed that the klist command shows a service principle of krbtgt/I.DOMAIN.NAME@I.DOMAIN.NAME

Things are complicated by two things

  1. So the setup is like this. I want this server placed in the DMZ with potential access to other jabber servers. I therefore used the IM Domain of im.domain.name

However internally our Microsoft AD is i.domain.name

So the the server fqdn is server-im.i.domain.name

But I’m got internal DNS records that respond to domain.name as well as i.domain.name. Basically all the records in one domain have CNAMEs in the other.

  1. This server is actually a clone. The original server is running in production with the original IP address. This server has a temporary IP address and is used as a test server so I can get my head around how to get SSO working reliably! (I can’t be restarting a production server every 5 minutes!)

Because of that, some of the domain names are technically wrong, but I did make sure that the PTR and SRV do point at this test server (They seem to have no effect on the production system)

Anyway, I will perform some more testing tomorrow and let you know what I find. I really wish there was a log file I could look at to see what the problem actually is, so far this whole process has been voodoo…



Once I modified the xmpp.fqdn property and re-did the SPN and GSS.conf to match (i.e. xmpp/xmpp.fqdn@domain.name ) I was able to login via SSO - or at least I thought.

I logged in as a test user ( new profile on my test workstation ) and that user could not login via SSO. which leads me to believe that the Spark client is falling back on the username/password authentication.

I also learned that the ktpass utility is useless when trying to add multiple SPNs into a keytab file. You need to create multiple keytabs and then use ktuitl to combine them.

Regardless it is progress and I will re-attack the problem tomorrow.


So I changed the Server FQDN to im2.domain.name

I modified the Openfire System Properties so the xmpp.fqdn and xmpp.domain are both im2.domain.name

Still no diference.

I’ve learned that if you run ktpass multiple times, and even if you save to different keytab files, the only one that is usable is the last one. ???

I’ve learned kadmin is the least useful utility in life!!

I found some properties in the AD user which other SSO manuals say is important:

In the users properties, there is a Delegation Tab. I set it to “Trust this user for delegation to any service (Kerberos Only)”

If your right-click the user there is a “Name Mapings…” option. In there I added the SPNs from above

Still no difference!

@speedy, you have been great, but… I’m losing the will to live!

Any other ideas?

Are you sure there is no log file anywhere???

no really. the debug logs and the logs in spark are pretty much it. most cases, the issue is with the keytab file or dns. If you like, I can help you out via webex sometime.


I might just take you up on that… A Java developer friend of my asked if the problem might be Java Kerberos vs Windows Kerberos or possibly a UAC problem…

I’m fighting so mail problems as well so I will get back to you soon.



So after a lengthy break, fighting other fires, I’m back to this problem…

I’ve simplified the installation so that the xmpp domain, xmpp fqdn, server name … everything is im2.domain.name

The domain name is i.domain.name and the principle is xmpp/im2.domain.name@I.DOMAIN.NAME.

I have tested the keytab file on the linux box and everything is working, and from what I can see, I have removed any chance of the client having UAC issues.

When I login from the workstation I see this error in the logs on the server:

2017.06.06 11:19:23 WARN [socket_c2s-thread-2]: org.jivesoftware.openfire.net.SASLAuthentication - An unexpected exception occurred during SASL negotiation. Affected session: org.jivesoftware.openfire.session.LocalClientSession@7ad76a26 status: 1 address: im2.domain.name/gmoua2myb id: gmoua2myb presence:

java.lang.SecurityException: java.io.IOException: Configuration Error:

Line 12: expected [option key]

at sun.security.provider.ConfigFile$Spi.<init>(ConfigFile.java:137)

at sun.security.provider.ConfigFile.<init>(ConfigFile.java:102)

at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)

at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessor Impl.java:62)

at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructor AccessorImpl.java:45)

at java.lang.reflect.Constructor.newInstance(Constructor.java:423)

at java.lang.Class.newInstance(Class.java:442)

at javax.security.auth.login.Configuration$2.run(Configuration.java:255)

at javax.security.auth.login.Configuration$2.run(Configuration.java:247)

at java.security.AccessController.doPrivileged(Native Method)

at javax.security.auth.login.Configuration.getConfiguration(Configuration.java:246 )

at sun.security.jgss.LoginConfigImpl$1.run(LoginConfigImpl.java:65)

at sun.security.jgss.LoginConfigImpl$1.run(LoginConfigImpl.java:63)

at java.security.AccessController.doPrivileged(Native Method)

at sun.security.jgss.LoginConfigImpl.<init>(LoginConfigImpl.java:63)

at sun.security.jgss.GSSUtil.login(GSSUtil.java:256)

at sun.security.jgss.krb5.Krb5Util.getServiceCreds(Krb5Util.java:206)

at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:74)

at sun.security.jgss.krb5.Krb5AcceptCredential$1.run(Krb5AcceptCredential.java:72)

at java.security.AccessController.doPrivileged(Native Method)

at sun.security.jgss.krb5.Krb5AcceptCredential.getInstance(Krb5AcceptCredential.ja va:71)

at sun.security.jgss.krb5.Krb5MechFactory.getCredentialElement(Krb5MechFactory.jav a:127)

at sun.security.jgss.GSSManagerImpl.getCredentialElement(GSSManagerImpl.java:193)

at sun.security.jgss.GSSCredentialImpl.add(GSSCredentialImpl.java:427)

at sun.security.jgss.GSSCredentialImpl.<init>(GSSCredentialImpl.java:62)

at sun.security.jgss.GSSManagerImpl.createCredential(GSSManagerImpl.java:154)

at com.sun.security.sasl.gsskerb.GssKrb5Server.<init>(GssKrb5Server.java:108)

at com.sun.security.sasl.gsskerb.FactoryImpl.createSaslServer(FactoryImpl.java:85)

at javax.security.sasl.Sasl.createSaslServer(Sasl.java:524)

at org.jivesoftware.openfire.net.SASLAuthentication.handle(SASLAuthentication.java :294)

at org.jivesoftware.openfire.net.StanzaHandler.process(StanzaHandler.java:182)

at org.jivesoftware.openfire.nio.ConnectionHandler.messageReceived(ConnectionHandl er.java:181)

at org.apache.mina.core.filterchain.DefaultIoFilterChain$TailFilter.messageReceive d(DefaultIoFilterChain.java:690)

at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(D efaultIoFilterChain.java:417)

at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilt erChain.java:47)

at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceiv ed(DefaultIoFilterChain.java:765)

at org.apache.mina.core.filterchain.IoFilterAdapter.messageReceived(IoFilterAdapte r.java:109)

at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(D efaultIoFilterChain.java:417)

at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilt erChain.java:47)

at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceiv ed(DefaultIoFilterChain.java:765)

at org.apache.mina.filter.codec.ProtocolCodecFilter$ProtocolDecoderOutputImpl.flus h(ProtocolCodecFilter.java:407)

at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(ProtocolCodecF ilter.java:236)

at org.apache.mina.core.filterchain.DefaultIoFilterChain.callNextMessageReceived(D efaultIoFilterChain.java:417)

at org.apache.mina.core.filterchain.DefaultIoFilterChain.access$1200(DefaultIoFilt erChain.java:47)

at org.apache.mina.core.filterchain.DefaultIoFilterChain$EntryImpl$1.messageReceiv ed(DefaultIoFilterChain.java:765)

at org.apache.mina.core.filterchain.IoFilterEvent.fire(IoFilterEvent.java:74)

at org.apache.mina.core.session.IoEvent.run(IoEvent.java:63)

at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTask(Ordere dThreadPoolExecutor.java:769)

at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.runTasks(Order edThreadPoolExecutor.java:761)

at org.apache.mina.filter.executor.OrderedThreadPoolExecutor$Worker.run(OrderedThr eadPoolExecutor.java:703)

at java.lang.Thread.run(Thread.java:748)

Caused by: java.io.IOException: Configuration Error:

Line 12: expected [option key]

at sun.security.provider.ConfigFile$Spi.ioException(ConfigFile.java:666)

at sun.security.provider.ConfigFile$Spi.match(ConfigFile.java:562)

at sun.security.provider.ConfigFile$Spi.parseLoginEntry(ConfigFile.java:477)

at sun.security.provider.ConfigFile$Spi.readConfig(ConfigFile.java:427)

at sun.security.provider.ConfigFile$Spi.init(ConfigFile.java:329)

at sun.security.provider.ConfigFile$Spi.init(ConfigFile.java:271)

at sun.security.provider.ConfigFile$Spi.<init>(ConfigFile.java:135)

... 50 more

So the gmoua2myb is I’m guessing the token being passed to the server for authentication. Which means that the UAC is not affecting my client and there is a problem with the server config…

Any thoughts?