We can now chat on irc on the new freenode channel #pyfreebilling.
How to install PyFreeBilling 1.4.6 on Ubuntu 14.04 64 bits LTS
IMPORTANT : PyFB v1 is end of life. Please check v2 documentation
Introduction
This howto is written for ubuntu 14.04 LTS server. You can use the same commands for debian based servers, but depending on version, some commands may differ.
Prerequisites
First, you need to install these packages :
apt-get install git-core build-essential autoconf automake libtool libncurses5 libncurses5-dev gawk libjpeg-dev zlib1g-dev pkg-config libssl-dev libpq-dev unixodbc-dev odbc-postgresql postgresql postgresql-client libpq-dev libxml2-dev libxslt-dev ntp ntpdate libapache2-mod-wsgi apache2 gcc python-setuptools python-pip libjpeg62 libjpeg62-dev libdbd-pg-perl libtext-csv-perl sqlite3 libsqlite3-dev libcurl4-openssl-dev libpcre3-dev libspeex-dev libspeexdsp-dev libldns-dev libedit-dev libmemcached-dev python-psycopg2 python-dev libgeoip-dev
Freeswitch installation
go to the source directory :
cd /usr/src
and download the last stable freeswitch version
git clone -b v1.4 https://stash.freeswitch.org/scm/fs/freeswitch.git
after, boostrap, configure, make and install freeswitch
cd freeswitch ./bootstrap.sh -j
edit modules.conf suiting your needs. You will find below the minimum list of modules to be installed :
applications/mod_commands applications/mod_db applications/mod_dptools pplications/mod_esf applications/mod_esl applications/mod_expr applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_memcache applications/mod_nibblebill codecs/mod_amr codecs/mod_g723_1 codecs/mod_spandsp codecs/mod_siren codecs/mod_amrwb codecs/mod_g729 dialplans/mod_dialplan_xml endpoints/mod_loopback endpoints/mod_sofia event_handlers/mod_cdr_csv event_handlers/mod_event_socket formats/mod_local_stream formats/mod_native_file formats/mod_sndfile formats/mod_tone_stream languages/mod_lua languages/mod_spidermonkey loggers/mod_console loggers/mod_logfile loggers/mod_syslog say/mod_say_en
after, do :
./configure make make install
you need to compile esl for python
cd libs/esl make pymod make pymod-install
create a freeswitch user and group as follow :
groupadd freeswitch adduser --disabled-password --quiet --system --home /usr/local/freeswitch --gecos "FreeSWITCH Voice Platform" --ingroup daemon freeswitch
and to apply the rule to freeswitch user :
chown -R freeswitch:daemon /usr/local/freeswitch/ chmod -R ug=rwX,o= /usr/local/freeswitch/ chmod -R u=rwx,g=rx /usr/local/freeswitch/bin/
and now, we need to create the init script to start and stop
freeswitch :
nano /etc/init.d/freeswitch
Add your init code
#!/bin/bash ### BEGIN INIT INFO # Provides: freeswitch # Required-Start: $local_fs $remote_fs # Required-Stop: $local_fs $remote_fs # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Description: Freeswitch debian init script. # Author: Matthew Williams # ### END INIT INFO # Do NOT "set -e" # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin DESC="Freeswitch" NAME=freeswitch DAEMON=/usr/local/freeswitch/bin/$NAME DAEMON_ARGS="-nc -nonat" PIDFILE=/usr/local/freeswitch/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME FS_USER=freeswitch FS_GROUP=daemon # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.0-6) to ensure that this file is present. . /lib/lsb/init-functions # # Function that sets ulimit values for the daemon # do_setlimits() { ulimit -c unlimited ulimit -d unlimited ulimit -f unlimited ulimit -i unlimited ulimit -n 999999 ulimit -q unlimited ulimit -u unlimited ulimit -v unlimited ulimit -x unlimited ulimit -s 240 ulimit -l unlimited return 0 } # # Function that starts the daemon/service # do_start() { # Set user to run as if [ $FS_USER ] ; then DAEMON_ARGS="`echo $DAEMON_ARGS` -u $FS_USER" fi # Set group to run as if [ $FS_GROUP ] ; then DAEMON_ARGS="`echo $DAEMON_ARGS` -g $FS_GROUP" fi # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null -- \ || return 1 do_setlimits start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --background -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc -p $PIDFILE $DAEMON $NAME && exit 0 || exit $? ;; #reload|force-reload) # # If do_reload() is not implemented then leave this commented out # and leave 'force-reload' as an alias for 'restart'. # #log_daemon_msg "Reloading $DESC" "$NAME" #do_reload #log_end_msg $? #;; restart|force-reload) # # If the "reload" option is implemented then remove the # 'force-reload' alias # log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2 exit 3 ;; esac exit 0
make this script executable :
chmod +x /etc/init.d/freeswitch update-rc.d freeswitch defaults
add the cli link :
ln -s /usr/local/freeswitch/bin/fs_cli /bin/fs_cli
Postgresql configuration
create user and database :
sudo -i -u postgres createuser -P pyfreebilling Enter password for new role: Enter it again: Shall the new role be a superuser? (y/n) n Shall the new role be allowed to create databases? (y/n) y Shall the new role be allowed to create more new roles? (y/n) y createdb -O pyfreebilling -E UTF8 pyfreebilling exit
set odbc parameters; you need to create and edit /etc/odbc.ini file. Do not forget to specify your postgres password !
[freeswitch] Driver = PostgreSQL Description = Connection to POSTGRESQL Servername = 127.0.0.1 Port = 5432 Protocol = 6.4 FetchBufferSize = 99 Username = pyfreebilling Password = Database = pyfreebilling ReadOnly = no Debug = 0 CommLog = 0
edit /etc/odbcinst.ini (delete all entries and add these ones)
[PostgreSQL] Description = PostgreSQL ODBC driver (Unicode version) Driver = /usr/lib/x86_64-linux-gnu/odbc/psqlodbcw.so Setup = /usr/lib/x86_64-linux-gnu/odbc/libodbcpsqlS.so Debug = 0 CommLog = 0 UsageCount = 0 Threading = 0 MaxLongVarcharSize = 65536
Web server install
securing apache
sudo a2enmod ssl sudo make-ssl-cert /usr/share/ssl-cert/ssleay.cnf /etc/ssl/private/localhost.pem (or use others methods or certificats)
install python virtualenv
pip install virtualenv cd /usr/local virtualenv venv --no-site-packages chown -R myuser:mysuser venv (replace myuser by your current user, perhaps root - better other one)
activate it :
source venv/bin/activate cd venv
install CPAN
install all dependent packages for CPAN
apt-get install build-essential
invoke the cpan command as a normal user :
$cpan But once you hit on enter for “cpan” to execute, you be asked of some few questions. To make it simple for yourself, answer “no” for the first question so that the latter ones will be done for you automatically. ->; ANSWER YES
Once the above is done, you will be present with the cpan prompt.
now enter the commands below
cpan prompt>; make install cpan prompt>; install Bundle::CPAN
Now all is set and you can install any perl module you want.
examples of what installed below
cpan prompt>; install Carp cpan prompt>; install Filter::Simple cpan prompt>; install Config::Vars cpan prompt>; exit
Pyfreebilling installation
download pyfreebilling sources :
git clone https://github.com/mwolff44/pyfreebilling.git chown -R www-data:www-data pyfreebilling cd pyfreebilling
create un new file in pyfreebilling directory called local_settings.py
touch pyfreebilling/local_settings.py
edit this new file, and put yours specific values
# -*- coding: utf-8 -*- from .settings import * DEBUG = False MANAGERS = ADMINS DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql_psycopg2', 'NAME': 'pyfreebilling', 'USER': 'pyfreebilling', 'PASSWORD': 'password', 'HOST': '127.0.0.1', 'PORT': '', # Set to empty string for default. } } ALLOWED_HOSTS = ['*'] SECRET_KEY = 'securitykeymustbechanged' # very important - put your key for security - any string TIME_ZONE = 'Europe/Paris' OPENEXCHANGERATES_APP_ID = "Your API Key" #-- Nb days of CDR to show PFB_NB_ADMIN_CDR = 3 PFB_NB_CUST_CDR = 30 # EMAIL SETUP TEMPLATED_EMAIL_BACKEND = 'templated_email.backends.vanilla_django.TemplateBackend' TEMPLATED_EMAIL_TEMPLATE_DIR = 'templated_email/' TEMPLATED_EMAIL_FILE_EXTENSION = 'email' EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' EMAIL_HOST = '' EMAIL_PORT = 587 EMAIL_HOST_USER = '' EMAIL_HOST_PASSWORD = '' #EMAIL_USE_TLS = True EMAIL_USE_SSL = True EMAIL_SIGNATURE = ''
and now, enter the following commands without sudo (IMPORTANT). At the step “syncdb”, you will fave a prompt asking you to enter a username and a password. They are very important, as thez are the admin one !
pip install -r requirements/requirements.txt python manage.py syncdb (IMPORTANT : enter your username and password) python manage.py initcurrencies python manage.py migrate python manage.py loaddata country_dialcode.json python manage.py loaddata switch 0001_fixtures.json python manage.py loaddata 0001_initial_SipProfile.json python manage.py loaddata 0001_initial_ReccurentTasks.json python manage.py loaddata country.json python manage.py updatecurrencies (if you have set your Openexchange API key) python manage.py collectstatic (answer 'yes')
copy some config files :
cp -av /usr/local/venv/pyfreebilling/freeswitch/conf/autoload_configs/acl.conf.xml /usr/local/freeswitch/conf/autoload_configs/acl.conf.xml cp -av /usr/local/venv/pyfreebilling/freeswitch/conf/autoload_configs/cdr_csv.conf.xml /usr/local/freeswitch/conf/autoload_configs/cdr_csv.conf.xml cp -av /usr/local/venv/pyfreebilling/freeswitch/conf/autoload_configs/modules.conf.xml /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml cp -av /usr/local/venv/pyfreebilling/freeswitch/conf/autoload_configs/nibblebill.conf.xml /usr/local/freeswitch/conf/autoload_configs/nibblebill.conf.xml cp -av /usr/local/venv/pyfreebilling/freeswitch/dialplan/pyfreebill.xml /usr/local/freeswitch/conf/dialplan/pyfreebill.xml cp -av /usr/local/venv/pyfreebilling/freeswitch/dialplan/public/00_did.xml /usr/local/freeswitch/conf/dialplan/public/00_did.xml cp -av /usr/local/venv/pyfreebilling/freeswitch/conf/freeswitch.xml /usr/local/freeswitch/conf/freeswitch.xml
copy freeswitch esl binaries to your virtual env directory
cd /usr/src/freeswitch cp libs/esl/python/ESL.py /usr/local/venv/lib/python2.7/site-packages/ cp libs/esl/python/_ESL.so /usr/local/venv/lib/python2.7/site-packages/
set good rights :
rm -f /usr/local/freeswitch/conf/directory/default/* chown -R freeswitch:freeswitch /usr/local/venv/pyfreebilling/freeswitch/scripts/ chmod 2750 /usr/local/freeswitch chmod 2750 /usr/local/freeswitch/conf/ chmod 2750 /usr/local/freeswitch/conf/autoload_configs/ chmod 2750 /usr/local/freeswitch/conf/directory/ chmod 2750 /usr/local/freeswitch/conf/dialplan/ chmod 2750 /usr/local/freeswitch/conf/dialplan/public/ chmod 770 /usr/local/freeswitch/conf/directory/default.xml chmod 770 /usr/local/freeswitch/conf/autoload_configs/sofia.conf.xml chmod 770 /usr/local/freeswitch/conf/dialplan/public/00_did.xml chown freeswitch:www-data -R /usr/local/freeswitch/ mkdir /tmp/cdr-csv/ chmod 777 -R /tmp/cdr-csv touch /tmp/cdr-csv/Master.csv chmod 600 /tmp/cdr-csv/Master.csv chown freeswitch:freeswitch /tmp/cdr-csv/Master.csv chown -R freeswitch:daemon /tmp/cdr-csv/
set apache config :
cp /usr/local/venv/pyfreebilling/setup/apache/001-pyfreebilling /etc/apache2/sites-enabled/000-default.conf a2ensite 000-default /etc/init.d/apache2 restart
set crontab :
*/1 * * * * perl /usr/local/venv/pyfreebilling/freeswitch/scripts/import-csv.pl>> /var/log/cron.log 2>&1 * * * * * /usr/local/venv/bin/chroniker -e /usr/local/venv/bin/activate_this.py -p /usr/local/venv/pyfreebilling
modify db password and somme settings in :
/usr/local/venv/pyfreebilling/pyfreebilling/local_settings.py /usr/local/venv/pyfreebilling/freeswitch/scripts/import-csv.pl
restart FreeSwitch :
sudo /etc/init.d/freeswitch restart
Pyfreebilling login
Got to the url https://my-ip/extranet and enter your username and password.
The customer portal url is : https://my-ip
I recommend to setup a firewall restrincting access to web pages and your voip ports !
PyFreeBilling : quick start
This is in one line a quick start to work with PyFreeBilling. You also understand how it works :
- Create a customer : Prepaid mode means that the calls are allowed if balance > 0, and Postpaid mode menas that the calls are allowed if balance > credit_limit. Important : the balance represent the real amount due by your customer. If you want to allow a negative balance, you must set in PostPaid mode and a negative credit_limit.
- Add fund to customer balance
- Create a sip account and apply the conf to Freeswitch
- Create a customer rate card and add the rate by prefix (you can import a cvs file)
- Create a LCR and affect it to the ratecard you have just created
- Attach the ratecard to customer
- Create a provider (for the time being, the provider balance is not updated, but it will be in future version)
- Create a provider gateway and apply the conf to Freeswitch
- Create a provider rate card and add the rate by prefix (you can import a cvs file)
- Attach this ratecard to the LCR
- And now test a call !
As you see, it is simple, and permit any configuration you can imagine.
User documentation fundraise
I receive many mails asking about user documentation. As i am working hard on new features, i do not have the time to write it now. But i understand that is very important to have a good up to date documentation.
Also, i can propose something : i have a girl in my team that could work on it, but i need to find how to finance the job. I propose to add any donation made for this purpose, and when the amount reach 1 500 $, she will work on it.
This is documentation contents :
- Getting start : Overview, features, architecture
- Installation (this content exists !)
- Set up configuration
- Customer configuration
- Provider configuration
- LCR
- Customer panel
- Security
- Troubleshooting
- Frequently asked question
Any person making a donation for this purpose, will add a comment in this post to allow everyone to follow easily the evolution of the fundraise.
[the_campaign_funds id=”57″ before=”We already collected USD” after=”for this campaign]
[the_campaign_target id=”57″ before=”Help us! We need to collect USD” after=”- We need your help!”]
[the_campaign_funds_raised_percentage id=”57″ before=”This campaign is pledged at “]
[the_donation_progress_bar id=”57”]
1.4 version released
I very happy to announce the 1.4 final version released. After hours, and many new stuffs, this version is available in the PyFreeBilling Bitbucket repos.
The installation documentation is hosted on PyFreeBilling ReadTheDocs repos.
If you see any bugs, please report in PyFreeBilling bug tracker.
The change log :
Version 1.4
New features
- New customer portal
- HTTPS access only
- Reload Fs config via button in admin panel
- Currency management
- Database size monitoring – new panel (in admin menu)
- Sofia Gateway : add new choose lists for selecting codecs
- Add sip profile DTMF options (pass-rfc2833)
- Add new rtp_rewrite_timestamps sofia profile option
- Visitors and web interface use stats
- Admin CDR panel : show minutes / sell / cost / margin corresponding to selection
- New dashboard : revenue / cost / minutes / calls stats
- documentation update for installation of 1.4 freeswitch version
- web country blocker based on visitor’s ip. Databases : freegeoip.net and/or maxmind
- detailed customers, providers and destinations stats
Modifications
- Django 1.6 migration
- All dependencies are up to date
- Optimisation of customer sip parameter and customer sip UA codecs selection
Bug corrections
- Add new codec options in Customer sip accounts and sip profiles : G711u&G711a and G711a&G711u
- Destination number is checked before LUA
- Recurrent tasks working with new chronicler version