Homelab Hotline

Introduction

Inspired by the now defunct Hamshack hotline I have been researching how to set up a similar service for me and some friends. To begin with, I only need basic functionality: dial extensions to reach specific endpoints. More advanced PBX features I will leave for a later date.

To keep things simple I will be leveraging IPv6 to ignore NAT and allow true end-to-end communication for connected phones. This removes the need for a RTP relay. Phones communicate directly with eachother and the SIP server only handles the signalling. I chose Kamailio as my SIP server

In this setup I will be using the following architecture:

The goals for my setup are to have the SIP server exposed over the internet. This means I will need to keep security in mind during my setup. Transport Layer Security (TLS) is a must as well as using other tools to stop spam messages. Since this SIP server will not be the Public Switched Telephone Network (PSTN) I won’t need to worry about Toll Fraud which is the worst thing that can happen to a poorly configured SIP Server. My SIP server won’t have any important data that needs to be secure, and I will be trying to secure it as best as possible. So I am willing to take the risk of exposing it.

To mitigate risk I will be using Kamailio modules such as pike for rate limiting, sanity for dropping malformed requests. Database user auth with strong random passwords. TLS for the SIP talking and enforcing encryption of the RTP. Lastly I will be using Fail2Ban to block any bad IPs that misbehave.

I chose Kamailio as my SIP server because it is an extremely flexible solution that can scale up to thousands of active calls. There exists real life deployments of Kamailio for example the German telephone provider 1&1 that use it as it’s back end. I obviously don’t expect to be handling thousands of calls every minute but being able to use and experiment with enterprise ready solutions in the home lab is always fun. Kamailio is also free libre and open source (FLOSS)

The Setup

Kamailio is configured in a C like configuration language. The full config is available here. TLS configuration can be found here

The configuration is fairly conventional for Kamailio. Here I will highlight the most important parts.

route[REQUIRE_SRTP] {
    if (!has_body("application/sdp")) {
        sl_send_reply("488", "SDP Required");
        exit;
    }

    if (search_body("RTP/SAVP") || search_body("RTP/SAVPF") || search_body("a=crypto:")) {
        return;
    }

    sl_send_reply("488", "SRTP Required");
    exit;
}

This section is enforcing the use of SRTP by rejecting sessions that do not advertise encryption in SDP. The first if statement rejects requests if there is no Session Description Protocol included. The next if statement asks if encryption is included in the SDP body. If it is we return leaving the route. Lastly if we do not return because encryption is not present, we reply with an error and exit.

request_route {
	# Drop malformed requests
	if (!sanity_check("1511", "7")) {
		exit;
	}
	# Drop spam
	if (!pike_check_req()) {
		sl_send_reply("403", "Flood detected");
		exit;
	}
    # Prevent loops
    if (!mf_process_maxfwd_header("10")) {
        sl_send_reply("483", "Too Many Hops");
        exit;
    }

This section helps protect Kamailio from bad requests. The first block uses the sanity module to detect and block malformed requests. Next the pike module that records requests is able to block requests that come to often. Lastly looped SIP requests are detected and also blocked.

These blocks are essential for an internet exposed Kamailio server