3CX states support for TLS/SRTP and also handles SIP over TCP (instead of the default UDP).
There seems to be a problem with this when used with external devices (devices not reachable on the local LAN). I'll get to the problem, but first a quick overview.
I have followed the instructions here and setup TLS/SRTP and it does indeed work great for local phones (on the LAN). SIP over TCP (unencrypted) also works fine for local devices. Neither of these work with external phones.
So out of the three ways to handle SIP signalling, only the FIRST one works for external devices:
- SIP over UDP -- port 5060 (works for internal and external)
- SIP over TCP -- port 5060 (works for internal only)
- SIP over TLS -- port 5061 (works for internal only)
Of course TLS is just a specialised case of TCP -- still a TCP connection but with the content wrapped up in encryption -- so it makes sense that the problems I'm experiencing apply equally to plain TCP or TLS. For now I have disabled TLS and am doing my testing with straight vanilla TCP on port 5060 which is something that is mature and should work great.
I should add that the other part of the equation in securing calls, SRTP, works fine for both internal and external calls. I've been able to reduce the problem down to TCP-based connections for the SIP signalling, whether they are TLS or just plain unencrypted.
Before anyone points out anything about firewalling issues, I have ports 5060, 5061, and all the other required ports for the actual audio channels all forwarded (and for TCP too in the case of 5060 and 5061). The phone system is behind a connection with a static IP and is configured to use this in SIP invites, etc (in all places where the public IP is supposed to be specified). STUN is disabled as it's not needed, but I've tried with it on and the problem still exists.
When using TCP-based SIP signalling, external phones register fine and can even place calls. But the audio doesn't work. Switching back to SIP over UDP makes everything work fine again for these external devices.
From inspecting the logs, the problem appears to be that 3CX is sending the wrong IP when setting up the RTP connection -- but ONLY when non-UDP SIP signalling is used.
The logging is set to verbose. The calls were simply an extension phone calling the voice mail system (from outside the local LAN). For a call from an external device set to use UDP SIP signalling (which works fine) part of the logs show:
01:28:16.575 [MS210003] C:7.1:Answer provided. Connection(transcoding mode[unsecure]):<PUBLIC_IP_REMOVED>:9004(9005)
01:28:16.575 [MS210001] C:7.2:Answer received. RTP connection[unsecure]: 127.0.0.1:40622(40623)
You can see that the public IP was correctly specified by 3CX for setting up the RTP connection and consequently the call worked correctly with full audio heard both ways.
However, as soon as the phone is changed to use TCP-based SIP signalling, the same part of the logs show:
01:30:23.108 [MS210003] C:8.1:Answer provided. Connection(transcoding mode[unsecure]):192.168.7.7:9122(9123)
01:30:23.108 [MS210001] C:8.2:Answer received. RTP connection[unsecure]: 127.0.0.1:40624(40625)
Notice how the IP that 3CX gave out was the internal IP (192.168.7.7) of the phone system. Consequently the RTP connection can never be setup and after a timeout 3CX complains in its logs that no RTP packets were received and drops the call.
The ONLY difference between these two scenarios is whether UDP-based or TCP-based SIP signalling was used. As I said, the firewalling is definitely setup right. By switching to SIP over UDP instead of TCP, these same external devices work fine -- which proves that the firewalling is fine, since the same ports of 9000 to 9049 are used for the audio legs no matter whether the SIP signalling is UDP or TCP. And remember that the phones do register fine even when TCP or TLS SIP is used. And they even place the calls fine. It's just that the RTP connection can never be setup, as 3CX is sending the internal IP.
So it seems to be a bug in that whenever TCP SIP signalling is used, 3CX no longer uses the public IP you've specified for SIP invites, but instead reverts to using the internal IP. And of course this isn't going to work for devices located off the local LAN.
Of course it's hard for me to believe that such a bug would really exist, because then anyone using TLS would also be having this problem for external devices (and it's external devices where you normally care more about security).
So why is this happening, and has anyone else noticed this behaviour? Put another way, can anyone confirm that they have TLS or TCP SIP signalling successfully working for external phones?
I'm using the latest build of 3CX version 9, and it's a fully-licensed installation (but the same behaviour was observed when I initially was running the trial/free version). The phones I am using as external devices are the Counterpath Bria softphone app running on iPhones. This softphone supports TLS/SRTP and works great with 3CX.
BTW... the reason why it's important to be able to use TCP-based SIP signalling for external devices is because:
1) that's the only way to get SIP signalling encryption (TLS is inherently TCP-based and without that SRTP is much less effective since the keys are broadcast in plaintext)
2) UDP SIP signalling on external phones requires very regular keep-alive packets to be broadcast to reliably stay connected to the server, and this drains battery life. So even if you don't care about encryption, you probably do care about battery life.
Thanks for any insight!

