Jump to content

Linux script for Asterisk (updating IP)

Go to solution Solved by Fetzie,

A few pointers that could help you:

#!/bin/bash

 

myIP=$(dig +short myip.opendns.com @resolver1.opendns.com)

 

Assuming the config file is formatted like this:

 

externalip=192.168.0.1

 

then you can call eval:

 


extIPSetting=$(cat /path/to/Unistim.conf | grep externalip)

eval ${extIPSetting}

extIpFromFile=${externalip}

 

Then compare them and if they aren't equal, replace it with something like this:

if [ "${extIpFromFile}" != "${myIP}" ]; then

    sed -i "s/externalip=${extIpFromFile}/externalip=${myIP}/g" /path/to/Unistim.conf

fi

 

You can execute "restart gracefully" to stop Asterisk from accepting new calls and restart when call volume is empty, which should be:


asterisk -rx"restart gracefully"

 

Double-check the sed command (I always seem to get that wrong at the first attempt :( ) and the asterisk execution command, but it should work like that  :)

Hi

 

The explanation: I have some Nortel phones that require the chan_unistim module. I've got them (well... one of them. But if I can get one working they should all work) working however they require my public IP to be put in the unistim.conf file before asterisk loads. Slight problem - I have a dynamic IP. (I can get a static IP inexpensively but I want to try and get this working). That means the phones can get the correct IP and boot, but if the IP changes, Asterisk will update it's self but the phones won't get updated.

 

Quick version: my plan is to try and write a script that: 1. Grabs my current IP, 2. Compares it to the IP entered in the Unistim.conf file, 3. If they are different, update the Unistim.conf file, 4 Check to see is there are any current calls going one, 5. If not, restart Asterisk (they phones will disconnect and re boot with correct IP), 6. If there are calls going on, check again in a set time (about 10 seconds?).

 

I've got the script to grab my current IP but that's about where my knowledge ends... for 4. I was thinking of getting the script to check if there is any traffic on my RTP ports (10000-10010). If there is then there must be a call going on. I realise this is a pretty janky solution but oh well. It's not by any means a critical system. If someone tries to call me during the reboot, they can either try again in a few minutes, call my mobile or leave a voicemail with my VoIP provider (or other PBX depending on how I set it up). I don't even know if it's possible to do what I'm asking (I suspect it is, how easy it is, I have no idea).

 

dig +short myip.opendns.com @resolver1.opendns.com

 

Thanks for any help :)

CPU: 8320, GPU: 7870 Myst, Motherboard: Asrock 970 extreme3, PSU: XFX Pro 650W, RAM: 8GB Corsair Vengeance 1600Mhz, Case: Zalman Z11

Link to comment
https://linustechtips.com/topic/690646-linux-script-for-asterisk-updating-ip/
Share on other sites

Link to post
Share on other sites

A few pointers that could help you:

#!/bin/bash

 

myIP=$(dig +short myip.opendns.com @resolver1.opendns.com)

 

Assuming the config file is formatted like this:

 

externalip=192.168.0.1

 

then you can call eval:

 


extIPSetting=$(cat /path/to/Unistim.conf | grep externalip)

eval ${extIPSetting}

extIpFromFile=${externalip}

 

Then compare them and if they aren't equal, replace it with something like this:

if [ "${extIpFromFile}" != "${myIP}" ]; then

    sed -i "s/externalip=${extIpFromFile}/externalip=${myIP}/g" /path/to/Unistim.conf

fi

 

You can execute "restart gracefully" to stop Asterisk from accepting new calls and restart when call volume is empty, which should be:


asterisk -rx"restart gracefully"

 

Double-check the sed command (I always seem to get that wrong at the first attempt :( ) and the asterisk execution command, but it should work like that  :)

AMD Ryzen 7800 X3D, MSI B650 Project Zero, Antec C5, Gigabyte RTX 4080 Super Aero

 

Nikon D500 | Nikon 300mm f/4 PF  | Nikon 200-500 f/5.6 | Nikon 50mm f/1.8 | Tamron 70-210 f/4 VCII | Sigma 10-20 f/3.5 | Nikon 17-55 f/2.8 | Tamron 90mm F2.8 SP Di VC USD Macro | Neewer 750II

Link to post
Share on other sites

15 hours ago, Fetzie said:

-- snip --

Thanks!! That nearly does everything I require (I will test it later).

 

Would you happen to know how to make it repeat every 15 seconds? I'm looking into the 'watch' command but I don't know if that will work properly. If Asterisk takes longer than 15 seconds to restart, will the watch command wait until that it completed or will it ignore it and continue to loop. 

 

Also when the server boots and the script starts to run, it may be able to change the IP in the file however it won't be able to restart Asterisk because Asterisk doesn't start until about 10 minutes after the server is up. Will the script care about the output when it issues the restart command or will it ignore it? (So will it not care if it gets an error or will it freeze the script)

CPU: 8320, GPU: 7870 Myst, Motherboard: Asrock 970 extreme3, PSU: XFX Pro 650W, RAM: 8GB Corsair Vengeance 1600Mhz, Case: Zalman Z11

Link to post
Share on other sites

8 minutes ago, Samwell said:

Thanks!! That nearly does everything I require (I will test it later).

 

Would you happen to know how to make it repeat every 15 seconds? I'm looking into the 'watch' command but I don't know if that will work properly. If Asterisk takes longer than 15 seconds to restart, will the watch command wait until that it completed or will it ignore it and continue to loop. 

 

Also when the server boots and the script starts to run, it may be able to change the IP in the file however it won't be able to restart Asterisk because Asterisk doesn't start until about 10 minutes after the server is up. Will the script care about the output when it issues the restart command or will it ignore it? (So will it not care if it gets an error or will it freeze the script)

Why do you need it to run every 15 seconds? The command 'restart gracefully' tells asterisk to restart when all calls are finished (i.e. when sip show channels returns no result). The script issues the command to Asterisk and exits (in programming terms, the script thread isn't blocked until asterisk restarts).

 

You can set the script to run as a cron job (highest frequency every 60 seconds) and have the script exit before issuing the restart command if the IP hasn't changed

 


if [ condition ]; then

     exit 0

fi

 

depending on the linux you'll either put the cron job in /etc/cron.d/ or /etc/cron.minute/ (google how to set up cron jobs, gnu.org has a good article about it).

AMD Ryzen 7800 X3D, MSI B650 Project Zero, Antec C5, Gigabyte RTX 4080 Super Aero

 

Nikon D500 | Nikon 300mm f/4 PF  | Nikon 200-500 f/5.6 | Nikon 50mm f/1.8 | Tamron 70-210 f/4 VCII | Sigma 10-20 f/3.5 | Nikon 17-55 f/2.8 | Tamron 90mm F2.8 SP Di VC USD Macro | Neewer 750II

Link to post
Share on other sites

1 hour ago, Fetzie said:

-- snip --

It needs to run frequently because when the public IP changed I want it to pick that up ASAP (I thought 15 seconds would be OK). The server is on 24/7 and if my IP changes every few days (I don't know how often it actually changes), I need it to pick that up and update it automatically. Running it once on startup wouldn't work because it will only be started once every few weeks, so I need it to check periodically.

CPU: 8320, GPU: 7870 Myst, Motherboard: Asrock 970 extreme3, PSU: XFX Pro 650W, RAM: 8GB Corsair Vengeance 1600Mhz, Case: Zalman Z11

Link to post
Share on other sites

1 hour ago, Fetzie said:

-- snip --

When running the sid command, it does this:

If the variable is set like this first (I manually change it in the conf) - public_ip=25.25.25.25

Then run the script, it changes it to this - public_ipnewip25.25.25.25

 

So it removes the '=', puts the new IP against the variable name and then the old IP right after

CPU: 8320, GPU: 7870 Myst, Motherboard: Asrock 970 extreme3, PSU: XFX Pro 650W, RAM: 8GB Corsair Vengeance 1600Mhz, Case: Zalman Z11

Link to post
Share on other sites

2 minutes ago, Samwell said:

When running the sid command, it does this:

If the variable is set like this first (I manually change it in the conf) - public_ip=25.25.25.25

Then run the script, it changes it to this - public_ipnewip25.25.25.25

 

So it removes the '=', puts the new IP against the variable name and then the old IP right after

And if you run the command outside of the script? What is the exact command that you're running?

AMD Ryzen 7800 X3D, MSI B650 Project Zero, Antec C5, Gigabyte RTX 4080 Super Aero

 

Nikon D500 | Nikon 300mm f/4 PF  | Nikon 200-500 f/5.6 | Nikon 50mm f/1.8 | Tamron 70-210 f/4 VCII | Sigma 10-20 f/3.5 | Nikon 17-55 f/2.8 | Tamron 90mm F2.8 SP Di VC USD Macro | Neewer 750II

Link to post
Share on other sites

This is the script so far - 

 

#!/bin/bash
while :
do
        myIP=$(dig +short myip.opendns.com @resolver1.opendns.com)
        extIPSetting=$(cat /etc/asterisk/unistim.conf | grep public_ip)
        echo ${extIPSetting}
        eval ${extIPSetting}
        extIpFromFile=${public_ip}
        if [ "${extIpFromFile}" != "${myIP}" ]; then
                sed -i "s/externalip=${extIpFromFile}/externalip=${myIP}/g" /etc/asterisk/unistim.conf
                asterisk -rx"restart gracefully"
        fi
sleep 15
done

 

34 minutes ago, Fetzie said:

-s-

 

CPU: 8320, GPU: 7870 Myst, Motherboard: Asrock 970 extreme3, PSU: XFX Pro 650W, RAM: 8GB Corsair Vengeance 1600Mhz, Case: Zalman Z11

Link to post
Share on other sites

It seems to be working now. I think the problem was, there was a comment after the variable that explained what the variable did. I moved that to the next line and now the script is working. It turns out I don't need to restart Asterisk to get the new unistim.conf to register, I just need to load it again (it doesn't take effect until a new call is made though). I'll have to see how this goes. It'll be interesting to see what happens if my ISP issues me a new IP during a call but I think the chances of that happening are pretty small. For anyone interested, here is the final working code - 

 

#!/bin/bash
while :
do
        myIP=$(dig +short myip.opendns.com @resolver1.opendns.com)
        extIPSetting=$(cat /etc/asterisk/unistim.conf | grep public_ip)
        eval ${extIPSetting}
        extIpFromFile=${public_ip}
        if [ "${extIpFromFile}" != "${myIP}" ]; then
                sed -i "s/public_ip=${extIpFromFile}/public_ip=${myIP}/g" /etc/asterisk/unistim.conf
                asterisk -rx"unistim reload"
        fi
sleep 15
done

@Fetzie Thank you very much for your help, it's greatly appreciated :)

CPU: 8320, GPU: 7870 Myst, Motherboard: Asrock 970 extreme3, PSU: XFX Pro 650W, RAM: 8GB Corsair Vengeance 1600Mhz, Case: Zalman Z11

Link to post
Share on other sites

17 minutes ago, Samwell said:

It seems to be working now. I think the problem was, there was a comment after the variable that explained what the variable did. I moved that to the next line and now the script is working. It turns out I don't need to restart Asterisk to get the new unistim.conf to register, I just need to load it again (it doesn't take effect until a new call is made though). I'll have to see how this goes. It'll be interesting to see what happens if my ISP issues me a new IP during a call but I think the chances of that happening are pretty small. For anyone interested, here is the final working code - 

 


#!/bin/bash
while :
do
        myIP=$(dig +short myip.opendns.com @resolver1.opendns.com)
        extIPSetting=$(cat /etc/asterisk/unistim.conf | grep public_ip)
        eval ${extIPSetting}
        extIpFromFile=${public_ip}
        if [ "${extIpFromFile}" != "${myIP}" ]; then
                sed -i "s/public_ip=${extIpFromFile}/public_ip=${myIP}/g" /etc/asterisk/unistim.conf
                asterisk -rx"unistim reload"
        fi
sleep 15
done

@Fetzie Thank you very much for your help, it's greatly appreciated :)

I was wondering what could be the matter, because there is no way that you could get the string "newIp" in the line of the config file with that command :) Glad to see you worked it out. I personally wouldn't have the script running in an infinite loop 24/7 (but I guess if it works for you then that's the main thing and this short script won't really use much system resources anyway).

 

Happy to help :)

AMD Ryzen 7800 X3D, MSI B650 Project Zero, Antec C5, Gigabyte RTX 4080 Super Aero

 

Nikon D500 | Nikon 300mm f/4 PF  | Nikon 200-500 f/5.6 | Nikon 50mm f/1.8 | Tamron 70-210 f/4 VCII | Sigma 10-20 f/3.5 | Nikon 17-55 f/2.8 | Tamron 90mm F2.8 SP Di VC USD Macro | Neewer 750II

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×