Here is the setup I put together to have two SIP phones connect together over an encrypted channel. Since the two phones do not support encryption, I used Asterisk to provide the encrypted channel over the Internet.
Installing Asterisk
First of all, each VoIP phone is in a different physical location and so I installed an Asterisk server in each house.
One of the server is a Debian stretch machine and the other runs Ubuntu
bionic 18.04. Regardless, I used a fairly standard configuration and simply
installed the asterisk
package on both machines:
apt install asterisk
SIP phones
The two phones, both Snom 300,
connect to their local asterisk server on its local IP address and use the
same details as I have put in /etc/asterisk/sip.conf
:
[1000]
type=friend
qualify=yes
secret=password1
encryption=no
context=internal
host=dynamic
nat=no
canreinvite=yes
mailbox=1000@internal
vmexten=707
dtmfmode=rfc2833
call-limit=2
disallow=all
allow=g722
allow=ulaw
Dialplan and voicemail
The extension number above (1000
) maps to the following configuration
blurb in /etc/asterisk/extensions.conf
:
[home]
exten => 1000,1,Dial(SIP/1000,20)
exten => 1000,n,Goto(in1000-${DIALSTATUS},1)
exten => 1000,n,Hangup
exten => in1000-BUSY,1,VoiceMail(1000@mailboxes,su)
exten => in1000-BUSY,n,Hangup
exten => in1000-CONGESTION,1,VoiceMail(1000@mailboxes,su)
exten => in1000-CONGESTION,n,Hangup
exten => in1000-CHANUNAVAIL,1,VoiceMail(1000@mailboxes,su)
exten => in1000-CHANUNAVAIL,n,Hangup
exten => in1000-NOANSWER,1,VoiceMail(1000@mailboxes,su)
exten => in1000-NOANSWER,n,Hangup
exten => _in1000-.,1,Hangup(16)
the internal
context
maps to the following blurb in /etc/asterisk/extensions.conf
:
[internal]
include => home
include => iax2users
exten => 707,1,VoiceMailMain(1000@mailboxes)
and 1000@mailboxes
maps to the following entry in
/etc/asterisk/voicemail.conf
:
[mailboxes]
1000 => 1234,home,[email protected]
(with 1234
being the voicemail PIN).
Encrypted IAX links
In order to create a virtual link between the two servers using the
IAX protocol, I
created user credentials on each server in /etc/asterisk/iax.conf
:
[iaxuser]
type=user
auth=md5
secret=password2
context=iax2users
allow=g722
allow=speex
encryption=aes128
trunk=no
then I created an entry for the other server in the same file:
[server2]
type=peer
host=server2.dyn.fmarier.org
auth=md5
secret=password2
username=iaxuser
allow=g722
allow=speex
encryption=yes
forceencrypt=yes
trunk=no
qualify=yes
The second machine contains the same configuration with the exception of the
server name (server1
instead of server2
) and hostname
(server1.dyn.fmarier.org
instead of server2.dyn.fmarier.org
).
Speed dial for the other phone
Finally, to allow each phone to ring one another by dialing 2000
, I put
the following in /etc/asterisk/extensions.conf
:
[iax2users]
include => home
exten => 2000,1,Set(CALLERID(all)=Francois Marier <2000>)
exten => 2000,2,Dial(IAX2/server1/1000)
and of course a similar blurb on the other machine:
[iax2users]
include => home
exten => 2000,1,Set(CALLERID(all)=Other Person <2000>)
exten => 2000,2,Dial(IAX2/server2/1000)
Firewall rules
Since we are using the IAX protocol instead of SIP, there is only one port
to open in /etc/network/iptables.up.rules
for the remote server:
# IAX2 protocol
-A INPUT -s x.x.x.x/y -p udp --dport 4569 -j ACCEPT
where x.x.x.x/y
is the IP range allocated to the ISP that the other
machine is behind.
If you want to restrict traffic on the local network as well, then these ports need to be open for the SIP phone to be able to connect to its local server:
# VoIP phones (internal)
-A INPUT -s 192.168.1.3/32 -p udp --dport 5060 -j ACCEPT
-A INPUT -s 192.168.1.3/32 -p udp --dport 10000:20000 -j ACCEPT
where 192.168.1.3
is the static IP address allocated to the SIP phone.
On my Asterisk server, I happen to have two on-board ethernet boards. Since I only used one of these, I decided to move my VoIP phone from the local network switch to being connected directly to the Asterisk server.
The main advantage is that this phone, running proprietary software of unknown quality, is no longer available on my general home network. Most importantly though, it no longer has access to the Internet, without my having to firewall it manually.
Here's how I configured everything.
Private network configuration
On the server, I started by giving the second network interface a static IP
address in /etc/network/interfaces
:
auto eth1
iface eth1 inet static
address 192.168.2.2
netmask 255.255.255.0
On the VoIP phone itself, I set the static IP address to 192.168.2.3
and
the DNS server to 192.168.2.2
. I then updated the SIP registrar IP address
to 192.168.2.2
.
The DNS server actually refers to an unbound daemon running on the Asterisk server. The only configuration change I had to make was to listen on the second interface and allow the VoIP phone in:
server:
interface: 127.0.0.1
interface: 192.168.2.2
access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.1/32 allow
access-control: 192.168.2.3/32 allow
Finally, I opened the right ports on the server's firewall in
/etc/network/iptables.up.rules
:
-A INPUT -s 192.168.2.3/32 -p udp --dport 5060 -j ACCEPT
-A INPUT -s 192.168.2.3/32 -p tcp --dport 5060 -j ACCEPT
-A INPUT -s 192.168.2.3/32 -p udp --dport 10000:20000 -j ACCEPT
Network time synchronization
In order for the phone to update its clock automatically using NTP, I installed chrony on the Asterisk server:
apt install chrony
then I configured it to listen on the private network interface and allow access from the VoIP phone by adding the following to /etc/chrony/conf.d/asterisk-local.conf
:
bindaddress 192.168.2.2
allow 192.168.2.3
Finally, I opened the right firewall port by adding a new rule to /etc/network/iptables.up.rules
:
-A INPUT -s 192.168.2.3 -p udp --dport 123 -j ACCEPT
Accessing the admin page
Now that the VoIP phone is no longer available on the local network, it's not possible to access its admin page. That's a good thing from a security point of view, but it's somewhat inconvenient.
Therefore I put the following in my ~/.ssh/config
to make the admin page
available on http://localhost:8081
after I connect to the Asterisk server
via ssh:
Host asterisk
LocalForward localhost:8081 192.168.2.3:80
Allowing calls between local SIP devices
Because this local device is not connected to the local network
(192.168.1.0/24
), it's unable to negotiate a direct media connection to
any other local (i.e. one connected to the same Asterisk server) SIP device.
What this means is that while calls might get connected successfully, by
default, there will not be any audio in a call.
In order for the two local SIP devices to be able to hear one another, we
must enforce that all media be routed via Asterisk instead of going directly
from one device to the other. This can be done using the directmedia
directive (formerly
canreinvite
) in
sip.conf
:
[1234]
directmedia=no
where 1234
is the extension of the phone.