Tuesday, August 31, 2010

Monitor Asterisk calls using SNMP

Monitor calls in asterisk using Cacti or MRTG.

Requirements:
1) install net-snmp on linux
2) recompile asterisk. make sure res_snmp in resource module is enabled

#make menuselect

[*] 13. res_odbc
[*] 14. res_smdi
[*] 15. res_snmp
[*] 16. res_speech

3) install asterisk

4) configure asterisk and enable snmp.

# vi /etc/asterisk/res_snmp.conf

[general]
subagent = yes
enabled = yes

5) enable snmpd on linux

# vi /etc/snmp/snmpd.conf

# First, map the community name (COMMUNITY) into a security name
# (local and mynetwork, depending on where the request is coming
# from):

# sec.name source community
com2sec mymrtg 192.168.1.10 MyCOMMUNITY
com2sec mymrtg 192.168.1.11 MyCOMMUNITY
com2sec mymrtg localhost MyCOMMUNITY

####
# Second, map the security names into group names:

# sec.model sec.name
group networkmon v1 mymrtg
group networkmon v2c mymrtg
group networkmon usm mymrtg
group networkmon local mymrtg

####
# Third, create a view for us to let the groups have rights to:

# incl/excl subtree mask
view all included .iso

####
# Finally, grant the group access
# context sec.model sec.level match read write notif
access networkmon "" any noauth exact all none none


# Asterisk configuration
master agentx
agentXSocket /var/agentx/master
agentXPerms 0660 0550 nobody asterisk

6) copy asterisk MIB files to snmp mib directory

# cp doc/asterisk-mib.txt /usr/share/snmp/mibs
# cp doc/digium-mib.txt /usr/share/snmp/mibs

7) restart snmpd and set agentx permission

# /etc/init.d/snmpd restart
# chmod 755 /var/agentx

8) restart asterisk

# amportal restart <-- if you are using freepbx to start asterisk

9) Test it locally

# export MIBS=+ASTERISK-MIB
# snmpwalk -c MyCOMMUNITY -v 1 localhost asterisk

10) You can use the OID equivalant if you want.

# MIB equivalent (Asterisk 1.4.22 version)
ASTERISK-MIB::astChanTypeName.1 = STRING: Phone
ASTERISK-MIB::astChanTypeName.2 = STRING: Local
ASTERISK-MIB::astChanTypeName.3 = STRING: IAX2
ASTERISK-MIB::astChanTypeName.4 = STRING: Skinny
ASTERISK-MIB::astChanTypeName.5 = STRING: SIP <---- SIP MIB ID
ASTERISK-MIB::astChanTypeName.6 = STRING: MGCP
ASTERISK-MIB::astChanTypeName.7 = STRING: DAHDI
ASTERISK-MIB::astChanTypeName.8 = STRING: Agent
ASTERISK-MIB::astChanTypeName.9 = STRING: OOH323

ASTERISK-MIB::astChanTypeChannels.1 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.2 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.3 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.4 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.5 = Gauge32: 0 <---- SIP channel value
ASTERISK-MIB::astChanTypeChannels.6 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.7 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.8 = Gauge32: 0
ASTERISK-MIB::astChanTypeChannels.9 = Gauge32: 0

# Get OID equivalent
# snmpwalk -On -c MyCOMMUNITY -v 1 localhost ASTERISK-MIB::astChanTypeChannels.5

.1.3.6.1.4.1.22736.1.5.4.1.7.5 = Gauge32: 0 <---- oid that can be used in cacti


11) open cacti and use the generic snmp template for the device
you want to create the graph for, then define the OID. Same method applies
for mrtg users.

Wednesday, August 25, 2010

Asterisk clock source

You may need to change your Linux server's clock source in order for
Asterisk's conference bridge to perform properly.

Requirements: Asterisk 1.4 and Dahdi

1) First verify what clock sources are available in Linux.
#cat /sys/devices/system/clocksource/clocksource0/available_clocksource

acpi_pm jiffies tsc pit

2) Some distributions may have hpet (newer kernels). Set the clock source
to next best thing, "acpi_pm". Edit grub.conf and insert the following:

clocksource=acpi_pm

Here's an example.

# cat /etc/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
# initrd /initrd-version.img
#boot=/dev/hda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-92.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-92.el5 ro root=/dev/VolGroup00/LogVol00 clocksource=acpi_pm
initrd /initrd-2.6.18-92.el5.img

3) Reboot your server. In my case, starting asterisk before dahdi produced
more accurate measurements. I'm using old Intel P4 servers, 3.0Ghz CPU / 1G Ram.

4) Verify your new setting.

# cat /sys/devices/system/clocksource/clocksource0/current_clocksource

5) Use the dahdi_test command to measure the accuracy.

# dahdi_test
Opened pseudo dahdi interface, measuring accuracy...
99.950882% 99.961235% 99.948433% 99.956535% 99.948242% 99.956253% 99.956741%

Before, I had 99.8s and 99.9s. Now it's all 99.9s

Tuesday, August 3, 2010

Chillispot on DD-WRT and remote radius / https server for authentication

This will force users to login (via a captive portal web-page).

Info:

From a previous blog, we used chillispot on a server which
served as our router and captive portal. Radius and Apache
were also installed on the same server.

This time, we will use DD-WRT which is installed on our access
point. DD-WRT has chillispot built-in. Our radius and http services
will remain on the Linux server. This scenario configures chillispot
to authenticate clients (Wireless or Wired) from a remote server.

Same as before, chillispot on DD-WRT creates the virtual tunnel and
other processes as it does on the Linux server. It directs
unauthenticated users to the remote https and radius server.

Again, the steps to be done are the same when you configure radius,
apache and chillispot on CentOS 5. This time, chillispot is not on
the server but on the access point.

1) Install, configure apache to support SSL and update the
hotspotlogin.cgi script
2) Install Radius and update all user and password required
3) Enable chillispot on DD-WRT and supply the required parameters:

uamserver / redirect https://192.168.182.1/cgi-bin/hotspotlogin.cgi
uamsecret ht2eb8ej6s4et3rg1ulp

4) By default, chillispot uses 192.168.182.0/24 as its dhcp range.
You can change this under the "hotspot" menu and supply another
ip range at the "remote network" field. Try putting
192.168.185.0/24 renew your laptop's address.

Friday, July 30, 2010

Install ChilliSpot on CentOS 5

This will force users to login (via a captive portal web-page).

Info:

eth0 = WAN
eth1 = Internal Interface / LAN (Clients, PC, Access Points)

Chillispot takes control of (eth1) using a vtun kernel module
to bring up a virtual interface (tun0). The vtun kernel module
is used to move IP packets from the kernel to user mode

Chillispot sets up a DHCP server (can be disabled from the
chillispot conf file) on the tun0 interface.

A client connecting to internal interface has all packets rejected
until it is authorized though the chillispot login page (acting as
a supplicant for authentication). When a non-authenticated client
tries to connect to a web-page (on port 80 or 443) the request is
intercepted by chilli and redirected to a perl-script called
hotspotlogin.cgi (served by apache over https).

hotspotlogin.cgi serves a page to the end-user with a username and
password field. These authentication data are then forwarded to the
freeradius server, which matches them with information in it’s backend
(using either PAP or CHAP). The backend in this case is mysql, but
could be any number of services such as LDAP, Kerberos, unix passwd
files or even Active Directory (probably).

A user is then either rejected or authenticated by freeradius,
prompting hotspotlogin.cgi to present either a rejection message
or a page with a success message and a logout link to the user.


-------You need to install the following packages:
* mysql-server
* apache2
* freeradius
* freeradius-mysql


-------You need to enable packet forwarding:
Edit /etc/sysctl.conf and set net.ipv4.ip_forward = 1


-------Install chillispot from http://chillispot.org/download.html

1) Copy hotspotlogin.cgi from source to /var/www/cgi-bin directory
2) Copy chillispot-pf.conf from source to /etc/pf.conf
3) Edit /etc/pf.conf and update int & ext_if macros
4) Copy chilli.conf & chilli.ipup from source to /etc
5) Tell Chilli about the location of the authentication server
(which in this scenario is on the same machine as chillispot).
This is done by uncommenting and editing the following line in
“/etc/chilli.conf”:

uamserver https://192.168.182.1/cgi-bin/hotspotlogin.cgi

192.168.182.1 is the default IP address that chillispot gives
the tun0 interface.

6) For added password security, we need to add a shared secret
between the hotspotlogin.cgi and chilli. Find the line in
“/etc/chilli.conf” that reads

#uamsecret ht2eb8ej6s4et3rg1ulp

Uncomment this line (remove the #) and CHANGE the secret to
what ever you desire. The secret needs to be the same with the
hotspotlogin.cgi script.

Continue editing /etc/chilli.conf and update the dns, dhcpif
& other parameters.

Edit the hotspotlogin.cgi in your cgi-bin directory & update
the uamsecret so that its the same as the entry in your
/etc/chilli.conf. Also uncomment the line that reads:
#$userpassword=1;

7) chmod 755 /var/www/cgi-bin/hotspotlogin.cgi
8) Copy chilli.init from source to /etc/rc.d/init.d/chilli
Edit /etc/rc.d/init.d/chilli and Define the correct path
for the chilli binary


-------You need to configure the network interfaces.
1) Set eth0 for internet connection.
2) Set eth1 with address 0.0.0.0 255.255.255.0
or issue command: ifconfig eth1 0.0.0.0 up
3) Check that both interfaces are physically connected
to the appropriate network equipment


-------Configuring Apache2 for SSL
1) yum install mod_ssl
2) mkdir /etc/httpd/ssl
3) openssl req -new -x509 -days 365 -nodes -out \
/etc/httpd/ssl/httpd.pem -keyout /etc/httpd/ssl/httpd.key

4) Edit http.conf and enable ssl

NameVirtualHost *:443


SSLEngine On
SSLCertificateFile /etc/httpd/ssl/httpd.pem
SSLCertificateKeyFile /etc/httpd/ssl/httpd.key

#ServerAdmin info@mydomain.com
#ServerName www.mydomain.com
#DocumentRoot /srv/www/mydomain.com/public_html/
#ErrorLog /srv/www/mydomain.com/logs/error.log
#CustomLog /srv/www/mydomain.com/logs/access.log combined



-------Configure radius
1) Edit “/etc/raddb/clients.conf”.
Find the section that contains the line
client 127.0.0.1 {

make sure it is uncommented, and then, in the section between the
{ and the following }, change the following lines:

secret = testing123

change testing123 to match the radiussecret you chose for
“/etc/chilli.conf”


2) Edit “/etc/raddb/users”
Uncomment the following line in the file
#steve Auth-Type := Local, User-Password == “testing”
This will be the test user and password we will use to make sure
everything works.


-------Copy firewall.iptables from source to /etc/rc.d/init.d/chilli.iptables


-------Start the firewall
sh /etc/rc.d/init.d/chilli.iptables


-------Restart services
/etc/rc.d/init.d/httpd restart
/etc/rc.d/init.d/radiusd restart
/etc/rc.d/init.d/chilli restart


;notes

Thank this site for the information above:
http://www.multiplicity.dk/2006/10/chillispot-howto/

Wednesday, July 28, 2010

Query a database from Asterisk Part 2

This simple example resembles a feature, which might be used by credit card companies, where a user may inquire about recent payments.


Here are the configurations:
------------------------------------------------

;Create the database "odbc_finance_bank"
;Create table "finance_bank_members" with the information below

+------------------+----------+---------------------+--------------------+
| account_number | pin_code | recent_payment_date | recent_paid_amount |
+------------------+----------+---------------------+--------------------+
| 5111300001 | 1234 | 2010-05-16 19:23:00 | 5003.12 |
| 5222300002 | 5678 | 2010-06-22 10:09:00 | 9800.00 |
+------------------+----------+---------------------+--------------------+


;Edit configuration files
------------------------------------------------
;cat /etc/odbcinst.ini

[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/libmyodbc3.so
Setup = /usr/lib/libodbcmyS.so
FileUsage = 1

------------------------------------------------
;cat /etc/odbc.ini

[astodbc]
Description = Retrieve names and extensions
Driver = MySQL
Server = localhost
Port = 3306
USER = dbuser
Password = dbpassword
Database = odbc_finance_bank
Option = 3

------------------------------------------------
;cat /etc/asterisk/res_odbc.conf

[getuserinfo]
enabled => yes
dsn => astodbc
username => dbuser
password => dbpassword
pre-connect => yes

------------------------------------------------
;cat /etc/asterisk/func_odbc.conf

[GETDATE]
dsn=getuserinfo
read=SELECT recent_payment_date FROM finance_bank_members WHERE account_number='${SQL_ESC(${ARG1})}' and pin_code='${SQL_ESC(${ARG2})}';

[GETAMOUNT]
dsn=getuserinfo
read=SELECT recent_paid_amount FROM finance_bank_members WHERE account_number='${SQL_ESC(${ARG1})}' and pin_code='${SQL_ESC(${ARG2})}';

------------------------------------------------
;cat /etc/asterisk/extensions_custom.conf

[from-internal-custom]
; Account Transactions

; answer incoming
exten => 1000,1,answer
exten => 1000,n,wait(1)

; enter account number
exten => 1000,n,Playback(after-the-tone)
exten => 1000,n,Playback(please-enter-your)
exten => 1000,n,Playback(digits/10)
exten => 1000,n,Playback(astcc-digit-account-number)
exten => 1000,n,Playback(beep)
exten => 1000,n(getacctnum),read(account_number,,10,,3,15)

;confirm account number
exten => 1000,n,Playback(you-entered)
exten => 1000,n,Playback(silence/1)
exten => 1000,n,SayDigits(${account_number})
exten => 1000,n,Playback(silence/1)
exten => 1000,n,Playback(if-this-is-correct)
exten => 1000,n,Playback(press-1)
exten => 1000,n(acctverify),read(account_verify,,1,,3,5)
exten => 1000,n,GotoIf($[${account_verify} = 1]?getpincode:goodbye)

; enter pin code
exten => 1000,n(getpincode),Playback(please-enter-your)
exten => 1000,n,read(pin_code,access-code,4,,3,10)

; hangup if no data
exten => 1000,n,Set(recentdate=${ODBC_GETDATE(${account_number},${pin_code})})
exten => 1000,n,GotoIf($["${recentdate}" = ""]?tryagain:)

; if data present, format date
; recentdate format: 1976-12-16 07:30:35
exten => 1000,n,Set(formatdate=${STRPTIME(${recentdate}|Asia/Manila|%Y-%m-%d %H:%M:%S})

exten => 1000,n,Playback(received)
exten => 1000,n,SayUnixTime(${formatdate})
exten => 1000,n,Set(recentamount=${ODBC_GETAMOUNT(${account_number},${pin_code})})
exten => 1000,n,SayNumber(${recentamount})
exten => 1000,n,Playback(digits/dollars)
exten => 1000,n,Set(centavo=${CUT(recentamount,.,2)})
exten => 1000,n,Playback(and)
exten => 1000,n,SayNumber(${centavo})
exten => 1000,n,Playback(cents)

exten => 1000,n,Playback(silence/3)
exten => 1000,n(goodbye),Playback(goodbye)
exten => 1000,n,hangup()

exten => 1000,n,Playback(silence/3)
exten => 1000,n(tryagain),Playback(login-fail)
exten => 1000,n,Playback(please-try-again)
exten => 1000,n,Playback(goodbye)
exten => 1000,n,hangup()

Friday, July 23, 2010

Managing Cisco ATA 186

1) Reset the ATA to default configuration:
Power on ATA and insert an analog unit at "Phone 1" on the back
- Pick up handset
- Press red button to access the configuration menu
- You will hear "configuration menu"
- Enter: 322873738#
- You will hear "to save press star, or press the pound key"
- Press "*"
- Red light flashes. ATA is now at default configuration

2) Check the ATA's IP address (DHCP enabled):
- Access the configuration menu
- Type 80#

3) Change the ATA's IP address (DHCP disabled):
- Access the configuration menu
- Disable DHCP by entering:
20# 0# 3
1# 172*16*10*70 #3 - set IP address

10# 255*255*255*0 #3 - set mask

28# 172*16*10*1 - set default gateway
- Hang up the phone, device will reset with new IP address

Thursday, July 22, 2010

Query a database from Asterisk

; Define MySQL ODBC modules
; edit /etc/odbcinst.ini
[MySQL]
Description = ODBC for MySQL
Driver = /usr/lib/libmyodbc3.so
Setup = /usr/lib/libodbcmyS.so
FileUsage = 1

; edit /etc/odbc.ini
[astodbc]
Description = Retrieve names and extensions
Driver = MySQL
Server = localhost
Port = 3306
USER = astconnector
Password = astpasskey
Database = astodbc
Option = 3

; prepare asterisk for odbc connection
; asterisk will use res_odbc.conf information to connect to MySQL
; edit /etc/asterisk/res_odbc.conf
[sqlconnect]
enabled => yes
dsn => astodbc
username => astconnector
password => astpasskey
pre-connect => yes

; prepare the sql query commands that asterisk will initiate
; edit /etc/asterisk/func_odbc.conf
[GETUSERINFO]
dsn=sqlconnect
read=SELECT id_firstname, id_middlename, id_lastname, age, sex, location FROM client_db WHERE ext_number='${SQL_ESC(${ARG1})}'

; define extensions that connect to MySQL
; Festival needs to be configured prior to this
/etc/asterisk/extensions_custom.conf
[from-internal-custom]
exten => 5000,1,answer
exten => 5000,n,wait(1)
; get user input (ext_number)
exten => 5000,n(getextension),read(keyext,extension,4,,,10)
; say user input
exten => 5000,n,Festival(${keyext})
; retrieve information from odbc query in func_odbc.conf
exten => 5000,n,Set(myinfo=${ODBC_GETUSERINFO(${keyext})})
; say user information
exten => 5000,n,Festival(${myinfo})
exten => 5000,n,Playback(silence/3)
; ask for another input
exten => 5000,n,Goto(getextension)
exten => 5000,n,hangup()

sample sql table
select * from client_db ;
+----------+--------------+---------------+-------------+------------+-----+------+-----------+---------------------+
| uniqueid | id_firstname | id_middlename | id_lastname | ext_number | age | sex | location | stamp |
+----------+--------------+---------------+-------------+------------+-----+------+-----------+---------------------+
| 101 | John | Michael | Price | 4010 | 23 | male | home | 2010-03-12 03:30:42 |
| 103 | Joseph | Edward | Smith | 4020 | 25 | male | office | 2010-03-12 03:30:44 |
+----------+--------------+---------------+-------------+------------+-----+------+-----------+---------------------+

ViciDial - Number scrubbing / Call list washing

# Get CPD results from Campaigns
# CAMP1 - Campaign 1 name
# CAMP2 - Campaign 2 name
# List ID "537" - Number list common to both CAMP1 and CAMP2

# Run ViciDial with Sangoma Netborder support
# Then prepare to query the ViciDial database for CPD results

# Create table for CAMP1
create table scrubber_result_x_CAMP1 TYPE=MYISAM AS
select campaign_id, lead_id, list_id, term_reason, call_date,
length_in_sec as duration, phone_number, status from vicidial_log
where campaign_id = 'CAMP1' order by lead_id ASC;

# Add CPD column
alter table scrubber_result_x_CAMP1 add column cpd varchar(32);
update scrubber_result_x_CAMP1 set cpd = '' where cpd is null;

# Update CPD column
update scrubber_result_x_CAMP1 AS t1, vicidial_cpd_log AS t2
set t1.cpd = t2.result where t1.lead_id = t2.lead_id;

# OPTIONAL - Set NA for those w/o CPD results
update scrubber_result_x_CAMP1 set cpd = 'NA' where cpd = '';

# --------------------

# Create table for CAMP2
create table scrubber_result_x_CAMP2 TYPE=MYISAM AS
select campaign_id, lead_id, list_id, term_reason, call_date,
length_in_sec as duration, phone_number, status from vicidial_log
where campaign_id = 'CAMP2' order by lead_id ASC;

# Add CPD column
alter table scrubber_result_x_CAMP2 add column cpd varchar(32);
update scrubber_result_x_CAMP2 set cpd = '' where cpd is null;

# Update CPD column
update scrubber_result_x_CAMP2 AS t1, vicidial_cpd_log AS t2
set t1.cpd = t2.result where t1.lead_id = t2.lead_id;

# OPTIONAL - Set NA for those w/o CPD results
update scrubber_result_x_CAMP2 set cpd = 'NA' where cpd = '';

# --------------------

# Create comparison of two Campaigns (CAMP1 and CAMP2)

# Create Comparison table
create table scrubber_result_list_CAMP_COMPARISON TYPE=MYISAM AS
select lead_id, list_id, phone_number from vicidial_list
where list_id = '537' order by lead_id ASC;

# Add CPD column
alter table scrubber_result_list_CAMP_COMPARISON add column cpd varchar(32);
alter table scrubber_result_list_CAMP_COMPARISON add column cpd2 varchar(32);
update scrubber_result_list_CAMP_COMPARISON set cpd = '' where cpd is null;
update scrubber_result_list_CAMP_COMPARISON set cpd2 = '' where cpd2 is null;

# Update CPD column (lookup phone then update cpd)
update scrubber_result_list_CAMP_COMPARISON AS t1, scrubber_result_x_CAMP1 AS t2
set t1.cpd = t2.cpd where t1.phone_number = t2.phone_number;

update scrubber_result_list_CAMP_COMPARISON AS t1, scrubber_result_x_CAMP2 AS t2
set t1.cpd2 = t2.cpd where t1.phone_number = t2.phone_number;

update scrubber_result_list_CAMP_COMPARISON set cpd = 'NA' where cpd = '';
update scrubber_result_list_CAMP_COMPARISON set cpd2 = 'NA' where cpd2 = '';

select * from scrubber_result_list_CAMP_COMPARISON;

Monday, July 19, 2010

Backup and Restore Asterisk, FreePBX, MySQL, HTTP

;Required:
1) Make sure you have the same version of source files used to
install Asterisk, FreePBX, MySQL and Apache
2) Modify the file path if needed


;;;;Backup Script
#!/bin/sh
NOW=$(date +"%m-%d-%Y-%H%M%S")
#mkdir /root/ast-backup-$NOW
tar -zcvf /root/ast-backup-$NOW/etc-amportal-$NOW.tar.gz /etc/amportal.conf ;
tar -zcvf /root/ast-backup-$NOW/etc-asterisk-$NOW.tar.gz /etc/asterisk ;
tar -zcvf /root/ast-backup-$NOW/var-lib-asterisk-$NOW.tar.gz /var/lib/asterisk ;
tar -zcvf /root/ast-backup-$NOW/var-lib-mysql-$NOW.tar.gz /var/lib/mysql ;
tar -zcvf /root/ast-backup-$NOW/var-spool-asterisk-$NOW.tar.gz /var/spool/asterisk ;
tar -zcvf /root/ast-backup-$NOW/var-www-html-$NOW.tar.gz /var/www/html ;


;;;;Restore Script
#!/bin/sh
NOW=$(date +"%m-%d-%Y-%H%M%S")
######## ------- Configuration / DB restore steps -------
######## BACKUP EXISTING and RESTORE /etc/asterisk
mv /etc/asterisk /etc/asterisk.$NOW
cd /usr/local/src/postinstall/config_files/etc
cp -R asterisk /etc
chown -R asterisk.asterisk /etc/asterisk
cp amportal.conf /etc

######## RESTORE Directories
mv /var/www/html/admin /var/www/html/admin.$NOW
mv /var/www/html/myqueue /var/www/html/myqueue.$NOW
mv /var/www/html/panel /var/www/html/panel.$NOW
mv /var/www/html/recordings /var/www/html/recordings.$NOW

cp -R /usr/local/src/postinstall/config_files/var/www/html/* /var/www/html
chown -R asterisk.asterisk /var/www/html

mv /var/lib/mysql /var/lib/mysql.$NOW
cp -R /usr/local/src/postinstall/config_files/var/lib/mysql /var/lib
chown -R mysql.mysql /var/lib/mysql

mv /etc/asterisk /etc/asterisk.$NOW
cp -R /usr/local/src/postinstall/config_files/etc/asterisk /etc
chown -R asterisk.asterisk /etc/asterisk

mv /var/lib/asterisk /var/lib/asterisk.$NOW
cp -R /usr/local/src/postinstall/config_files/var/lib/asterisk /var/lib
chown -R asterisk.asterisk /var/lib/asterisk

mv /var/spool/asterisk /var/spool/asterisk.$NOW
cp -R /usr/local/src/postinstall/config_files/var/spool/asterisk /var/spool
chown -R asterisk.asterisk /var/spool/asterisk

######## RESTART MYSQL and HTTPD Services
/etc/rc.d/init.d/httpd restart
/etc/rc.d/init.d/mysqld restart

Friday, May 7, 2010

Disconnect calls in cisco AS5400 gateways

;Disconnect calls in cisco AS5400 gateways
;IOS Version 12.4(25a)


:Method 1
;Inspect the as5400 for dead or stuck calls
gateway#show call active voice compact
A/O FAX T Codec type Peer Address IP R:
Total call-legs: 2
6970 ANS T164506 g711ulaw TELE P5000
6971 ORG T164506 g711ulaw VOIP P1000 192.168.1.2:18876
;T164506 = 164506 seconds (call duration)

;Look into the details of the call
gateway#show call activce voice brief
B03 : 6970 467365190ms.1 +2220 pid:1 Answer 5000 active
dur 1d21h tx:4584734/709292132 rx:8261947/1321911520
Tele 7/7:D (6970) [7/7.1] tx:165238945/368000/0ms g711ulaw
noise:-71 acom:80 i/0:-56/-55 dBm

B03 : 6971 467365200ms.1 +2210 pid:2 Originate 1000 active
dur 1d21h tx:8261947/1321911520 rx:4584734/709292132
IP 192.168.1.2:18876 SRTP: off rtt:155ms pl:106228000/0ms
lost:0/205/0 delay:60/40/105ms g711ulaw
media inactive detected:n media contrl rcvd:n/a timestamp:n/a

;Disconnect the call
gateway#clear call voice causecode 10 id B03



;Method 2
gateway#show call active voice id B03
-------strip----------
OriginalCallingNumber=5000
OriginalCalledNumber=1000
TranslatedCallingNumber=5000
TranslatedCalledNumber=1000
GwReceivedCalledNumber=1000
GwReceivedCallingNumber=5000
DSPIdentifier=2/4:1
;The above indicate the calling/called number and dsp being used

;Inspect the spe
SPE# Port # State Busyout Shut Crash State Type
2/03 0018-0023 ACTIVE 0 0 0 ______ ______
2/04 0024-0029 ACTIVE 0 0 0 _a____ _v____

;Disconnect the call
gateway#clear spe 2/04
;This will clear all calls within 2/04 spe

Asterisk custom context

Asterisk 1.4.22 / Freepbx 2.5 - Create custom contexts and extensions

Why create a different context other than the default?
Contexts allow us to partition peers and extensions, creating
dial policies for individials or groups.

For example, in a corporate office, you may want regular
employees to only reach HR department extensions, while
HR personnel are allowed to reach everyone (billing deparment,
regular employees..etc)

Freepbx's default context used by internal extensions are
"from-internal" and "from-internal-custom". The latter
is used to include custom contexts. This means that any user
under the "from-internal" context can reach our custom context
but not the other way around.

; Here's our example
; sip_additional.conf ----------------------------
; All extensions were added using freepbx's gui.
; This makes configuration, enabling features easier (Recording, VM..etc)
; Take note that we applied the appropriate contexts for each.

[1001]
;regular employee
type=friend
secret=ext1001
qualify=yes
port=5060
nat=yes
mailbox=1001@device
host=dynamic
dtmfmode=rfc2833
dial=SIP/1001
context=from-internal-employee
canreinvite=no
callerid=device <1001>
call-limit=50

[2001]
;HR
type=friend
secret=ext2001
qualify=yes
port=5060
nat=yes
mailbox=2001@device
host=dynamic
dtmfmode=rfc2833
dial=SIP/2001
context=from-internal
canreinvite=no
callerid=device <2001>
call-limit=50

[3001]
;billing department
type=friend
secret=ext3001
qualify=yes
port=5060
nat=yes
mailbox=3001@device
host=dynamic
dtmfmode=rfc2833
dial=SIP/3001
context=from-internal
canreinvite=no
callerid=device <3001>
call-limit=50

;extensions_custom.conf ----------------------------

[from-internal-custom]
;enables call transfer to PSTN using the sip client's features
;not the freepbx internal transfer function
include => from-internal-employee-pstn

;for regular employees, create main and sub context:
;put local extension routes under their main context
;place outbound PSTN routes under their main context's subcontext

[from-internal-employee]
;regular employee extensions
include => from-internal-employee-pstn
exten => _100X,1,Macro(user-callerid)
exten => _100X,n,Macro(record-enable,${AMPUSER},OUT,)
exten => _100X,n,Dial(Local/${EXTEN}@from-internal/n)
exten => _100X,n,Hangup

[from-internal-employee-pstn]
;regular employee pstn routes
exten => _1XXXXXXXXXX,1,Macro(user-callerid)
exten => _1XXXXXXXXXX,n,Macro(record-enable,${AMPUSER},OUT,)
exten => _1XXXXXXXXXX,n,Dial(SIP/pstn-gw/${EXTEN})
exten => _1XXXXXXXXXX,n,Hangup


;The macros used here are internal to freepbx and should be
;used to provide known system features to these custom routes
;(call recording, caller id passing, voicemail..etc
;
;Macro(record-enable,${AMPUSER},OUT,)
;Macro(user-callerid)
;Dial(Local/${EXTEN}@from-internal/n)

;Since HR needs both access to regular employees and billing,
;we only need to create HR extensions in freepbx with a
;default context.


Asterisk 1.4.22 / Freepbx 2.5 - Create custom contexts and extensions


Why create a different context other than the default?
Contexts allow us to partition peers and extensions, creating
dial policies for individials or groups.

For example, in a corporate office, you may want regular
employees to only reach HR department extensions, while
HR personnel are allowed to reach everyone (billing deparment,
regular employees..etc)

Freepbx's default context used by internal extensions are
"from-internal" and "from-internal-custom". The latter
is used to include custom contexts. This means that any user
under the "from-internal" context can reach our custom context
but not the other way around.

; Here's our example
; sip_additional.conf ----------------------------
; All extensions were added using freepbx's gui.
; This makes configuration, enabling features easier (Recording, VM..etc)
; Take note that we applied the appropriate contexts for each.

[1001]
;regular employee
type=friend
secret=ext1001
qualify=yes
port=5060
nat=yes
mailbox=1001@device
host=dynamic
dtmfmode=rfc2833
dial=SIP/1001
context=from-internal-employee
canreinvite=no
callerid=device <1001>
call-limit=50

[2001]
;HR
type=friend
secret=ext2001
qualify=yes
port=5060
nat=yes
mailbox=2001@device
host=dynamic
dtmfmode=rfc2833
dial=SIP/2001
context=from-internal
canreinvite=no
callerid=device <2001>
call-limit=50

[3001]
;billing department
type=friend
secret=ext3001
qualify=yes
port=5060
nat=yes
mailbox=3001@device
host=dynamic
dtmfmode=rfc2833
dial=SIP/3001
context=from-internal
canreinvite=no
callerid=device <3001>
call-limit=50

;extensions_custom.conf ----------------------------

[from-internal-custom]
;enables call transfer to PSTN using the sip client's features
;not the freepbx internal transfer function
include => from-internal-employee-pstn

;for regular employees, create main and sub context:
;put local extension routes under their main context
;place outbound PSTN routes under their main context's subcontext

[from-internal-employee]
;regular employee extensions
include => from-internal-employee-pstn
exten => _100X,1,Macro(user-callerid)
exten => _100X,n,Macro(record-enable,${AMPUSER},OUT,)
exten => _100X,n,Dial(Local/${EXTEN}@from-internal/n)
exten => _100X,n,Hangup

[from-internal-employee-pstn]
;regular employee pstn routes
exten => _1XXXXXXXXXX,1,Macro(user-callerid)
exten => _1XXXXXXXXXX,n,Macro(record-enable,${AMPUSER},OUT,)
exten => _1XXXXXXXXXX,n,Dial(SIP/pstn-gw/${EXTEN})
exten => _1XXXXXXXXXX,n,Hangup


;The macros used here are internal to freepbx and should be
;used to provide known system features to these custom routes
;(call recording, caller id passing, voicemail..etc
;
;Macro(record-enable,${AMPUSER},OUT,)
;Macro(user-callerid)
;Dial(Local/${EXTEN}@from-internal/n)

;Since HR needs both access to regular employees and billing,
;we only need to create HR extensions in freepbx with a
;default context.

Asterisk call recording using Ramdisk

Asterisk 1.4.22 / Freepbx 2.5 - Call recording using Ramdisk


Ramdisk is a portion of the computer's physical memory which
you can use to store files temporarily. Since memory is faster
than hard disk, ramdisk increases computer performance during
file operations.

We can set up asterisk to store ongoing call recordings in
ramdisk and then move these files to a permanent storage once
recording has finished.

In freepbx's general settings, you can assign a directory
for saving call recordings, "Recording Location:". We'll define
ramdisk as the destination folder.

Since ramdisk is a temporary storage, any files located in it
will be removed when the computer restarts. This is where the
"Run After Record" comes in handy. We can define a script to
move the recordings once asterisk has finished writing them.
Freepbx allows us to push asterisk arguments to the script,
which we can use to specify recording file names.

In this example, we set /temp_rec as our recording location.
This is our ramdisk. Do the following to create our
temporary storage.


;Specify how big is our ramdisk going to be.
;Do this in /etc/grub.conf
;ramdisk_size is in KB
;Here we are configured for 2GB
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.18-128.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-128.el5 ro root=/dev/VolGroup00/LogVol00 ramdisk_size=2000000
initrd /initrd-2.6.18-128.el5.img


;Put this in rc.local to create ramdisk during bootup
/sbin/mke2fs -m 0 /dev/ram0
/bin/mount /dev/ram0 /temp_rec
/bin/mkdir /temp_rec/monitor
/bin/mkdir /temp_rec/system
/bin/mkdir /temp_rec/tmp
/bin/chown -R asterisk.asterisk /temp_rec
;For more infor on ramdisk:
;http://www.vanemery.com/Linux/Ramdisk/ramdisk.html


;Link asterisk's default folders to our ramdisk
/bin/ln -s /temp_rec/system /var/spool/asterisk
/bin/ln -s /temp_rec/tmp /var/spool/asterisk
/bin/ln -s /temp_rec/monitor /var/spool/asterisk


;Create script move_recordings.sh
;nfs_disk is a nfs server
#! /bin/bash
# ARGUMENT INPUT ORDER ^{MIXMON_DIR} ^{CALLFILENAME} ^{MIXMON_FORMAT}
# MOVE EXTENSION RECORDINGS
/bin/mv $1/$2.$3 /nfs_disk


;Now the general settings should look like this:
Recording location:
/var/spool/asterisk/monitor/

Run after record:
/var/spool/asterisk/scripts/move_recordings.sh ^{MIXMON_DIR} ^{CALLFILENAME} ^{MIXMON_FORMAT}


;create nfs entries in fstab
;192.168.0.2 is our nfs server
192.168.0.2:/data/rec /nfs_disk nfs rw,soft,intr,bg,nolock,rsize=8192,wsize=8192,udp 0 0


Below are the figures and specifications I used to
test everything we've discussed.

Asterisk server:
Quad Xeon 2.40GHz
4GB RAM

Pjsip / Pjsua server - for emulating (multiple calls) 60 extensions
logged into asterisk's queue. You can set them to auto-answer,
automatically play audio and disconnect after 10 minutes.

Vicidial server - for conducting 60 simultaneous calls to asterisk
(with audio playing) and redialing each time pjsip extensions
disconnect (10 minutes). Vicidial made 500 calls during the test.

Asterisk with 60 simultaneous incoming calls being recorded for 10
minutes at any given time. Finishing off with 500 calls in total.

I used sync in crontab to clear the memory cache from
time to time. But it is best to put in additional physical
RAM if recording eats up more memory.

*/30 * * * * /bin/sync; echo 3 > /proc/sys/vm/drop_caches

Access List on a Cisco CUBE / SBC

;Access-list on a Cisco CUBE / SBC


A commonly used design is to put voip servers (callmanager, asterisk...etc)
behind the CUBE by using private addresses. With this set up, our voip
servers are secured from outside, non-trusted networks.

But how do we protect the cube? One of many ways is to put an ACL on its public
interface, only allowing voice traffic from trusted networks.

In this example, we have two interfaces, the public and private interfaces.
Our callmanager sits on the private network.


interface FastEthernet0/1
description callmanager and ip phone segment
ip address 192.168.0.1 255.255.255.0

interface FastEthernet0/1
description public interface
ip address 198.198.198.1 255.255.255.252
ip access-group OUTSIDE_INTERFACE in

ip access-list extended OUTSIDE_INTERFACE
10 permit ip [define allowed public networks here] any
25 permit ip 192.168.0.0 0.0.0.255 192.168.0.0 0.0.0.255
100 deny ip any any log


on line 25, you need specify the private network or you will encounter
one-way audio.

IOS version used on this example is c2600-js2-mz.123-13a.bin



;CUBE, multi-service IP-to-IP gateway or SBC

Friday, January 1, 2010

A life of happiness

something to do, something to love, and something to hope for