Wednesday, December 11, 2013

How to setup virtual presence in Hong Kong

Hong Kong is the Asia hub providing numerous opportunities for you to develop business in the most promising economy sectors.

A Hong Kong local phone number would be very useful to kick off your business here and in fact, you could establish your virtual presence conveniently by subscribing to a licensed HK DID SIP trunk service provider .   

The DID stands for direct inward dialing and describes the functionality to receive call.  SIP is the industry standard for handling calls over internet.  In essence, the provider is using SIP technology to let you receive and send calls using a HK number even you are not physically in HK.

They will give you a local HK number and route all incoming calls to this HK number via internet to your overseas office or call center.  In the simplest way, you just need a IP phone in order to receive calls from and dial out via the HK number.

When you have multiple HK DID numbers or a team of agents to answer calls, you need a SIP-based telephone system for distributing and logging the calls.  These systems usually provide other value-added features like IVRS, conversation recording and follow-me.  Sophisticated ones could even allow you to monitor your agents on-the-fly and gather useful performance statistics.
There are a variety of such systems in the market, such as Asterisk, Elastix or FreePBX.   

Monday, December 02, 2013

Elastix : How to automatically add '9' to all incoming calls

You have setup an Elastix with T1 connectivity to PSTN.  You can also dial '9' to pickup the T1 trunk and dial out.  However, you soon find that it is inconvenient to dial a missed call on your phone simply because the caller number just does not have a '9' in front of it.

Here shows how to automatically add a '9' to all incoming calls in Elastix.

  • Edit /etc/asterisk/extensions_override_elastix.conf

  • Append below lines.  These codes add '9' in front of the caller number if it looks like a local one (8 digits in our case).

include => macro-user-callerid-custom
exten => s,1,Set(AMPUSER=${IF($["foo${AMPUSER}" = "foo"]?${CALLERID(number)}:${AMPUSER})})
exten => s,n,GotoIf($["${CHANNEL:0:5}" = "Local"]?report)
exten => s,n,ExecIf($["${REALCALLERIDNUM:1:2}" = ""]?Set(REALCALLERIDNUM=${CALLERID(number)}))
exten => s,n,Set(AMPUSER=${DB(DEVICE/${REALCALLERIDNUM}/user)})
exten => s,n,Set(AMPUSERCIDNAME=${DB(AMPUSER/${AMPUSER}/cidname)})
exten => s,n,GotoIf($["x${AMPUSERCIDNAME:1:2}" = "x"]?report)
exten => s,n,Set(AMPUSERCID=${IF($["${DB_EXISTS(AMPUSER/${AMPUSER}/cidnum)}" = "1"]?${DB_RESULT}:${AMPUSER})})
exten => s,n,Set(CALLERID(all)="${AMPUSERCIDNAME}" <${AMPUSERCID}>)
exten => s,n,ExecIf($["${DB(AMPUSER/${AMPUSER}/language)}" != ""]?Set(CHANNEL(language)=${DB(AMPUSER/${AMPUSER}/language)}))
exten => s,n(report),GotoIf($[ "${ARG1}" = "SKIPTTL" ]?continue)
exten => s,n(report2),Set(__TTL=${IF($["foo${TTL}" = "foo"]?64:$[ ${TTL} - 1 ])})
exten => s,n,GotoIf($[ ${TTL} > 0 ]?continue)
exten => s,n,Wait(${RINGTIMER})
exten => s,n,Answer
exten => s,n,Wait(2)
exten => s,n,Playback(im-sorry&an-error-has-occured&with&call-forwarding)
exten => s,n,Macro(hangupcall,)
exten => s,n,Congestion(20)
exten => s,n(continue),Noop(Original Using CallerID ${CALLERID(all)})
exten => s,n,Set(CALLERID(number)=${CALLERID(number):0:40})
exten => s,n,Set(CALLERID(name)=${CALLERID(name):0:40})
exten => s,n,ExecIf($[ LEN(${CALLERID(number)}) = 8 ]?Set(CALLERID(number)=9${CALLERID(number)}))
exten => s,n,Noop(Using CallerID ${CALLERID(all)})
exten => h,1,Macro(hangupcall,)

; end of [macro-user-callerid]

  • This approach basically supercedes the original  [macro-user-callerid] of Elastix and you have control on how the caller id would be presented to your extensions.  However, if you upgrade Elastix later, you need to check if these customization align with the upgraded Elastix source code .

Saturday, August 31, 2013

Auto-provision Yealink IP Phones

Auto-provisioning allows us to conveniently mass deploy IP phones.  Generally, we put a set of configuration files containing the sip credentials and other phone settings on a tftp server.  When the IP phones boot, they download the configuration from the tftp server and self configure to work with the IP PBX.

This blog describes the steps taken to auto-provision Yealink T20P and T28P.

When Yealink phone boots, it looks for auto provision information in order of PnP, DHCP option 150 and DHCP option 66.  We therefore could configure our DHCP server to supply the tftp server address via option 66.

For illustration, below shows how to specify tftp server address in /etc/dhcpd.conf in CentOS.

subnet netmask {
        option routers        ;
        option subnet-mask    ;
        option nis-domain               "pbx";
        option domain-name              "bx";
        option domain-name-servers;
        option time-offset              28800; # Asia/Hong_Kong
        option ntp-servers    ;
        option tftp-server-name         "";

Yealink phones expect two types of XML configuration files: model-oriented cfg and mac-oriented cfg.  A full list of the configuration parameters could be found here.

The model-oriented.cfg for T20 and T28 are given below.

T20 y000000000007.cfg
T28 y000000000000.cfg

A mac-oriented.cfg would look like  0015652e9af6.cfg.

By preparing a set of cfg, we could easily deploy a large number of Yealink phones.

Monday, August 05, 2013

Setup Elastix SIP trunk to Skype with SkypeConnect

What is SkypeConnect

Skype Connect is the official Skype-to-SIP gateway offered by Skype.  

You can subscribe this service via the Skype Manager's Features Menu.  It works like a SIP trunk whereas you will be given a SIP account and a password for your SIP PBX, for example, Elastix, to register to which is the gateway between your PBX and the proprietary Skype network.

By gaining connectivity with the global Skype community, your business can get improved customer exposure. 

You can place a Skype button on your web site and your visitors can instantly talk to your service staff through a mouse click and at zero IDD cost -- What a easy way to setup a toll-free inquiry to your product !  

Incoming call is eventually handled by your PBX and therefore call management like IVR, Call Queue, Auto Attendant andconversation recording becomes possible.

What is more, 
you can take advantage of the wide coverage of Skype Numbers to allow international visitors to contact you via their local telephone network.    

Your SIP Profiles

You can setup more than one SIP profiles in Skype Manager.  A SIP profile is basically a SIP account with which your SIP-based PBX uses to register to  
Next, go to Profile settings|Incoming calls, we add business account or Skype Number to establish a connection with our SIP profile with a particular Skype identity.  Incoming calls to this Skype id or Skype Number will be diverted to our SIP trunk and be eventually handled by our Elastix.

Note that Skype enforces a ceiling on the maximum number of concurrent calls per profile.

Setup SIP trunk in Elastix

We go to PBX|Trunks|Add SIP Trunk and input the account credentials in PEER Details and Registration sections.

username=<refer to your SIP profile in Skype Manager>
secret=<refer to your SIP profile in Skype Manager>


To verify whether we can successfully register to Skype, we can use below command in Asterisk CLI.

CLI > sip show registry

You should see that your SIP account is reported as 'registered'.

Setup Inbound Route in Elastix

To route the Skype incoming calls to an Elastix destination, we have to setup an inbound route in PBX|Inbound Routes.
Simply specify the Skype SIP username in the DID number field and choose a destination, such as IVR or ring groups.
Then you can receive calls from Skype and could take advantages of numerous call management features in Elastix.

Yet world is not perfect

At the time of writing, we experience a consistent long delay (around 1min) after clicking a Skype Button and before our Elastix sees the incoming traffic.  
When you google 'skype connect long delay', you should find more than a few posts about similar situation.  Apparently, this issue has been brought to Skype support and is still awaiting resolution.

Friday, July 05, 2013

[SOLVED] Asterisk disk space problem

Recently, we see an issue with an Asterisk installation where the disk
usage keeps growing, but apparently not due to increasing call volume.

First of all, repeating 'df -h' shows that '/' is approaching its
capacity upper limit. More importantly, the free space keeps decreasing
for unknown reason.

# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00 43G 39G 2.5G 94% /

Filesystem Size Used Avail Use% Mounted on
/dev/mapper/VolGroup00-LogVol00 43G 39G 2.0G 96% /

However, the 'du -sh /' provides conflicting results.

# du -sh /
13G /

Such discrepancy could be due to hidden files behind a mount point under
'/'. The 'df' command uses the file system superblock to report the
usage statistics. On the other hand, 'du' command follows the directory
tree to accumulate the usage figures and files hidden behind a mount
point are not taken into consideration.

This system is coincidentally mounting a storage device on

We can use the 'bind' option in mount to reveal the real situation.

# mount -o bind / /another-view-root
# cd /another-view-root
# du -sh /another-view-root/var/spool/asterisk/monitor

Now, we get consistent result with the 'df' command. It also shows the
wave files which became hidden when another device was mounted over them.

Furthermore, we spot a very large wave file modified recently among
these hidden files. The wave filename indicates that it was created at
least a month ago, but is still growing.

Using 'CLI> core show channels', we notice there is a active call which
is bridged to VM. This problematic call is not disconnected for unknown
reason and because all extensions under this site requires monitoring,
its corresponding wave file keeps growing.

Another device later mounts over these files and unintentionally hides
the problem until the decreasing free space alerts the administrator.

By stop this problematic call using 'CLI> channel request hangup
<channel-id>', the wave file is closed finally and subsequently deleted.

Thursday, June 20, 2013

How to setup passwordless sftp connection

The following steps are used to setup passwordless sftp connection to a remote host.

Local host
# ssh-keygen -t rsa -b 4096

It will generate the public key file in ~/.ssh/ .
Let's assume that it is named in your unix installation.

# ssh-copy-id -i root@remote-host

This command pastes contents of in the remote host's /root/.ssh/authorized_keys and ensures proper file permission.
Upon successful execution, we should be able to sftp to the remote host without password prompt.

# sftp root@remote-host
> sfftp

Remote host
# cd ~/.ssh
# ls -l authorized_keys

We should see that the authorized_keys file is updated.

Tuesday, May 28, 2013

Setup Snom UC Edition with Elastix

First of all, Snom UC edition is not ready for Lync connection out of the box.  We have to obtain the UC edition firmware from Snom and install it on the Snom phone.

If we setup the Snom phone manually, it is important to perform a factory reset after the UC edition firmware was installed.  This step is re-stated in the Snom FAQ section.

Snom phone with the UC edition firmware successfully installed could be identified by:
  • The phone display shows 'UC edition' when startup
  • The WEB UI uses 443 instead of 80
  • A menu item for Lync connection is added

To register the Snom UC edition phone to Elastix, we have to ensure:

  • The rtp encryption in the sip section is disabled (it is enabled by default)
  • The servertype is set to 'asterisk' in the sip section
    • This field has been reset by UC edition firmware to OCS during the firmware upgrade and we have to change it to 'asterisk' to enable sip registration


Monday, January 07, 2013

Use DNSBL with Sendmail

It is imperative that we implement some kind of anti-spam controls in
the mail server that receives internet email traffic. One of the
controls is to check the connecting smtp server's ip address against a
blacklist of known spammers, zombie pc, open relays, ip addresses range
that should not send out email (eg the subscriber ip address ranges of
ISP) etc. What is more, many of these blacklists are free to use.

In this example, we use the blacklists provided by and

In the /etc/mail/, we add below two lines:

FEATURE(`dnsbl',`',`"Rejected due to Spamhaus listing
see" $&{clientaddr} " for more
FEATURE(`dnsbl',`',`"Rejected due to cbl listing see" $&{clientaddr} " for more

Note the use of backquote here (` vs '). The third parameter provides
the customized message that should be returned to the sending mail
server in case it hits the blacklist. Multiple dnsbl can be used
together to enhance the anti spam strength.

To make the changes effective:

m4 >
service sendmail restart

To verify whether the anti spam checking is in use, we can look for
something like 'Rejected due to Spamhaus' in the /var/log/maillog.

Wednesday, January 02, 2013

Prepare sendmail as MX and forward all incoming emails to another server

Our client has two sendmail boxes, one for receiving emails from
internet (ie as MX record), another one as the SMTP, POP3 and IMAP
server for internal users to send out emails and retrieve mail boxes.
By separating incoming and outgoing email traffic, he could reduce
impact of email bomb attack.

The followings apply to Sendmail 8.14.4.

1. First of all, in /etc/mailertable, we instruct sendmail to route
all incoming emails for to another server. esmtp:[hostname-or-ip-of-another-server]

The [ ] will turn off MX lookup for this domain. Otherwise, there will
a MX loop.

After making changes, we have to rebuild the mailertable.db as below.

makemap hash mailertable.db < mailertable

2. Note that our has to enable the 'mailertable' feature.

FEATURE(`mailertable', `hash -o /etc/mail/mailertable.db')dnl

The is a macro-based file for us to specify configuration
parameters easily. It has to be converted by the 'm4' utility to become
the ultimately required
m4 >
service sendmail restart

3. At the same time, we have to comment the DAEMON_OPTIONS such that
our sendmail will listen to internet smtp traffic.
dnl DAEMON_OPTIONS(`Port=smtp,Addr=, Name=MTA')dnl

4. We have the option to reject emails if the sender domain is not
resolvable. Note that it might block some legitimate emails (eg users
on computers that do not have 7x24 DNS)

To turn it on/off, we use FEATURE(`accept_unresolvable_domains')dnl in

5. /etc/mail/local-host-names should be empty as incoming emails
should just be forwarded as said in mailertable.

6. Relaying is by default disabled in sendmail. We need to specify
the domains that we want to serve in the /etc/mail/access.

The example below permits emails sent to and
specifically blacklist all emails coming

# By default we allow relaying from localhost...
Connect:localhost.localdomain RELAY
Connect:localhost RELAY

After making changes to access, we have to rebuild it by:

makemap hash access.db < access