Hi all
I've set up a kamailio server on a public IP address to serve public clients.
- The clients REGISTER over a mix of TCP and TLS, so kamailio has
listeners on the same IP address: port 5060 for UDP/TCP and port 5061
for TLS.
- Some clients REGISTER from the same public IP address, behind the same NAT.
- Sometimes, the client-side NAT can use the same client-side IP
address and port for two concurrent connections - one TCP and one TLS
- which is normal because the server-side port is different (they're
different 5-tuples).
- Now when a request comes to kamailio, to be routed to a client, the
the t_relay_to_tls() function sometimes can relay the request over a
TCP connection instead of a TLS connection.
I've enabled tcp_connection_match=1. This is helpful, but it doesn't
completely resolve the problem. It helps when both connections (TCP
and TLS) are open, because the TLS connection will always be used for
TLS requests. However, when there's no TLS connection open, kamailio
will erroneously use the TCP connection.
Note that this setup depends on TCP/TLS connections being made from
the client to the server, not the other way around.
I've made a cut-down version of this setup to demonstrate the problem.
- Client: 11.15.32.1
- Server: 11.15.32.11
- version: kamailio 5.9.0-dev0 (x86_64/linux)
#################################################################
#!KAMAILIO
enable_tls=yes
listen=tls:11.15.32.11:5061
listen=tcp:11.15.32.11:5060
listen=udp:11.15.32.11:5060
loadmodule "tm"
loadmodule "tls"
loadmodule "pv"
loadmodule "rr"
fork=yes
log_facility=LOG_LOCAL0
log_stderror=no
children=2
debug=3
tcp_connection_match=1
modparam("tls", "low_mem_threshold1", -1)
modparam("tls", "low_mem_threshold2", -1)
modparam("tls", "certificate",
"/usr/local/etc/kamailio/certs/chain")
modparam("tls", "private_key",
"/usr/local/etc/kamailio/certs/key")
request_route {
loose_route();
$fs="tls:11.15.32.11:5061";
t_relay_to_tls();
}
#################################################################
This is a BYE message to be sent from internally in the network.
###########################
BYE sip:user3@11.15.32.1:33333;transport=tls SIP/2.0
Via: SIP/2.0/UDP 0.0.0.0:11111;rport;branch=z9hG4bK-d8754z-cc2c63344f5218d3-1
Route: <sip:11.15.32.11:5060;transport=tcp;r2=on;lr;ftag=ZUrDU2m4Z9Zam>
Route: <sip:11.15.32.11:5061;transport=tls;r2=on;lr;ftag=ZUrDU2m4Z9Zam>
f: <sip:user1@server>;tag=ZUrDU2m4Z9Zam
t: <sip:user3@server>;tag=gK0ea97395
i:sdfg8we790t874ujk
CSeq: 102 BYE
Content-Length: 0
###########################
When I send that to kamailio over UDP, kamailio relays it over a TCP
connection, as seen with socat here (socat runs on the machine with
address 11.15.32.1).
###########################
$ socat - TCP:11.15.32.11:5060,bind=:33333
BYE sip:user3@11.15.32.1:33333;transport=tls SIP/2.0
Via: SIP/2.0/TLS
11.15.32.11:5061;branch=z9hG4bKd2bf.137932ff9a937cde941fd1790db040c9.0
Via: SIP/2.0/UDP
0.0.0.0:11111;received=11.15.32.11;rport=11111;branch=z9hG4bK-d8754z-cc2c63344f5218d3-1
f: <sip:user1@server>;tag=ZUrDU2m4Z9Zam
t: <sip:user3@server>;tag=gK0ea97395
i:sdfg8we790t874ujk
CSeq: 102 BYE
Content-Length: 0
###########################
Note that
- the RURI has transport=tls in it,
- kamailio is forcing the TLS socket,
- kamailio is using the t_relay_to_tls function,
- the Route header field tells that TLS should be used, and
- the Via header field shows that kamailio tried to send this over TLS, but
- the BYE was sent over unencrypted TCP.
If I use this socat command instead, then I can receive the BYE,
showing that kamailio is able to use TLS if there's a connection
available.
- socat - OPENSSL:11.15.32.11:5061,bind=:33333,verify=no
I can't find any setting to control this, so it looks to me like a
kamailio bug. At that, I see this as a security flaw, because the SIP
traffic should always be encrypted but now is leaked.
Can anyone help?
James