Why?


Search This Blog

Tuesday, August 18, 2015

Asterisk behind NAT - on home network with dynamic IP

Asterisk behind NAT - on home network with dynamic IP

Here is what I did to get my Asterisk 100% functional behind NAT in my home network, without static IP.

First a little background. I am running Asterisk 13.4.0 on Centos 7. It uses 192.168.10.100 behind a Cisco/Linksys EA5400 router. Internet is provided by COX communications with 50 down and 5 up. this is a residential COX account so I do not get a static IP. My Asterisk is using a SIP Trunk to Vitelity. I have a few phones attached to my asterisk but for this wiki I will use the Yealink T19 I have and set it up as extension 100, and IP 192.168.10.2, for simplicity. I have the latest firmware on this Yealink as of 8/18/2015, version 31.72.0.75. My DID i got from Vitelity is 480-555-2222 (That's fake, but you get it)

From your PC go to http://checkip.amazonaws.com/ and get your external IP. You will need this IP later.

In my EA5400 router I did a few port forwards to my Asterisk server. They are:

SIP 5060 - 5062 UDP
RTP 10000 - 20000 UDP

Make sure the RTP range matches up with your Asterisk server. You can see this in rtp.conf. I also rebooted my router after this port forwarding was added.


Setup Asterisk with the Vitelity SIP Trunk. In sip.conf I made the following entry:

[general]
register => myaccount:mypassword@inbound32.vitelity.net:5060
alwaysauthreject=yes 
nat=yes
externip=x.x.x.x                                       ;Your real external IP goes here
localnet=192.168.10.0/255.255.255.0     ;Your real local net goes here with /subnet_mask
transport=udp
context=internal                                      ; Default context for incoming calls. Defaults to 'default'

[vitel-outbound]
type=friend
dtmfmode=auto
host=outbound.vitelity.net
username=myaccount
fromuser=myaccount
secret=mypassword
trustrpid=yes
sendrpid=yes
allow=all
canreinvite=no

A sip reload from the Asterisk console and then check things.

CLI> sip reload
CLI> sip show peers
vitel-outbound/myaccount   64.2.142.17                       Yes        Yes            5060     Unmonitored
CLI> sip show registry
inbound32.vitelity.net:5060     N      myaccount      45 Registered           Tue, 18 Aug 2015 14:40:39

As you can see we have both inbound and outbound set for Vitelity now.

For the phone setup for extension 100 I added the following in sip.conf:

[100]
type=friend
callerid=100
secret=myphoneregverysecretpassword
context=internal
host=dynamic
allow=all
dtmfmode=rfc2833
canreinvite=no


In the extensions.conf file I made the following entries:

[internal]
;used for in-bound DID to go to extension 100. If no answer then go to voicemail.
;after voice mail i play the goodbye message and then hangup
exten => 4805552222,1,Dial(SIP/100,20)
exten => 4805552222,n,VoiceMail(100@internal,u)
exten => 4805552222,n,Playback(vm-goodbye)
exten => 4805552222,n,Hangup

;used for extension to extension dialing
exten => 100,1,Dial(SIP/100,15)
exten => 100,n,VoiceMail(100@internal,u)
exten => 100,n,Playback(vm-goodbye)
exten => 100,n,Hangup
; used to dial outside line through our vitelity SIP Trunk
exten => _1NXXNXXXXXX,1,Dial(SIP/${EXTEN}@vitel-outbound)


Do a "core reload" from the asterisk console and you should be operational at this point for both in-bound/out-bound calls and have two way audio on your extension 100.

Now lets cover what happens when your external IP changes, as it will if you don't have a static IP, and how do you get an external client registered (like your soft phone when your outside your LAN). We fix these issues with a free service from duckdns.org and a couple scripts that run in cron every 5 minutes.

Since we don't have a static IP we can use an IP address for off net client registrations. We need to use a fqdn and make sure that is resolved to whatever IP COX has given us for that day/week/month.

Go to http://www.duckdns.org and sign up. Its free and takes like 5 seconds. From there you can chose a name for your domain. lets say you choose myhomeasterisk, then your fqdn will be myhomeasterisk.duckdns.org. After you have done this then click install at the top of there page, choose Linux cron, then select your domain you just created. You now get the script to run and all the instructions for getting it to run in cron. I wont redo the instructions here. They are really simple though.

With the duckdns solution in place we can now set our off net clients to register to our new domain we got with duckdns. If COX changes the IP on us then it will be updated within 5 minutes for us. Cox normally sets a lease time for a week, and then it is in the evening, so you should really never have a problem with this.

One last thing though. If COX changes the IP on us, and they will :) . Then we need to also update the Asterisk server sip.conf with our new external IP. I searched the web and found a script for this. Just a few mods to make it work for default Asterisk installs and it works like a charm.

In your /etc/asterisk directory create a file named updateexternalip.sh with the contents of:

#!/bin/bash

ip_url="http://checkip.amazonaws.com/"

oldip=`grep externip /etc/asterisk/sip.conf |sed 's/;.*//' |grep -v ^$ |sed s/.*=\ *//`
ip=`curl -s "$ip_url" |head -n 1`

echo $oldip
echo $ip

if [ "$oldip" != "$ip" ]
then
        echo "Updating IP"
        sed -i "s/externip=$oldip/externip=$ip/" /etc/asterisk/sip.conf
        asterisk -r -x "core reload"

fi


Set this file as executable with:

# chmod +x /etc/asterisk/updateexternalip.sh

Run this file for a test with:

# /etc/asterisk/updateexternalip.sh

It should echo your externip from sip.conf and also show you what your real external IP is. If these are different it will update your sip.conf file and reload asterisk for you.

To get this to run automatically every 5 minutes just add it to your contab file. The line to insert for this would be:

*/5 * * * * /etc/asterisk/updateexternalip.sh >/dev/null 2>&1

That's it. Enjoy !

2 comments:

  1. Oh ya. I do everything on this box as root. Not Prod, just home lab setup. So make sure you chown on the scripts if needed and run in cron with user that has rights, Thanks!

    ReplyDelete
  2. This comment has been removed by a blog administrator.

    ReplyDelete