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