I am revamping my XMPP server and I’ve written down notes on how to set up certificates to enable TLS.
I will run Debian Jessie with JabberD 2.x, using the recent jabberd2 jessie-backport. The choice of server software is not significant for the rest of this post.
Running XMPP over TLS is a good idea. So I need a X.509 PKI for this purpose. I don’t want to use a third-party Certificate Authority, since that gives them the ability to man-in-the-middle my XMPP connection. Therefor I want to create my own CA. I prefer tightly scoped (per-purpose or per-application) CAs, so I will set up a CA purely to issue certificates for my XMPP server.
The current XMPP specification, RFC 6120, includes a long section 13.7 that discuss requirements on Certificates.
One complication is the requirement to include an AIA for OCSP/CRLs — fortunately, it is not a strict “MUST” requirement but a weaker “SHOULD”. I note that checking revocation using OCSP and CRL is a “MUST” requirement for certificate validation — some specification language impedence mismatch at work there.
The specification demand that the CA certificate MUST have a keyUsage extension with the digitalSignature bit set. This feels odd to me, and I’m wondering if keyCertSign was intended instead. Nothing in the XMPP document, nor in any PKIX document as far as I am aware of, will verify that the digitalSignature bit is asserted in a CA certificate. Below I will assert both bits, since a CA needs the keyCertSign bit and the digitalSignature bit seems unnecessary but mostly harmless.
My XMPP/Jabber server will be “chat.sjd.se” and my JID will be “simon@josefsson.org”. This means the server certificate need to include references to both these domains. The relevant DNS records for the “josefsson.org” zone is as follows, see section 3.2.1 of RFC 6120 for more background.
_xmpp-client._tcp.josefsson.org. IN SRV 5 0 5222 chat.sjd.se. _xmpp-server._tcp.josefsson.org. IN SRV 5 0 5269 chat.sjd.se.
The DNS records or the “sjd.se” zone is as follows:
chat.sjd.se. IN A ... chat.sjd.se. IN AAAA ...
The following commands will generate the private key and certificate for the CA. In a production environment, you would keep the CA private key in a protected offline environment. I’m asserting a expiration date ~30 years in the future. While I dislike arbitrary limits, I believe this will be many times longer than the anticipated lifelength of this setup.
openssl genrsa -out josefsson-org-xmpp-ca-key.pem 3744 cat > josefsson-org-xmpp-ca-crt.conf << EOF [ req ] x509_extensions = v3_ca distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] CN=XMPP CA for josefsson.org [ v3_ca ] subjectKeyIdentifier=hash basicConstraints = CA:true keyUsage=critical, digitalSignature, keyCertSign EOF openssl req -x509 -set_serial 1 -new -days 11147 -sha256 -config josefsson-org-xmpp-ca-crt.conf -key josefsson-org-xmpp-ca-key.pem -out josefsson-org-xmpp-ca-crt.pem
Let’s generate the private key and server certificate for the XMPP server. The wiki page on XMPP certificates is outdated wrt PKIX extensions. I will embed a SRV-ID field, as discussed in RFC 6120 section 13.7.1.2.1 and RFC 4985. I chose to skip the XmppAddr identifier type, even though the specification is somewhat unclear about it: section 13.7.1.2.1 says that it “is no longer encouraged in certificates issued by certification authorities” while section 13.7.1.4 says “Use of the ‘id-on-xmppAddr’ format is RECOMMENDED in the generation of certificates”. The latter quote should probably have been qualified to say “client certificates” rather than “certificates”, since the latter can refer to both client and server certificates.
Note the use of a default expiration time of one month: I believe in frequent renewal of entity certificates, rather than use of revocation mechanisms.
openssl genrsa -out josefsson-org-xmpp-server-key.pem 3744 cat > josefsson-org-xmpp-server-csr.conf << EOF [ req ] distinguished_name = req_distinguished_name prompt = no [ req_distinguished_name ] CN=XMPP server for josefsson.org EOF openssl req -sha256 -new -config josefsson-org-xmpp-server-csr.conf -key josefsson-org-xmpp-server-key.pem -nodes -out josefsson-org-xmpp-server-csr.pem cat > josefsson-org-xmpp-server-crt.conf << EOF subjectAltName=@san [san] DNS=chat.sjd.se otherName.0=1.3.6.1.5.5.7.8.7;UTF8:_xmpp-server.josefsson.org otherName.1=1.3.6.1.5.5.7.8.7;UTF8:_xmpp-client.josefsson.org EOF openssl x509 -sha256 -CA josefsson-org-xmpp-ca-crt.pem -CAkey josefsson-org-xmpp-ca-key.pem -set_serial 2 -req -in josefsson-org-xmpp-server-csr.pem -out josefsson-org-xmpp-server-crt.pem -extfile josefsson-org-xmpp-server-crt.conf
With this setup, my XMPP server can be tested by the XMPP IM Observatory. You can see the c2s test results and the s2s test results. Of course, there are warnings regarding the trust anchor issue. It complains about a self-signed certificate in the chain. This is permitted but not recommended — however when the trust anchor is not widely known, I find it useful to include it. This allows people to have a mechanism of fetching the trust anchor certificate should they want to. Some weaker cipher suites trigger warnings, which is more of a jabberd2 configuration issue and/or a concern with jabberd2 defaults.
My jabberd2 configuration is simple — in c2s.xml I add a <id> entity with the “require-starttls”, “cachain”, and “pemfile” fields. In s2s.xml, I have the <pemfile>, <resolve-ipv6>, and <require-tls> entities.
Some final words are in order. While this setup will result in use of TLS for XMPP connections (c2s and s2s), other servers are unlikely to find my CA trust anchor, let alone be able to trust it for verifying my server certificate. I’m happy to read about Peter Saint-Andre’s recent SSL/TLS work, and in particular I will follow the POSH effort.
Whether a CA can MITM your connections doesn’t depend on whether you use them in the first place; it depends on whether your peers trust them. And like it or not, your peers do. So you might as well use a certificate that people can trust.
Unfortunately, as far as I can tell, XMPP doesn’t have anything like certificate pinning.
Thanks for feedback!
Any CA can MITM my connections if I use them, by issuing a “fake” certificate for my names. I don’t see any way around that, modulo new ideas like CT where you can audit the CAs. So I don’t follow why I might as well use a certificate signed by a WebPKI CA.
Perhaps I should use different policies for c2s and s2s though.
For my server, and c2s, I control both the client and server environment and don’t want MITMs. Using an internal CA is not visible to anyone.
For s2s, I control only my side of of the connection, and cannot control what my peer uses or trust. But that goes both ways — my peers doesn’t control what I use or trust. If there is a subset of common (WebPKI?) CAs that all s2s operators can trust, then everything works if admins use one of those CAs for signing their s2s certs. So in theory all s2s XMPP servers should use a CA that everyone can use, that solves the problem. I believe that requirement is not an easy one to enforce, at least not until we have CT.
However the trust anchor question doesn’t matter for s2s if peers do not verify the s2s certificate. How common is that? I have not found that any of my peer servers refuse to talk s2s to me. Admittedly, my contact list is fairly short, but it involves people using Google’s chat system, FSFE’s jabber server, and a couple of people who runs their own server. So at least those servers accept s2s without verifying trust anchors.
Certificate pinning is difficult for servers — what should the server do when the pinned certificate does not match with what the server present? Peers need to be able to roll certificates legitimately.
/Simon
For c2s, of course you can use anything you want; it doesn’t matter.
For s2s, if your peers aren’t verifying the certificate, then you can be *trivially* MITMed; someone can make up another certificate and your peers will accept it. Lack of verification is a critical bug in XMPP server software; please file it as such.
Good point re s2s. I’ll see if I can find out what server software some of my s2s peers uses, and then investigate why it doesn’t perform said validation.
I’ve never had issues establishing s2s connections to peers, and I have been using a similar setup with my own XMPP CA since last autumn. Google talks s2s to me, for example.
Some of my peers run their own CAs too, which suggests my XMPP server software (jabberd2) does not perform s2s server certificate validation properly either.
While this may be a bug from a specification point of view, I think in reality the issue is a bit more delicate. There appears to be no way to do s2s server certificate verification in a secure way today without assuming everyone trust a subset of CAs. So s2s deployments/implementations appear to disable s2s certificate validation in order to get interoperability.
/Simon
“I note that checking revocation using OCSP and CRL is a “MUST” requirement for certificate validation — some specification language impedence mismatch at work there.”
If it exists (and it SHOULD), then it MUST be used. No mismatch.
I agree the simplest fix is to add a qualifying ‘If it exists’. It doesn’t have that part at the moment. The text from 13.7.2 says:
5. Check certificate revocation messages via Certificate Revocation
Lists (CRLs), the Online Certificate Status Protocol [OCSP], or
both.
And goes on with:
If any of those validation attempts fail, the validating entity MUST
unilaterally terminate the session.
It could be argued that not finding valid CRL and OCSP responses could constitut “fail”.
/Simon
I think you got something really wrong there.
Of course, the CA you use can issue a fake certificate and impersonate you.
But that is also true for any other CA, no matter whether you use it or not. If it is in the trusted CA list of the client, e.g. ca-certificates, then this CA can impersonate you.
What you say only applies if all your clients remove all trusted CA certificates and if all s2s peers do the same – which will not happen and, as a matter of sad fact, would make XMPP unusable.
That said, a personal PKI does *not* help. On the contrary, it breaks things. If you have concerns that a CA will fake your certificate *and* gain access to your DNS to spoof that as well, then you have other issues.
What you should do is use TLSA, DNSSEC and end-to-end encryption.
Yes, this issue is true for all CAs. That’s why we need something better than WebPKI where the only security is “a lot of people already depend on this small number of CAs so you should too”. I find that argument unconvincing. Certificate Transparency is the closest to a solution I am aware of. If everyone has the ability to collectively audit the CAs with CT, you could trust them implicitly, since you are trusting that enough people/organizations actually will perform this auditing. It really changes the trust model from trusting a particular CA private key into trusting a process, which makes more sense to me.
I did not make the distinction between c2s and s2s, and I really should have. For my deployment c2s is within a single administrative domain, so it is much simpler.
What I would like to achieve on my client/server is indeed to remove the trust setting on all CAs. This should work fine on a c2s level for me.
You say this would break XMPP on a s2s level, but this does not seem to be the case — it actually appears that XMPP s2s is deployed without server certificate verification today. At least from my very limited experience (Google, jabber.dk, jabber.fsfe.org, and a couple of personal setups similar to mine) XMPP s2s with TLS but “personal PKI” works fine.
I don’t see how a CA could fake a certificate to gain access to my DNS?
In my view, DNSSEC trust is similar to WebPKI trust. I used to believe in DNSSEC but the adverseral model has changed in the last 10-15 years, making it provide little for a relatively high cost.
I firmly believe in end-to-end security though. OpenPGP over XMPP can provide good security, but the UI experience with different clients isn’t perfect.
/Simon
Pingback: Let’s Encrypt Clients – Simon Josefsson's blog
sorry for a noob question, I am new to SSL
if your XMPP users are created like
user@mydom.com
and mydom.com has srv records pointing to im1.abc.com and im2.abc.com than how do you order the SSL certs for these?
do you just order certs for abc.com domain and install them on im1 and im2 severs?
is the server identity check only done for the domain returned in srv records?
Pingback: Why I don’t Use 2048 or 4096 RSA Key Sizes – Simon Josefsson's blog