Linux tips & techniques for developers and system administrators.


Setting up a VOIP server, part 4 (aastra)

By jbayer - Last updated: Tuesday, March 22, 2011

The IP phones we are using are made by Aastra, and are great pieces of equipment.  When booting up they contact (by default) a TFTP server, which is identified by DHCP option 66.

We needed to have our phones portable, and didn’t want to go through the hassle of setting up an external TFTP server for several reasons, among them security.  So I set up an ftp server using VSFTP, and wrote a script which synchronizes the tftp directory with the ftp directory.

The script does the following:

Only run if any file in the tftp directory is newer than the newest file in the ftp directory
Update the aastra.cfg to have the phone use an FTP server instead of a TFTP server
Rsync the tftp directory to the ftp directory
Modify all *.cfg files in the ftp directory:

Change the local IP address with the DNS of the server
Change the HTTP lines which reference port 80 to the configured port
Change the HTTP lines which don’t reference a port at all to use the configured port

Change the permissions on all the files in the ftp directory to read only

You will need to configure the following values at the beginning of the script:


If you are using a non-standard tftp directory or ftp directory, you will need to update those values as well (also at the beginning of the script).

I’ve also attached a copy of the vsftpd.conf file.  You will need to create a user that your phones will use to access the FTP server, and add that user to the /etc/vsftpd/user_list file.  I would suggest using the following command for security to add your user:

useradd -s /sbin/nologin -b /var/ftp aastrauser

and don’t forget to put a password on the account

  vsftpd.conf (1.7 KiB, 942 hits) (2.6 KiB, 1,178 hits)

Filed in Administration, Linux Installations, Open Source, VOIP • Tags:

Setting up a VOIP server, part 3 (Elastix)

By jbayer - Last updated: Tuesday, March 15, 2011

I chose Elastix, partially because it is a a popular distribution, partly because it is easy to install, and partly because it includes additional functionality which we may use in the future.  Elastix is actually a complete communications server, including email, fax, VOIP, IM via Jabber, and integration with different CRMs

You can download it from their web site, or from SourceForge.  Going to SourceForge has additional files and documentation available, including Elastix Without Tears, an excellent installation & reference guide.

Filed in Administration, Linux Installations, Open Source, VOIP • Tags:

Setting up a VOIP Asterisk server, part 2 (IP Phones)

By jbayer - Last updated: Tuesday, March 15, 2011

IP phones are plentiful, but we wanted reliable phones which the phone system could use to the fullest.  I’ve used several, including Aastra and Grandstream.  The best supported IP phones for Asterisk are made by Aastra.

Their line includes:

6730i Series

6750i Series

9000i Series

Any one of these phones are a great choice.  We’ve decided to go with the 9143i for most of our desktops because it is relatively inexpensive yet has enough features to satisfy us for the foreseeable future.

One of the great things about the Aastra phones is the support available.  There are some script written by Aastra support, although these are officially unsupported there is actually plenty of support available, and the scripts are updated on an as-needed basis.  You can get them here:

Here is the documentation for these scripts.

The install script is called install-aastra-xml.x.gz, and it takes care of installing all dependencies.  To install these scripts, use the following set of commands:

cd /usr/src
gzip -d install-aastra-xml.x.gz
chmod +x install-aastra-xml.x

When complete, the scripts will be installed and ready to use.  Be sure to read the documentation supplied (see link above) to get a full understanding of what they do.

The scripts are installed, now run the configuration:


This command creates a proper aastra.cfg in the TFTP directory (/tftpboot) to allow self-configuration.  If you need to change how the phones are configured that is all done in the template files /var/www/html/aastra/asterisk/:


Here is the official Aastra XML script 2.0.0 manual.

Filed in Administration, Linux Installations, Open Source, VOIP • Tags:

Setting up a VOIP Asterisk server, part 1

By jbayer - Last updated: Tuesday, March 15, 2011

The saga of replacing a legacy phone system with a complete VOIP solution

The lease was coming to an end on our legacy phone system, and we started looking for an alternative.  We considered the following choices:

  1. Extend the lease for another 3 years, at which time we would own the system
  2. Replace the phone system with a hosted VOIP solution
  3. Replace the phone system with an internal VOIP solution

For phone service, we looked at the following:

  1. Continue with Verizon POTs lines
  2. Replace POTs lines with the hosted VOIP solutoin
  3. Replace POTs lines with a VOIP provider
  4. Get a T1 line for the phone lines

When considering to replace POTs lines, we needed to consider the reliability, cost, and quality of the VOIP providers.  We decided to go with two providers, in case one has problems, and we are probably going to keep one POTs line just in case the internet goes down on us.

After doing our due diligence, we decided to go with the third option for each, in other words, we are setting up a VOIP server and have selected two external VOIP providers.  While the initial upfront costs are higher, after 10-12 months we will have more than saved money.  Going with a hosted solution would have cost us about $450/month, going with an extended lease would have cost us $180/month plus about $400 phone charges/month.  The all-VOIP solution will cost us about $2500-$3000 for the initial hardware, and our phone charges will be less than $100/month plus an extra $50/month for the spare POTs line.  After running the numbers, it showed that after 9 months we would be ahead in terms of absolute cost using the all-VOIP solution.   In actuality, the physical system we built cost about $200 using an Atom 525 with a gig of memory and a decent hard disk, which was about $300 less than anticipated.

Then came the choice on VOIP providers.  We considered the cost of the phone service and also investigated their reputation and quality of service.  There were several finalists, and our final choice came down to the cost, all other factors being equal.  Without going into all the details, we settled on the following two providers:

nexMatrix ( as our primary VOIP provider
Teliax ( as our backup VOIP provider.

Finally, the choice of what VOIP system to use.  There are several very good Asterisk-based solutions, including:

Trixbox Pro
Trixbox CE

An alternative to Asterisk is sipXecs, located at sipFoundry.  To read the installation instructions for sipXecs, go here.

We decided against sipXecs because of our need to eventually integrate the phone system with SugarCRM

For a more complete list of Asterisk-based solutions, take a look at the following two links:

Having had experience with Trixbox, I first looked at that, but was disappointed at the lack of progress in recent years.  I also tried to roll our own Asterisk solution.  The roll-your-own, while I was able to build a working system, wasn’t supportable enough;  we didn’t want to have to constantly be the ones to download and install updates, etc.  Also, doing a roll-your-own means that the underlying OS may not be optimized to the fullest for Asterisk.

The final decision was to go with Elastix, both because the UI was easy to use, and it was FreePBX based.  This opened up a large number of add-ons if we ever desired to use them.

For FreePBX & Asterisk 1.6, here are the settings I used to set up the Elastix trunk, with my specific details removed.  There is no direct editing of files.

I’ve replaced my details with the following:

secret             ->    ***password***
username           ->    ***custid***
Register string    ->    ***registerString***
 Outgoing Settings
 Trunk Name:            nexMatrix-OUT
 PEER Details:
 Incoming Settings
 USER Context:            nexMatrix
 User details
 Register String:    ***registerString***
Filed in Administration, Linux Installations, Open Source, VOIP • Tags: ,

Set up a mail server for multiple domains using Postfix, Dovecot & PostfixAdmin

By jbayer - Last updated: Wednesday, March 9, 2011

A common task is to set up a mail server.  A less common task is to be able to support multiple domains on the same mail server, with the possibility of the same address on different domains.

An easy way to do this is to use Postfix and Dovecot, using MySql as a backend to store the user information, and using PostfixAdmin as a management interface.

The following link does a very nice job of explaining how to do this:

I have used this page as a reference to create a script to almost fully automate this.  The script has been tested on CentOS 5.5, and in fact was used to build our new mail server.

Additionally, this script installs Roundcube and Squirrelmail on the server for webmail access, and creates a minimal index.html to grant access to Roundcube & Squirrelmail.

Just do a minimal install, upload the script and execute it.  It will take care of disabling SELinux, if required. (24.9 KiB, 1,507 hits)

Filed in Administration, Linux Installations, Open Source • Tags: ,

Installing SugarCE on CentOS (and Fedora)

By jbayer - Last updated: Monday, March 7, 2011

SugarCE is an open-source version of the SugarCRM, (CRM meaning Customer Relationship Manager).  I needed to install it on a CentOS system, so made the attached script.  The script assumes that you are starting with a minimal CentOS 5.5 install, Fedora will most likely work as well.

The SugarCRM site is located:

and here is the install script: (17.8 KiB, 738 hits)

Filed in Administration, Linux Installations, Open Source • Tags: ,

Zoneminder and IE 8

By jbayer - Last updated: Wednesday, March 2, 2011

Zoneminder hasn’t been updated in over a year, and in that time new browsers have been released.  One of them, IE 8, has depreciated the use of the <applet> tag, which Zoneminder uses to load Cambozola (a java-based viewer)

The following is a replacement for the applet code.  Simple replace the applet code in the file:


around line 415, with the following:

 width="<?= $width ?>"
 height="<?= $height ?>"
 title="<?= $title ?>">
 <PARAM name="code" value="com.charliemouse.cambozola.Viewer">
 <PARAM name="archive" value="<?= ZM_PATH_CAMBOZOLA ?>">
 <param name="accessories" value="none"/>
 <param name="url" value="<?= $src ?>"/>
Filed in Administration, Linux Installations, Open Source • Tags:

Software Distribution & Syncronization

By jbayer - Last updated: Monday, February 28, 2011

I recently had to update about 30 different servers with the identical software.  This is an all-too-common occurance for an administrator, and there are many different systems available to do this.  However, most of them do too much and are generally non-trivial to set up and manage.  I wanted a system which would be easy to install, and easy for a non-administrator to use.  Enter PullIt, a simple system which solves these requirements:

  pullit.tar.gz (32.5 KiB, 308 hits)

PullIt Software Distribution System


0.  Introduction
1.  Description
2.  Installation Details
3.  Usage
4.  Parameter Definitions
5.  Commands
6.  Error Codes
7.  Example

0.  Introduction

Pullit is a small system which gives administrators the ability to remotely install files on various systems.  It has been designed to be simple to understand and simple to operate.  Based on the KISS principle, it doesn’t try to do everything.  There are many other packages which  provide much more extensive services, if you need more than this can provide.

This system does not have any security attached.  The code for all packages will be copied to all systems, only the required packages will be installed. What this means is that if you have a malicious user who wants to install a package and they are not supposed to, they will be able to copy the files and install them by hand.

1.  Description

PullIt consists of two parts, and  The first,,  is the shell by which the administrator/user queues up a set of file to be distributed.  The second,, is a daemon which is run periodictly by cron.

The basic idea is that there is a master server, on which the users/administrators will place files for distribution.  The files will be packaged up into  a shar file and placed into a distribution directory.

The clients will have the script running in a cronjob.  The script firsts uses rsync to syncronize it’s local directory of packages with those on the server.  This design allows each client to also function as a server, which both relieves the load on the main server in cases where either there are a large number of clients, or if the server is a very low-powered machine. It also allows remote distribution of packages

The system is flexible enough to allow for multiple architectures, and multiple distribution groups.

So for example, you can have a “manager” and “employee” group, and inside each group there could be both 32 bit, 64 bit, and noarch architectures.  Packages intended for the manager group will not get installed on the  employee group, and vice-versa.  Currently a client can only have one group active; this will be modified in the future to allow for multiple  groups.

Also, when installing files, there is a configuration option which says that a backup should be kept.  When this is set, if the file exists then the system will first createa subdirectory in the destination directory and then MOVE (not copy) the files to it.  The reason for the move is in case the file is currently being executed, it will be able to continue to execute without having to worry about the file being overwritten.

When installing a client, the group the client belongs to is specified in the configuration file.

2.  Installation Details

On the server, the file will be installed to /usr/local/sbin (or whereever you specify), a configuration directory will be created in /etc, and a configuration file installed in the configuration directory.

On the client, the file will be installed to /usr/local/sbin, a configuration directory will be created in /etc, and a configuration  file installed in the configuration directory.  Also, a file will be installed into /etc/cron.d

It is your responsibility to make sure that rsync is working properly on  all systems.

To install, unpack the tar file into a directory and run the  script:

The install script can optionally use the “dialog” command to have a curses- based installer.  If you would like to use the text-based mode even if you have the dialog command available, invoke the installer as follows: text

The installer should usually be run as root, however it will allow you to run as a regular user.  Obviously, a regular user will not be able to change system files or directories, so if a regular user is installing this then it will be installed local to that user.

The installer has the ability to create an installation script for the  clients.  I strongly recommend you use this, since the installation script  will also create ssh keys on the client and install them on the server.  This makes the complete installation process extemely easy.  The client installation creates the necessary ssh keys, and also asks for the group that the  client is in, and the architecture of the client.


The system runs as a simple shell with a limited number of commands.  The system is actually a bash shell script, and does not do any fancy screen manipulation, so you can very easily have this run in a batch mode.

The command to run is:

The valid shell commands are:

start packagename
end (see done)
done [ packagename [groupname]]
group groupname
noarch (shortcut for “arch noarch”)
arch 32 | 64 | noarch  (anything will work, as long as all clients use the same)
noarch is special, it means that ALL platforms in the group will install the package
add [ file [file]] destinationDirectory
del file [file...]  | all
commit all | packagename [group]
list [ files | packages | groups | archtypes ]  (defaults to files)
runbefore filename [in directory] [rc expected]
runafter filename [in directory] [rc expected]
prune packagename [packagename...] | all
at [ yyyy-mm-dd [ hh:mm:ss ] ]

4.  Parameter Definitions

packagename Name of the package being worked on.
groupname Name of the group the current package is intended for
filename Name/path of the file being installed/deleted

You can use quotes, either single or double, to enclose a parameter with spaces.  Also, you can use a backslash to escape the next character; this will allow you to embed a quote inside a single parameter.  All quotes,  except for a quoted parameter at the end, must be closed with the same quote which started the quoting.

5.  Commands

start [ packagename ] Use this command to start building a package.  Specify the name of the package with the command.  The packagename needs  to obey the rules for directory names.  The packagename is optional at this point, but will need to be specified on  the “end” command if not entered here.
group groupname An alternate method of specifying what group the current package will be distributed to.  If specified with this command, it will not need to be specified with the “end”  command
A shortcut to entering a group.  This relies on the allowable groups being defined in the configuration file.
done | end [ packagename [ groupname ] ] This command finishes a package.  However, the package is NOT released for distribution yet, use the “commit” command for that.  The packagename and groupname are optional here, in  that if they were specified using the “start” and “group” command you wouldn’t need to specify them here.
arch archtype | noarch The archicture specifies the destination system.  While it would be advisable to use the same arch as the basic OS, there is no technical reason to do so.  This allows you to specify any number of archictures.  One reason to do so is to use a single server to distribute files to 32 bit, 64 bit, x86 x86_64, arm avr32 blackfin m68k m68knommu microblaze  mips powerpc.  However, if you specify any architecture types during the server install, only those types will be allowed.
noarch This is a shortcut for “arch noarch”
(archtype) If the archtype is simply typed on a line by itself, and it doesn’t match a command name, then the architecture will be set to the entered archtype.  This is similar to the “noarch” command as a shortcut.  This relies on the default architectures being specified in the configuration file.
add [ filename [ filename ]…] destinationDirectory Multiple files can be specified here.  This command adds files to the package; the last paramenter is the destination directory on the client computers.  The files don’t have to be in the current directory, the full paths will be stripped before building the package.
del filename | all Delete the specified file from the current package.  If “all” is specified, then delete all files from the current package.
commit all | packagename [ groupname ] Commit a package for distribution.  If a groupname is  specified, then only commit packages which are ready for the specified group.  If “all” is specified, then commit  all available packages for distribution.
list [ files | packages | groups | archtypes ] This will list the following types of information:

files            All files in the current package
packages    All packages ready for commit
groups       All groups with packages ready for commit
archtypes   All allowed architecture types

runbefore filename [ inDirectory [ expectedReturncode ] ] Specify a command or program to run before the files are installed.  These commands are run BEFORE any files are  renamed for backup.  If inDirectory is specified, then  the command will be run in the specified directory.  If specified, the return code from the command must match the expectedReturncode, otherwise the install will abort.  If the directory the command is run in is not important, but you do want to specify the returncode, then use a . as the directory.
runafter filename [ inDirectory [ expectedReturncode ] ] Specify a command or program to run after the files are installed.  These commands are run BEFORE any files are  renamed for backup.  If inDirectory is specified, then  the command will be run in the specified directory.  If specified, the return code from the command must match the expectedReturncode, otherwise the install will abort.  Note that since the files have been installed and backups made if specified, that an abort at this point could leave your systems in an unexpected state.
prune packagename [packagename...] | all Prune specified packages from the cache directory, or all packages
at [ yyyy-mm-dd [ hh:mm:ss ] ] Install the package at or after the specified date/time
quit Both quit and exit will exit the shell.

6.  Error Codes

The following error codes can be returned by the script.  These may be useful if you are calling it from a script:

0       All ok
1       Missing configuration file
2       Missing file
3       Unable to create libdir
4       Unable to install sharutils with yum
5       Niether yum nor apt-get detected
6       unable to install sharutils with apt-get
7       Unable to create the cache dir

The following error codes can be returned by the script:

0       All ok
1       Missing configuration file
2       Unable to create libdir
3       Unable to create the top journaldir
4       Unable to create the cachedir
5       Transfer program missing
6       Unable to create the lower journal directory
7       Not running as specified user

7.  Example

Lets say that you have a number of web servers, all being load-balanced together in a colo facility.  You need to update some files in a directory on all the servers.  A problem is that some of the servers are always down for maintenance or other problems.

Here is the situation:

Main HTML directory: /var/www/html
Group: webserver
Directory containing files to be updated: /var/www/html/mydir
Files to be updated/added: index.php .htaccess config.php

First, copy the files to the master server:

scp index.php .htaccess config.php jbb@master:

Then log in to the master:

ssh jbb@master

Now start the pullit shell:

The shell gives the following prompt:


Enter the following commands, one per line:

start mydir
group webserver
arch noarch
add index.php .htaccess config.php /var/www/html/mydir
runbefore "/etc/init.d/httpd stop"
runafter "/etc/init.d/httpd start"
commit all

Note that because there are spaces in the commands you want to run, you  need to surround the command with quotes.

The commands do the following:

start mydir
Start a package called "mydir"
group webserver
This package is intended for the group called "webserver"
arch noarch
No architecture, so this will be installed on all servers in the group
add index.php .htaccess config.php /var/www/html/mydir
Add the three files to the package, they will be installed to the /var/www/html/mydir directory
runbefore "/etc/init.d/httpd stop
Stop the webserver before doing the installation
runafter "/etc/init.d/httpd start
start the webserver after the install is done
End the package, ready for commit
commit all
Commit all packages.  At this point, the packages are available for the servers to pull them down and install
exit the pullit shell
Filed in Administration, Bash, Open Source

Install problems on older hardware

By jbayer - Last updated: Friday, February 11, 2011

A coworker was trying to install Ubuntu 10.10 Maverick Meerkat onto an older laptop.  The installer would simply hang at a black screen as soon as the install was started.

This brought to mind the problems people have installing onto different hardware;  I’m going to keep this updated with various ideas and suggestions.

Maverick Meerkat on an HP Pavilion zv5000 (zv5380us)

In this case, the solution was to use the alternate install CD and change some of the boot options.  After selecting the location, press F6 to get to the option screen.  There will be a small menu at the lower right, you want to use the up/down keys to select the following options:


Then press the escape key, and press return to start the installation.  If you like, you can change the VGA mode to something different, I tend to use:


The complete install will be done using a text-mode installer.

Filed in Linux Installations

Using “configure” to build a 32 bit executable on a 64 bit System

By jbayer - Last updated: Thursday, February 10, 2011

If you are on a 64 bit Linux system, and need to build a 32 bit executable (for example if you need to install it on  another, 32 bit, system), you can build it by passing the following argument to the  configure script:

./configure --build=i686-pc-linux-gnu "CFLAGS=-m32" "CXXFLAGS=-m32" "LDFLAGS=-m32"
Filed in Building packages, Open Source, Programming