3cx voip / letsencrypt tls
3cx voip / letsencrypt tls
Can you get your 3CX Phone System to connect to your SIP provider Trunk over TLS, when the server uses a Let’s Encrypt certificate?
3CX documentation on this topic is scarce. There are posts like 3CX Forum: SIP TLS:
It’s fairly straightforward: Your provider must give you a TLS Root Certificate (.pem) so you can encrypt the traffic. If they have SRV records the system will automatically know where to connect for TLS mode (Auto Discovery option on General trunk tab), or the provider might just tell you to change your port to the one they are listening to for TLS connections.
It can actually be that straightforward, if you do have the root certificate. But if you try to give the 3CX the certificate itself, or an intermediate — which is a perfectly fine thing to do in the TLS world — it will refuse without any useful info.
Step one: select TLS in the interface.
Step two: upload a root certificate.
Okay, this is peculiar. Why doesn’t it just use the certificates from the OS? The SIP server uses a perfectly valid Let’s Encrypt certificate. Do I really need to upload anything here?
The server certificate we’re presented with is:
- a valid and recent Let’s Encrypt certificate;
- with the common name (CN) matching the FQDN;
- with a
- available over TLSv1.2.
(It doesn’t use fancy new
URI:sip:FQDN subject alternative names, but
I haven’t come across any of those yet. And I doubt I can get those
inserted into my Let’s Encrypt certificates.)
But, as the 3CX needs something uploaded to continue, let’s just upload the certificate itself. Surely that is even more secure than any root certificate…
$ openssl s_client -connect TRUNK:5061 -showcerts </dev/null ... -----BEGIN CERTIFICATE----- MIINllCT1NLTkpCRU5IM1NKTFBBRjVSRU9MVTRBTU1VVEVPUjQzSkpBICAtCgcCA ... -----END CERTIFICATE-----
Put it in a
cert.pem, and upload it. Right?
Wrong! The 3CX will refuse to connect with the following error, which has no bearing on the actual problem:
SIP Server / Call Manager ID: 12293 Registration at TRUNK has failed. Destination (sip: sip.TRUNK.tld: 5061; transport = TLS; lr; maddr = 188.8.131.52) is not reachable, DNS error resolving FQDN, or service is not available.
Some tcpdump/wireshark sniffing helps us more:
3CX -> TRUNK.5061: TLSv1.2: Handshake Protocol: Client Hello (len 260) TRUNK.5061: 3CX -> TLSv1.2: Handshake Protocol: Server Hello (len 58) TRUNK.5061: 3CX -> TLSv1.2: Handshake Protocol: Certificate (len 2589) TRUNK.5061: 3CX -> TLSv1.2: Handshake Protocol: Server Hello Done (len 4) 3CX -> TRUNK.5061: TLSv1.2: Alert (Level: Fatal, Description: Unknown CA) (len 2)
- there is traffic (no DNS error, and there is a service);
- they both speak TLS, and the same version at that;
- the 3CX speaks of an
Okay. Let’s upload the intermediate certificate then. If we scroll up
openssl s_client command above, we can find it in the second
certificate block. Save it as
intermediate.pem and upload it.
Also wrong! Same error, same TLS handshake failure.
Instead, the 3CX really really wants us to get the root certificate. It could be found like this:
$ openssl x509 -in intermediate.pem -noout -subject -hash -issuer -issuer_hash subject=C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X3 4f06f81d issuer=O = Digital Signature Trust Co., CN = DST Root CA X3 2e5ac55d $ ls -l /etc/ssl/certs/2e5ac55d* lrwxrwxrwx 1 root root 18 mrt 12 2018 /etc/ssl/certs/2e5ac55d.0 -> DST_Root_CA_X3.pem $ openssl x509 -in /etc/ssl/certs/DST_Root_CA_X3.pem -noout -subject -hash -issuer -issuer_hash subject=O = Digital Signature Trust Co., CN = DST Root CA X3 2e5ac55d issuer=O = Digital Signature Trust Co., CN = DST Root CA X3 2e5ac55d
Very well. After uploading
DST_Root_CA_X3.pem, things started to work.
Now, if only 3CX could work on their error reporting.