Server certificates are needed when you use secure socket connections - SSL/TLS.
For secure socket connection a proper certificate is needed. You can either generate your own self-signed certificate or obtain certificate from trusted third party organization.
Here are steps how to obtain certificate from a trusted organization.
Self-signed certificates can be generated easily on a Linux system. Although it may not be considered a 'trusted' certificate authority, it can be useful to test server installations. We do not recommend regular use of self-signed certificates.
that Tigase v5.0 and later can automatically create self signed PEM files if needed. However we will cover doing this process by hand.
This tutorial assumes you are running a Linux-based operating system with access to command shell, and the 'Openssl' package is installed on the system.
The process takes the following steps:
1. Create a local private key. This file ends with .key extension. It is recommended to create a new private key for the process.
2. Generate a certificate request. This file ends with the .csr extension and is the file sent to the Certificate Authority to be signed.
3. CA signs private key. This can be done by your own computer, but can also be done by private CAs for a fee.
4. Results are obtained from the CA. This is a .crt
file which contains a separate public certificate.
5. Combine the .csr
and .crt
file into a unified .pem
file. Tigase requires keys to be non-password protected PEM files.
Generate local private key.
openssl genrsa -out [domain.com.key] 1024
This command generates a private key using a 1024 bit RSA algorithm. -out
designates the name of the file, in this case it will be domain.com.key
. The exact name is not important, and the file will be created in whatever directory you are currently in.
Generate a certificate request:
openssl req -nodes -key domain.com.key -out domain.com.csr
This command generates a certificate request using the file specified after -key
, and the result file will be domain.com.csr
. You will be asked a series of questions to generate the request.
Country Name (2 letter code) [AU]:AU State or Province Name (full name) [Some-State]:Somestate Locality Name (eg, city) []:Your city name Organization Name (eg, company) [Internet Widgits Pty Ltd]:Company name Organizational Unit Name (eg, section) []:Department or any unit Common Name (eg, YOUR name) []:*.yourdomain.com Email Address []:your_email_address@somedomain.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
Sign the Certificate Request: Now the .csr file will be signed by a Certificate Authority. In this tutorial, we will be self-signging our certificate. This practice however is generally not recommended, and you will receive notifications that your certificate is not trusted. There are commercial offers from companies to sign your certificate from trusted sources. Please see the Certificate From Other Providers section for more information.
openssl x509 -req -days 365 -in domain.com.csr -signkey domain.com.key -out domain.com.crt
This command signs the certificate for 365 days and generates the domain.com.crt
file. You can, of course use any number of days you like.
Generate PEM file. You should now have the following files in the working directory: ..\ domain.com.key domain.com.csr domain.com.crt
cat yourdomain.com.cert.pem intermediate.cert.pem root.cert.pem > yourdomain.com.pem
If the certificate is issued by third-party authority you will have to attach the certificate chain, that being certificate of the authority who has generated your certificate. You normally need to obtain certificates for your chain from the authority who has generated your certificate.
The result file should looks similar to:
-----BEGIN CERTIFICATE----- MIIG/TCCBeWgAwIBAgIDAOwZMA0GCSqGSIb3DQEBBQUAMIGMMQswCQYDVQQGEwJJ . . . pSLqw/PmSLSmUNIr8yQnhy4= -----END CERTIFICATE----- -----BEGIN RSA PRIVATE KEY----- WW91J3JlIGtpZGRpbmchISEKSSBkb24ndCBzaG93IHlvdSBvdXIgcHJpdmF0ZSBr . . . ZXkhISEhCkNyZWF0ZSB5b3VyIG93biA7KSA7KSA7KQo= -----END RSA PRIVATE KEY----- -----BEGIN CERTIFICATE----- MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW . . . xV/stleh -----END CERTIFICATE-----
For Tigase server as well as many other servers (Apache 2.x), the order is following; your domain certificate, your private key, authority issuing your certificate, root certificate.
Note! Tigase requires full certificate chain in PEM file (described above)! Different applications may require pem file with certificates and private key in different order. So the same file may not be necessarily used by other services like Web server or e-mail server. Currently, Tigase can automatically sort certificates in PEM file while loading it.
Installing and loading certificates is very easy. The server can load all certificates directly from pem files. You just need to create a separate pem file for each of your virtual domains and put the file in a directory accessible by the server. Tigase server can automatically load all pem files found in given directory. By default, and to make things easy, we recommend the Tigase/certs
directory.
It’s also possible to use:
* Admin ad-hoc command via XMPP client - you should navigate to Service Discovery of your server and in the list of commands for VHost Manager
component select Add SSL Certificate
and then follow instructions
* Admin WebUI - open http://<host>/admin
, navigate to Other
category and in it select Add SSL Certificate
and then follow instructions
* REST API - make a POST
request to http://localhost:8080/rest/adhoc/vhost-man@domain.com
with payload containing your certificate; to get the required form fields make GET
request to the same endpoint
There is number of certificate providers offering certificates either for free or for money. You can use any of them, however you have to be aware that sometimes certificates might not be recognized by all XMPP servers, especially if it’s one from a new provider. Here is an example list of providers:
To obtain certificate from a third party authority you have to go to its website and request the certificate using certificate request generated above. I cannot provide any instructions for this as each of the providers listed have different requirements and interfaces.
We highly recommend using LetsEncrypt keys to self-sign and secure your domain. Instructions are in the next section.
By default, each virtual hosts will require it’s own certificate. However, if you choose to use one certificate for all virtual hosts, Tigase supports that option. For example, if you have host1.example.net, host2.example.net, and host3.example.net each vhost will need some configuration:
'certificate-container' { 'custom-certificates' { 'host1.example.net' = '/home/tigase/certs/host1.pem' 'host2.example.net' = '/home/tigase/certs/host2.pem' 'host3.example.net' = '/home/tigase/certs/host3.pem' } }
This may be time consuming if you have many Vhosts, or expect to generate many more. The good news is, now one certificate can be used for ALL Vhosts using the following configuration line:
'certificate-container' { 'custom-certificates' { '*.example.net' = '/home/tigase/certs/certificate.pem' } }
Now any Vhosts created will use the same certificate located at /home/tigase/certs/certificate.pem.
This is an all or nothing option, if you wish to customize each Vhost, you will need to do so individually.
LetsEncrypt is a trusted CA that provides free security certificates. Unlike previously self-signed certificates, we can use LetsEncrypt Certificates to certify your domains from a trusted source.
Please refer to official [certbot User Guide](https://certbot.eff.org/docs/using.html) for details how to install and operate the tool, choosing desired method of domain authentication (DNS or webserver). After successful execution the certificate with all related files will be stored under /etc/letsencrypt/live/$domain
$ sudo ls /etc/letsencrypt/live/$domain cert.pem chain.pem fullchain.pem privkey.pem README
In that directory, you will find four files:
- privkey.pem
- private key for the certificate
- cert.pem
- contains the server certificate by itself
- chain.pem
- contains the additional intermediate certificate or certificates
- fullchain.pem
- all certificates, including server certificate (aka leaf certificate or end-entity certificate). The server certificate is the first one in this file, followed by any intermediates.
For Tigase XMPP Server, we are only concerned with privkey.pem
and fullchain.pem
.
At this point we will need to obtain the root and intermediate certificates, this can be done by downloading these certificates from the LetsEncrypt website.
Alternatively, you may obtain them using wget:
wget https://letsencrypt.org/certs/isrgrootx1.pem wget https://letsencrypt.org/certs/letsencryptauthorityx3.pem
These are the root certificate, and the intermediate certificate signed by root certificate.
IdenTrust cross-signed certificate will not function properly.
Take the contents of your privkey.pem
, certificate, and combine them with the contents of isrgrootx1.pem
and letsencryptauthorityx3.pem
into a single pem certificate. You need to name the file after your domain such as mydomain.com.pem
and place it under certs/
subdirectory of Tigase XMPP Server installation
If you moved all certs to a single directory, you may combine them using the following command under *nix operating systems:.
cat ./cert.pem ./privkey.pem ./letsencryptauthorityx3.pem ./isrgrootx1.pem > mydomain.com.pem
If you are using isrgrootx1
root make sure you use cert.pem
file instead of fullchain.pem
, which uses different intermediate certificate ( Let’s Encrypt Authority X3 (IdenTrust cross-signed) ) and you will have to use DST Root CA X3 certificate!
Your certificate should look something like this:
-----BEGIN PRIVATE KEY----- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDAUAqqKu7Z4odo ... og89F9AbWr1mNmyRoScyqMXo -----END PRIVATE KEY----- -----BEGIN CERTIFICATE----- cmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4 ... TzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- FhpodHRwOi8vY3BzLmxldHNlbmNyeXB0Lm9yZzCBqwYIKwYBBQUHAgIwgZ4MgZtU ... bmcgUGFydGllcyBhbmQgb25seSBpbiBhY2NvcmRhbmNlIHdpdGggdGhlIENlcnRp -----END CERTIFICATE-----
LetsEncrypt certificates expire 90 days from issue and need to be renewed in order for them to remain valid!
You can check your certificate with utility class:
java -cp <path_to_tigase-server_installation>/jars/tigase-utils.jar tigase.cert.CertificateUtil -lc mydomain.com.pem -simple
The only way to obtain wildcard (*.domain.com
) certificate is via DNS verification. Certbot support a number of DNS operators - you can check if your DNS provider is listed by executing $ certbot plugins
If you want to use it with Amazon Cloud you should install plugin for AWS:
pip install certbot-dns-route53
If you are using certbot under macOS and you installed it via brew then you should use:
$( brew --prefix certbot )/libexec/bin/pip install certbot-dns-route53
You should store your credentials in ~/.aws/credentials
(you may want to create dedicated policy for updating DNS as described in plugin’s documentation:
[default] aws_access_key_id = <key_id> aws_secret_access_key = <key>
And afterward you should execute certbot
with --dns-route53
parameter
For greater automation it’s possible to automate updating certificate obtained with certbot
in Tigase XMPP Server. You should use following deploy hook - either add it to /etc/letsencrypt/renewal-hooks/deploy/
or use it directly in certboot
commandline with --deploy-hook
parameter (in the latter case, it will be added to particular domain configuration so it’s not necessary to specify UPDATE_DOMAINS).
Please adjust account credentials used for deployment (USER
, PASS
, DOMAIN
) as well as paths to Let’s Encrypt certificates (ISRG Root X1 named isrgrootx1.pem
and Let’s Encrypt Authority X3 named letsencryptauthorityx3.pem
)
#!/bin/bash set -e ## Configuration START USER="admin_username" PASS="admin_password" DOMAIN="my_domain.tld" HOST=${DOMAIN} #UPDATE_DOMAINS=(${DOMAIN}) # PORT=":8080" # APIKEY="?api-key=mySecretKey" LE_CERTS_PATH="/path/to/letsencrypt/CA/certificates/" ## Configuration END fail_count=0 for domain in ${RENEWED_DOMAINS[@]}; do if [[ $domain == "*."* ]]; then CERT_DOMAIN=${domain#*\*.} else CERT_DOMAIN=${domain} fi if [[ ! -z "${UPDATE_DOMAINS}" ]] ; then match=0 for dn in "${UPDATE_DOMAINS[@]}"; do if [[ $dn = "$CERT_DOMAIN" ]]; then match=1 break fi done if [[ $match = 0 ]]; then echo "Skipping updating ${domain} because it's not in the list of supported domains: ${UPDATE_DOMAINS[@]}" continue fi fi CERT=`cat "$RENEWED_LINEAGE/cert.pem" "$RENEWED_LINEAGE/privkey.pem" ${LE_CERTS_PATH}/isrgrootx1.pem ${LE_CERTS_PATH}/letsencryptauthorityx3.pem` REQUEST=" <command> <node>ssl-certificate-add</node> <fields> <item> <var>Certificate in PEM format</var> <value>${CERT}</value> </item> <item> <var>command-marker</var> <value>command-marker</value> </item> <item> <var>VHost</var> <value>${CERT_DOMAIN}</value> </item> <item> <var>Save to disk</var> <value>true</value> </item> </fields> </command>" response=`curl -s -L -H "Content-Type: text/xml" -X POST http://${USER}%40${DOMAIN}:${PASS}@${HOST}${PORT}/rest/adhoc/vhost-man@${DOMAIN}${APIKEY} -d "${REQUEST}"` if [[ ! ${response} = *"loaded successfully"* ]] ; then echo -e "Server returned error while updating ${domain} certificate:\n ${response}" fail_count=$((${fail_count}+1)) else echo "Correctly updated ${domain} certificate" fi done exit ${fail_count}
If you are not using wildcard certificate when you have to provide certificate for main domain as well as certificates for subdomains that mach all components that you want to expose (muc, pubsub, push, etc…)