Openfire 4.6.0 on CentOS 8 with Spark 2.9.4 SSO for Windows AD Domain
Windows AD domain: test.domain.com Windows DC: srv01.test.domain.com Openfire server fqdn: openfire.test.domain.com
Setup AD user in Windows AD DC and setup DNS
In AD DNS setup a “Reverse Lookup Zone” for the subnets where your Openfire server, your domain controllers and your clients reside.
Then create a DNS Zone entry for the Openfire server in the forward lookup zone, create an A record, leave the name blank and enter the IP address; check the PTR record box.
In the same zone create a SRV record:
Service: _xmpp-client Protocol: _tcp Priority: 0 Weight: 5 Port number: 5222 Host: openfire.test.domain.com
DNS of Openfire Server: openfire.test.domain.com 10.7.7.19
Create an AD user that will be used to bind from Openfire to AD, put this in a special OU, set the password to never expire, make a note of what this account if for in the description. e.g. user: openfire.bind@test.domain.com
Create an AD user that will be used for Openfire administration put this in a special OU but that is in the same base OU as the other AD users that will be using Spark/Openfire, set the password to never expire, make a note of what this account if for in the description. e.g. user: openfire.admin@test.domain.com
Install Openfire
Install CentOS8 minimal with a static IP and a DNS that points to your AD DNS, a fqdn for a hostname that will be entered in some DNS system somewhere (we're using Windows AD/DNS), enable NTP, 1GB /boot, 10+GB / and a swap.
Login and perform update process
Reboot and perform a dnf update + install vim then reboot again…
dnf update && dnf install vim shutdown -r now
Create sudo User + Disable root SSH Access
Create user with password
useradd sudo_username && passwd sudo_username
Add user to wheel group for sudo privileges
usermod -aG wheel sudo_username
Log out of root and into newly created account.
Disable root login over SSH
sudo vim /etc/ssh/sshd_config
Add line
PermitRootLogin no
Restart sshd
sudo systemctl restart sshd
Install Fail2ban
This will help prevent the baddies from brute forcing your SSH password…
Install epel repo, install fail2ban and enable it
sudo dnf install epel-release sudo dnf install fail2ban sudo systemctl enable fail2ban sudo systemctl start fail2ban
Create a jail for sshd
sudo vim /etc/fail2ban/jail.d/sshd.local
Add as follows:
[sshd] enabled = true port = ssh logpath = %(sshd_log)s backend = %(sshd_backend)s [selinux-ssh] enabled = true port = ssh logpath = %(auditd_log)s
Restart fail2ban
sudo systemctl restart fail2ban
Install Dependancies and Utils
sudo dnf install wget mariadb-server
add firewall rules:
sudo firewall-cmd --permanent --zone=public --add-port=9090/tcp sudo firewall-cmd --permanent --zone=public --add-port=9091/tcp sudo firewall-cmd --permanent --zone=public --add-port=5222/tcp sudo firewall-cmd --permanent --zone=public --add-port=7777/tcp sudo firewall-cmd --reload
Download & Install Openfire
wget https://igniterealtime.org/downloadServlet?filename=openfire/openfire-4.6.0-1.x86_64.rpm sudo dnf install openfire-4.6.0-1.x86_64.rpm
Secure Mariadb and configure
sudo systemctl enable mariadb sudo systemctl start mariadb
Secure the MariaDB install
sudo mysql_secure_installation
Create Database for Openfire and import schema from Openfire resourse dir
sudo mysql -u root -p CREATE DATABASE openfire; CREATE USER 'openfireuser'@'localhost' IDENTIFIED BY 'yourpassword'; GRANT ALL PRIVILEGES ON openfire.* TO 'openfireuser'@'localhost' IDENTIFIED BY 'yourpassword' WITH GRANT OPTION; FLUSH PRIVILEGES; USE openfire; SOURCE /opt/openfire/resources/database/openfire_mysql.sql; EXIT;
Start and enable Openfire service
sudo systemctl enable openfire sudo systemctl start openfire
Go to web interface via http://ip.add.r.ess:9090 to start Setup Wizard
Set the property Encryption key via AES and generate an AES 256 key in a linux shell like so (and be sure to record it and the decryption password)
sudo openssl enc -d -a -md sha512 -aes-256-ctr -pbkdf2 -nosalt -p
Then enter it twice in fields below AES → next
Database Settings
Standard Database Connection → MySQL
For the Database URL change:
jdbc:mysql://HOSTNAME:3306/DATABASENAME?rewriteBatchedStatements=true
to
jdbc:mysql://localhost/openfire?rewriteBatchedStatements=true&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
Note: after you restart the openfire server you'll not be able to login after a fresh install on 4.3.2 due to a bug as listed here: https://discourse.igniterealtime.org/t/issue-when-restart-openfire-server-after-setup-openfire-using-mysql-with-utf-8-encode-via-a-fresh-installation/84011
Edit /etc/openfire/conf/openfire/xml and find the <serverURL>jdbc:mysql line, change any amp;amp; you find to just amp; then restart the openfire service.
Enter your openfire database username and password…. → next
Select LDAP server → Active Directory
host= fqdn of Windows domain controller, e.g. srv01.test.domain.com
Set your base DN where all your Openfire users will be,
e.g. OU=Users,OU=Hadden Technologies,DC=test,DC=domain,DC=com
Set your administrator DN,
e.g. openfire.bind@test.domain.com
For now we aren't going to use SSL or StartTLS for LDAP(s) but will change that later… (however if you have a valid certificate on the DC then changing the port to 636 and enabling “use ssl” works with our self signed certificate; note no keys have been imported into openfire yet… so it seems to trust things by default.)
User Mapping:
Username Field: sAMAccountName
User Profiles:
Check "Store Avatar in database..." Nickname: {description} (we use this to put the users name and an phone extension after the users name) Save & Continue...
Defaults on Group Mapping → Save & Continue
Add an admin user from AD to be able to login to Openfire Web UI and manage things (e.g. use the openfire.admin account created earlier in AD)… test it before saving and continuing… note: it needs to be in the base DN you specified earlier where all of your regular openfire users are or it won't work…
When logged into the Web UI, allow all AD user groups to be seen by others, go to groups, click on the group name, enable contact list group sharing, type a name for the group (normally the actual group name) then set to All users and save.
In the server properties change the ldap.nameField from cn to description and put your AD users name and phone extension in the description field in AD… I'm tired so this may see jumbled… who cares!
Install Spark on a computer, try to authenticate using one of your AD users.
Setup SSO
Now lets setup SSO… https://discourse.igniterealtime.org/t/openfire-spark-on-windows-server-2008-r2-with-sso/59574 https://discourse.igniterealtime.org/t/how-to-video-on-setting-up-sso-ad-with-openfire/79384 https://wiki.zimbra.com/wiki/Configuring_SPNEGO_Single_Sign-On https://discourse.igniterealtime.org/t/28-steps-to-single-sign-on-for-openfire-xmpp-server-on-windows-server-2012-r2-with-spark/41696 https://discourse.igniterealtime.org/t/sso-single-sign-on-configuration-changes-since-spark-2-8-0/41873
Create an AD user that will be used for keytab, put this in a special OU, set the password to never expire, make a note of what this account if for in the description. e.g. user: openfire.keytab → open the user → account → check “This account supports Kerberos AES 256 bit encryption” → Apply & OK.
Set SPN
Open a command prompt to create and assign a service principal name to the openfire.keytab account using the setspn utility. To use setspn you must run it from an elevated command prompt. Note: these are case sensitive so follow the convention accordingly.
setspn -S xmpp/openfire.test.domain.com@TEST.DOMAIN.COM openfire.keytab
Replace openfire.test.domain.com with your Openfire application server and use the fully qualified domain name. Replace @TEST.DOMAIN.COM with your AD domain name.
From the same command prompt use the ktpass utility to map the Kerberos XMPP service principal name created in the previous step to the openfire.keytab account.
ktpass -princ xmpp/openfire.test.domain.com@TEST.DOMAIN.COM -mapuser openfire.keytab@test.domain.com -pass * -ptype KRB5_NT_PRINCIPAL -crypto AES256-SHA1 -out c:\xmpp.keytab
openfire.keytab@test.domain.com is the full active directory username of the account. If you do not put the name of the active directory domain that the account was created in on the end, the utility may not be able to find the user account in active directory and report an error. The /pass * parameter will indicate to the ktpass utility to prompt you for the password for the openfire.keytab account.
Copy the keytab to the Openfire server at /opt/openfire/resources then chown it daemon:daemon
sudo chown daemon:daemon /opt/openfire/resources/xmpp.keytab
Allow Session Keys to Be Sent in Kerberos Ticket-Granting-Ticket https://support.microsoft.com/en-us/help/308339/registry-key-to-allow-session-keys-to-be-sent-in-kerberos-ticket-grant
Add the following registry key with a value of 1 to the computers that need to have SSO enabled. Note there is a security risk here as it stores the cached http://people.duke.edu/~rob/kerberos/kerbasnds.html https://www.varonis.com/blog/kerberos-loopholes-pass-ticket/
The registry value to include a session key in the TGT:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters Value Name: AllowTgtSessionKey Value Type: DWORD Value Range: 1
0: The KerbRetrieveEncodedTicketMessage response will not include a session key that allows this TGT to be used for logon. 1: Indicates that a session key should be returned with the TGT according to current behavior. Note With Windows 10 and Credential Guard, this approach is permanently disabled.
Create GSSAPI config file gss.conf and place it in /opt/openfire/conf
com.sun.security.jgss.accept { com.sun.security.auth.module.Krb5LoginModule required storeKey=true keyTab="/opt/openfire/resources/xmpp.keytab" doNotPrompt=true useKeyTab=true realm="TEST.DOMAIN.COM" principal="xmpp/openfire.test.domain.com@TEST.DOMAIN.COM" debug=true isInitiator=false; };
chown daemon:daemon /opt/openfire/conf/gss.conf
Edit Kerberos config file at /etc/krb5.conf, add the following, delete other stuff except [logging].
[libdefaults] default_realm = TEST.DOMAIN.COM allow_weak_crypto = 0 [realms] TEST.DOMAIN.COM = { kdc = srv01.test.domain.com admin_server = srv01.test.domain.com default_domain = test.domain.com } [domain_realms] domain.com = TEST.DOMAIN.COM .domain.com = TEST.DOMAIN.COM
Login to the Openfire admin console and enable GSSAPI by adding and saving the following properties on the System Properties section, be sure to replace my realm with your own:
Property Name Property Value sasl.gssapi.config /opt/openfire/conf/gss.conf sasl.gssapi.useSubjectCredsOnly false sasl.realm TEST.DOMAIN.COM Optional?????? (tested and looks to not be needed as of 4.3.2) authorization.classList org.jivesoftware.openfire.auth.DefaultAuthorizationPolicy sasl.gssapi.debug true or false sasl.mechs GSSAPI xmpp.fqdn openfire.test.domain.com
Now go to “Server Settings” → “Registration & Login” → under “SASL Mechanisms” uncheck all except GSSAPI.
Restart Openfire service….
Enable SSL/TLS for Openfire
http://web.mit.edu/Ghudson/dev/openfire/documentation/docs/ssl-guide.html https://discourse.igniterealtime.org/t/configure-ssl-tls-certificate-trust-for-xmpp-with-a-trusted-ca-for-client-to-server-channel-security-the-non-ui-stable-way/59172
cd into /opt/openfire/resources/security (you'll likely need to sudo su to do this).
Change the password on the keystore (default is changeit) (or skip this step as it can complicate things if you're having trouble, then come back and change it later)
/opt/openfire/jre/bin/keytool -storepasswd -keystore /opt/openfire/resources/security/keystore
(default password is changeit, enter new password when prompted)
Generate a certificate (use fqdn of openfire server for firstname lastname field)
/opt/openfire/jre/bin/keytool -genkey -keystore /opt/openfire/resources/security/keystore -keyalg RSA -keysize 4096 -alias openfire.test.domain.com # First and last name: chat.domainy.com [Enter the name that you entered previously as the domain. Seems weird, but it is required.] # OU: . [as in a dot, this is okay, or you can add something else] # Organization: [name of your organization used in the CA] # City: [name of the city used in the CA] # State/Province: [name of the state/province used in the CA] # Country Code: [two letter country code used in your CA] # accept with yes # enter a passphrase to protect the private key ## or simply [all must match CA] # /opt/openfire/jre/bin/keytool -genkey -keystore /opt/openfire/resources/security/keystore -keyalg RSA -keysize 4096 -alias chat.domainy.com -dname "CN=chat.domainy.com,O=Domainy\, Inc.,L=New York,ST=New York,C=US"
Generate CSR
cd /opt/openfire/resources/security /opt/openfire/jre/bin/keytool -certreq -keystore /opt/openfire/resources/security/keystore -alias openfire.test.domain.com -file openfire.test.domain.com.csr
Submit CSR to dogtag ca under Server option then approve. Copy contents of pkcs7 certification and paste into openfire.test.domain.com.p7b. Then convert certificate to pem format.
openssl pkcs7 -print_certs -in /opt/openfire/resources/security/openfire.test.domain.com.p7b -out /opt/openfire/resources/security/openfire.test.domain.com.pem
Open the pem file and copy the first block – BEGIN… – … – END… – and paste it into a new file named /opt/openfire/resources/security/openfire.test.domain.com.crt
Do the same for the 2nd block but name it root-ca.test.domain.com.crt as this is the CA signing certificate.
If there are 3 more more blocks then the middle blocks are intermediate certificates with the root certificate at the end, copy each of these into it's own appropriately named file (e.g. sub-ca.test.domain.com.crt and root-ca.test.domain.com.crt)
Import CA certificate then do the same for the intermediate/sub certificate if it exists.
/opt/openfire/jre/bin/keytool -trustcacerts -import -keystore /opt/openfire/resources/security/keystore -file /opt/openfire/resources/security/root-ca.test.domain.com.ca.crt -alias root-ca.test.domain.com
And put it/them into the trust store…
/opt/openfire/jre/bin/keytool -trustcacerts -import -keystore /opt/openfire/resources/security/truststore -file /opt/openfire/resources/security/root-ca.test.domain.com.ca.crt -alias root-ca.test.domain.com
Import server certificate
/opt/openfire/jre/bin/keytool -import -keystore /opt/openfire/resources/security/keystore -alias openfire.test.domain.com -file /opt/openfire/resources/security/openfire.test.domain.com.crt
Delete the default self signed certificate. Go into the web ui and open the certificate, the top will show the alias name.
keytool -delete -keystore keystore -alias rsa /opt/openfire/jre/bin/keytool -delete -keystore /opt/openfire/resources/security/keystore -alias openfire.test.domain.com_rsa
Restart Openfire
systemctl restart openfire
Ignore any wonky info in the TLS/SSL area of the web gui. Make sure you're root ca and any intermediate certificates are installed on the computer you're going to use to test TLS/SSL, remember Firefox has it's own keystore so use IE if you deployed the root/sub/intermediate ca via GPO. Go to https://openfire.test.domain.com:9091 and if the TLS/SSL certificate looks ok to IE you're good to move on to adding the CA certificates to Sparks keystore….
Last try (appears not needed as above instructions seem to work)….
https://itigloo.com/security/generate-an-openssl-certificate-request-with-sha-256-signature/
generate private key using openssl sudo openssl genrsa -out key_name.key 4096 generate requst openssl req -out CSR.csr -key key_name.key -new -sha256
Submit your request to CA. Copy the Base64 PEM file to new_cert.crt Export your root and sub certificates from Windows (if you've already installed them) Or copy the Base64 pkcs7 to a file and use openssl to convert it to PEM, delete the first block and extra text and use that as your ca-bundle.
https://arthurpemberton.com/2016/09/openfire-certificate-import
#! /bin/bash JavaDir=“/opt/openfire/resources/security” PASS=“changeit” certdomain=“im.example.com” certname=“im_example_com” certdir=“/etc/ssl” tmp=“/root/tmp”
## echo “stop openfire” ##/etc/init.d/openfire stop
echo “> deleting truststore and keystore” test -e “/opt/openfire/resources/security/truststore” && rm -f “/opt/openfire/resources/security/truststore” test -e “/opt/openfire/resources/security/keystore” && rm -f “/opt/openfire/resources/security/keystore”
echo “> merge domain certificate with CA certificate” cat “/etc/ssl/openfire.test.domain.com.crt” “/etc/ssl/openfire.test.domain.com.ca-bundle” > “/etc/ssl/openfire.test.domain.com.combined.crt”
echo “> create a new trust store” keytool -import -trustcacerts -storepass $PASS -alias “PositiveSSL” -file “/etc/ssl/openfire.test.domain.com.ca-bundle” -keystore “/opt/openfire/resources/security/truststore”
echo “> create new p12 file” openssl pkcs12 -export -in “/etc/ssl/openfire.test.domain.com.combined.crt” -inkey “/etc/ssl/openfire.test.domain.com.key” -out “/etc/ssl/openfire.test.domain.com.p12” -name “openfire.test.domain.com” -CAfile “${ca}” -passout pass:“changeit”
echo “> create new key store” keytool -importkeystore -deststorepass “$PASS” -srcstorepass “$PASS” -destkeystore “/opt/openfire/resources/security/keystore” -srckeystore “/etc/ssl/openfire.test.domain.com.p12” -srcstoretype PKCS12 -alias “openfire.test.domain.com”
echo “> change file perms” chmod 644 “/opt/openfire/resources/security/truststore” “/opt/openfire/resources/security/keystore”
echo “> change ownership” chown daemon:daemon “/opt/openfire/resources/security/truststore” “/opt/openfire/resources/security/keystore”
echo “> list directory” ls -lha “/opt/openfire/resources/security” *store*
## echo “start openfire” ##/etc/init.d/openfire start
Your selfsigned certificates, the CA certificates will need to be installed in any browser you want to use them with. To get them into Spark, use the program KeyStore Explorer (run it as admin or your won't be able to save the file) to open up c:\program files (x86)\spark\jre\lib\security\cacerts (pass changeit) and import your root and any intermediate/sub certificates, save. In Spark as of 2.9.4, open settings and disable OCSP check in certificates for your internal CA certificates. Now spark should be able to login withing bypassing certificate checks.