Hardening FreePBX

Sections: 

Hardening FreePBXThis script is a highly modified version of the AsteriskNOW hardening script a copy of which is here.  Some things were added.  Some were changed.  Some things were taken out.  Most importantly, it has been updated to work with newer versions of FreePBX where all the settings that used to be in amportal.conf are now in the Asterisk MySQL database.  As such, it is not compatible with older versions of FreePBX (anything before v2.9) which use the amportal.conf file.

Unlike the original script, this script is (theoretically) designed to work with any distribution or install of FreePBX (such as the FreePBX install procedure on this website) regardless of what the defaults are set to.  This also means it can be (theoretically) re-run on the same server.  All you need is your current MySQL root password.  If you do not know your current MySQL root password and have no way of getting it, this procedure shows how to change it to whatever you want.

This script was tested on:

CentOS v6
Asterisk v1.8
FreePBX v2.10

Installed according to this FreePBX install guide.

Features

Randomized MySQL root password
Randomized Asterisk manager password
Randomized Asterisk database user password
Randomized ARI admin password and leave disabled
Change FreePBX admin to user specified password
Limit MySQL network listening to localhost

Asterisk Database Username

This username resides in /etc/freepbx.conf defined by the value of 'AMPDBUSER'. It is also in /etc/asterisk/cdr_mysql.conf for the asteriskcdrdb database and defined by the value of 'user'.   This script automatically extracts the username from /etc/freepbx.conf for you, it assumes the username is the same for asteriskcdrdb as defined in the cdr_mysql.conf file which it almost always is.  You should double check to make sure that is the case. I'm not aware of any distribution that currently uses a different asteriskcdrdb username but there is no reason you could not do that.  If that were the case this script would need to be modified slightly since it assumes the username is the same and changes the password in both files.

MySQL root Password

You will need to know what your current MySQL root password is if any.  Some distributions may leave it at the default which is blank.  Some may have a publicly known password.  Some ask you for one during the install.

Testing for MySQL root password

You can try log into MySQL root as follows
mysql

If that doesn't work then your root password is not blank.  If you think you know the root password try log in as follows.
mysql -u root -p

Changing MySQL root password

If you cannot get in and you have no way of finding out your current MySQL root password or are not sure where to look you can simply change it.

#service mysqld stop
#mysqld_safe --skip-grant-tables &

You should see mysqld start in safe mode and then get a linux command prompt.  If you don't see a command prompt press the ENTER key and you should get it.

mysql --user=root 
> use mysql;
update user set Password=PASSWORD('new-root-password') where user='root'; 
\q
service mysqld restart

The Script

If you know the MySQL root password you are ready to begin.  I make no guarantees or promises and accept no responsibility whatsoever.  Don't try running this on any in use system without testing it yourself on an experimental system first.  Chances of something going wrong are very high.

#!/bin/bash
clear
echo "--------------------------------------------"
echo "PowerPBX v1 Hardening script"
echo "http://powerpbx.org"
echo "--------------------------------------------"

echo "Don't run this script on this system if you have not thoroughly tested it first"
echo "If you haven't tested it chances are high you will have problems"
echo "--------------------------------------------"
echo "Press any key to continue... (or Ctrl+C to stop now)"
read
echo "First, we need a new admin password (Choose a strong one !)"
read -e -s -p "Admin password : " PasswordAdmin

PasswordManager=`cat /dev/urandom | tr -dc ._[:alnum:] | head -c12`
PasswordRootSQL=`cat /dev/urandom | tr -dc ._[:alnum:] | head -c12`
PasswordAstSQL=`cat /dev/urandom | tr -dc ._[:alnum:] | head -c12`
PasswordARI=`cat /dev/urandom | tr -dc ._[:alnum:] | head -c12`

echo
echo "--------------------------------------------"
echo "Before proceeding please confirm (and write it down somewhere) :"
echo "MySQL root password         : $PasswordRootSQL   (auto-generated)"
echo "Asterisk database user password : $PasswordAstSQL   (auto-generated)"
echo "Asterisk Manager password   : $PasswordManager   (auto-generated)"
echo "ARI admin password          : $PasswordARI   (auto-generated)"
echo "FreePBX admin password      : $PasswordAdmin   (user specified)"
echo
echo "Press any key to continue... (or Ctrl+C to stop now)"
read

echo "Setting stronger permission on asterisk manager configuration..."
chmod 640 /etc/asterisk/manager.conf
echo

echo "Restricted mysql to localhost..."
sed -i "/bind-address.*/d" /etc/my.cnf
sed -i "/\[mysqld\]/a\bind-address = 127.0.0.1" /etc/my.cnf
echo

echo "Changing MySQL root password."
echo "If no root password currently exists press enter at password prompt."
echo "If password fails command will run again."
echo "Press (Ctrl-C) during 2 second pause to exit loop and script."
echo

EXITSTATUS=-1
until [ ${EXITSTATUS} == 0 ]; do
mysqladmin -u root -p password $PasswordRootSQL
EXITSTATUS=$?
sleep 2
done

echo "MySQL root password has now been changed"
echo
echo "Extracting Asterisk database username from /etc/freepbx.conf"
AsteriskDBusername=$(sed -n "s/\$\w\+\['AMPDBUSER'\]\s\+=\s\+'\([^']\+\)';/\1/p" /etc/freepbx.conf)
echo "Asterisk database username = $AsteriskDBusername"

echo "Changing Asterisk database user password in conf files"
sed -i -e "s/\$amp_conf\['AMPDBPASS'\].*/\$amp_conf\['AMPDBPASS'\] = '$PasswordAstSQL';/g" \
/etc/freepbx.conf
sed -i -e "s/password.*/password = $PasswordAstSQL/" /etc/asterisk/cdr_mysql.conf
echo "Asterisk database password has now been changed"
echo

echo "Changing Asterisk database user password in MySQL"
echo "update user set password = password('$PasswordAstSQL') where user='$AsteriskDBusername'" | \
mysql -u root -p$PasswordRootSQL mysql
echo

echo "Changing Asterisk manager password in conf file"
sed -i -e "s/secret.*/secret = $PasswordManager/g" /etc/asterisk/manager.conf
echo
echo "Changing Asterisk manager password in MySQL"
echo "update freepbx_settings set value='$PasswordManager' where keyword='AMPMGRPASS'" | \
mysql -u root -p$PasswordRootSQL asterisk
echo

echo "Changing ARI password..."
echo "update freepbx_settings set value='$PasswordARI' where keyword='ARI_ADMIN_PASSWORD'" | \
mysql -u root -p$PasswordRootSQL asterisk
echo

echo "Changing FreePBX admin password..."
echo "update ampusers set password_sha1 = SHA1('$PasswordAdmin') where username = 'admin'" | \
mysql -u root -p$PasswordRootSQL asterisk
echo

echo "bit of housekeeping to keep unnecessary messages and logging to a minimum..."
echo -e "console =>\nfull => notice,warning,error,verbose" > /etc/asterisk/logger_logfiles_custom.conf
echo

echo "Restarting services...."
service mysqld restart
amportal restart
/var/lib/asterisk/bin/module_admin reload
echo

echo "--------------------------------------------"
echo "You can log into the GUI now with your new FreePBX admin password"
echo
echo "--------------------------------------------"