Wednesday, January 12, 2011

Simple Server Security

There are many security procedures and policies out there these days, and many of them overlook the simple things that can increase the security of your servers and networks in the production environment. This blog article will focus on some simple measures that are easy to implement.

Security through obscurity.

  1. Don't use descriptive DNS entries. I have seen many companies with descriptive DNS entries where there is no requirement and that can direct someone to the most critical elements of your network. Examples are, router.domain.tld, firewall.domain.tld, pptp.domain.tld. There is no requirement in DNS naming conventions and when you pick the names for these and other servers keep in mind that automated attacks may single out descriptive names like smtp.domain.tld. Sure it's easier to remember the hosts because of the descriptive DNS entries but why take the risk when even a simple naming convention change could save you some grief. What if you used something like 01router.domain.tld, or routera.domain.tld. You get the idea.
  2. Don't run ssh, ftp, telnet, plesk, or webmin on a standard port. You run the risk of being the victim of a automated attack. Any service that listens can run on a non standard port. Of course www, smtp, and the like you should use the standard ports but most everything else can be changed to a different port, however things like network devices like routers, firewalls, and web accelerators should have their administration interface disabled or configured on a different port.
    • Changing the port that sshd listens on.
      • Edit the /etc/ssh/sshd_conf file and change the port to something other than 22 and make sure only protocol 2 is enabled. Make sure you uncomment PermitRootLogin yes to deny root logins, this requires users to either su to root or use sudo for superuser commands.
    • To change the port for Webmin you need to login to do the following.
      • Log on to Webmin
      • Click on the Port and Address icon on the modules main page
      • Change the port number by entering a number into the Listen on port field
      • Hit the Save button to use the new settings.
    • Changing the port on Plesk is not recommended by the manufacturer however you can do it.
      • Edit the Apache configuration file %plesk_dir%admin/conf/httpd.conf
      • Find the line Listen 8443
      • Replace with Listen IP.ADDRESS:8444 or whatever port you would like to use.
      • NOTE: In the case of Plesk running on Virtuozzo Virtual Environment, port changing can lead to VZPP-Plesk integration failure.
  3. When using web applications change the default url to be anything but the default URL. A good example is http://www.domain.tld/mail for a webmail interface, even using mail1 will save you from an automated attack. Other examples are /stats, /awstats, /webstats, /forum, /cart, even changing /cgi-bin to something like /cgi-bin1 can be a bit of work modifying code or config files but it's well worth it.
  4. Never leave any tools installed for compiling applications this way if someone does get in they can't build applications to run.
  5. Only install packages from trusted sources. Sure it's nice to have the latest PHP with all the bells and whistles but you could install some code that has a built in exploit if you download a package that was not hosted on a secure server.
  6. Monitor installed packages daily. Add a daily cron job that counts the installed packages and compares them against a file which contains the known number of installed packages which emails you when the package count changes. Don't forget to update the file after upgrading the system or you will get false positives
  7. If you run a server that does not permit command line access make sure all the users have their shells set to something that does not give them a command prompt if they attempt to login, like /sbin/nologin and include a script in the shell environment so if someone does run a shell it emails you the server's name and the last 5 lines of log file that tracks ssh access or logins. Sure it may be a pain to get an email every time you login, but it's not if you catch someone login who should not be logging in with this simple method.
  8. Make sure standard scripts have non standard names, a big mistake is ForMail.pl, you can easily rename this to sendmemail.pl or something so an automated attack can't find it. This will work for things like /awstats also, you simply edit the /etc/httpd/conf.d/awstats.conf and add a 1 or something, again an automated attack can't find it then.
  9. Use a tmpfs.img to mount /tmp and /var/tmp with the noexec,nodev,nosuid flag to make global writable filespace more secure as malicious software can't be executed and they are the most common locations that exploits are run.
    This is quite an important step so don't leave this out.
    • Make a 300mb tmp file, you can adjust this if you need more space.

      cd /dev
      dd if=/dev/zero of=tmpfs.img bs=1024 count=300000
      mke2fs /dev/tmpfs.img
      
    • Backup the current tmp directory contents
      cp -pR /tmp /tmp.old
      
    • add the following line to /etc/fstab

      /dev/tmpfs.img /tmp ext2 loop,nosuid,noexec,nodev,noatime,rw 0 0
    • Mount the new filesystem on /tmp and copy the files back, then link /var/tmp so it's secure also.
      mount -o loop,nosuid,noexec,nodev,noatime,rw /dev/tmpfs.img /tmp
      chmod 1777 /tmp
      mount -o remount /tmp
      cp -R /tmp.old/* /tmp/
      rm -rf /var/tmp
      ln -s /tmp /var/tmp
      
  10. Make sure all passwords are complex and changed at a minimum 30 day interval.

If you need further assistance with this or any other open source application or issue, the experts at Pantek Inc. are available 24/7 at info@pantek.com, 216-344-1614, and 877-LINUX-FIX.



Thursday, December 30, 2010

SNMP Monitoring with Cacti

One of the easiest and most efficient methods of obtaining server or network statistics is to configure and install Cacti on a rpm/yum based system such as RedHat, CentOS, or FedoraCore. This post covers the basics of getting Cacti working on a RedHat or yum based system and monitoring the stats that are available on that system. I also cover the source method of installing Cacti for advance users at the bottom of the basic install/config.

Yum install method

You need to install Cacti, snmpd, httpd, php, php-mysql, php-snmp, MySQL and MySQL Server, if you have any of these installed you can omit them from the command below.

Run the command:
yum install httpd cacti net-snmp php php-mysql php-snmp mysql mysql-server

Next modify the /etc/httpd/conf.d/cacti.conf (allow from line) to allow your local network:
Allow from 192.168.0.
if that's your network.

Restart apache:
service httpd restart

Make sure apache, mysqld, and snmpd start at boot.
chkconfig httpd on
chkconfig mysqld on
chkconfig snmpd on

Make sure that snmpd accepts public as community from localhost.

You can use the command
snmpconf -g basic_setup
to generate an snmpd.conf file.

Restart snmpd:
service snmpd restart

Yum should have setup the cacti database, if it did not then do the following:

mysqladmin create cacti
mysql cacti

Create mysql user for cacti (use a decent password, not just password):
mysql> GRANT ALL ON * . * TO 'cactiuser'@'localhost' IDENTIFIED BY 'password';

Enable the user and privileges for the user:
mysql> flush privileges;

If you are running a yum based distribution then you should be able to go to:
http://serverip/cacti

You will be presented with the Cacti Installation Guide, click Next >>

Since this is a New Install you will click Next >> again.

Be sure that the values are correct and all the fields have [FOUND] above them, if they
do not then correct them and click Finish.

The default User Name is admin, and the default Password is admin, you will be forced to change this so pick a secure password

Now you should be in the console, click Devices, click localhost, now click Create Graphs for this Host, check all the check boxes at the left in the Graph Templates, and Data Query sections then click create. Now click create again.

Now if you click the graphs and you should be able to see the start of the graphs that are being created for the local host. These will take a bit of time to populate so expect to see data in about 10 minutes.


Source Method

To install via the source method, make sure you have the following required software installed and configured:
Apache
RRDTool 1.0.49 or 1.2.x or greater
MySQL 4.1.x or 5.x or greater
PHP 4.3.6 or greater, 5.x greater highly recommended for advanced features

Yum should need to setup the cacti database, do the following:
mysqladmin create cacti
mysql cacti

Create mysql user for cacti (use a decent password, not just password):
mysql> GRANT ALL ON * . * TO 'cactiuser'@'localhost' IDENTIFIED BY 'password'; 

Enable the user and privileges for the user:
mysql> flush privileges;

Download cacti-xxxxx.tar.gz from sourceforge to /var/www/html or wherever your webserver DocumentRoot is located.

Untar gzip the file:
tar -zxf cacti-xxxxx.tar.gz

Rename the directory this creates
mv cacti-xxxxx cacti

Add a cacti user:
adduser -d /var/www/html/cacti cactiuser

Change the owner of the files to the user cacti:
chown -R cacti:cactiuser /var/www/html/cacti

Populate the cacti database (use your values for user and password)
mysql cacti -u cactiuser -ppassword < /var/www/html/cacti/cacti.sql
Edit the /var/www/html/cacti/include/config.php file to specify the user+password: Add the Cacti poller job as a cron job:
crontab -e
Add the following line:
*/5 * * * * cacti1 php /var/www/html/cacti1/poller.php > /dev/null 2>&1


Now you can go to http://serverip/cacti

You will be presented with the Cacti Installation Guide, click Next >>

Since this is a New Install you will click Next >> again.

Be sure that the values are correct and all the fields have [FOUND] above them, if they
do not then correct them and click Finish.

The default User Name is admin, and the default Password is admin, you will be forced to change this so pick a secure password

Now you should be in the console, click Devices, click localhost, now click Create Graphs for this Host, check all the check boxes at the left in the Graph Templates, and Data Query sections then click create. Now click create again.

Now if you click the graphs and you should be able to see the start of the graphs that are being created for the local host. These will take a bit of time to populate so expect to see data in about 10 minutes.

As always if you need further assistance with this or any other open source application or issue, the experts at Pantek Inc. are available 24/7 at info@pantek.com, 216-344-1614, and 1-877-LINUX-FIX! We look forward to working with you.

Monday, November 15, 2010

Simple Linux HA web Cluster with minimal resources required

All you need is a single server to feed your High Availability Network Cluster.

This example will provide for Apache HA without anything complex like session handling, and will focus on the RHEL version of Linux High Availability.

The packages required:

piranha
ipvsadm
arptables_jf

You will need a load balancer machine to run Linux HA. In this example we will use Piranha and set the load balancer up in a weighted least connection configuration.

On the load balancer server you need the following:
Install piranha, and ipvsadm

The required lines for the configuration of the load balancer are in the file: /etc/sysconfig/ha/lvs.cf

primary = ip.address.of.this.server
service = lvs
keepalive = 6
deadtime = 18
network = direct
debug_level = 0
virtual balanced_www {
     address = public.ip.address eth0:0
     vip_nmask = 255.255.255.0
     active = 1
     port = 80
     send = “GET / HTTP/1.0\r\n\r\n:
     expect = “HTTP”
     load_monitor = none
     scheduler = wlc
     protocol = tcp
     timeout = 5
     reentry = 10
     server webserver1 {
          address = ip.address.of.webserver1
          active = 1
          weight = 1
     }
     server webserver1 {
          address = ip.address.of.webserver2
          active = 1
          weight = 1
     }
}

Beware, the file above will fail if there is any additional whitespace or there are any comments in the file.
Also: do not worry about the eth0:0 ip address, as lvs will bring that up and down as required when you start the daemon.

On both webservers you need the following file:

/etc/sysctl.conf

net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.eth0.arp_ignore = 1 net.ipv4.conf.eth0.arp_announce = 2

Now run sysctl -p this will activate the new rules which will reload automatically upon reboots.

You will also need the following arptables_jf rules which you can add prior to the ifconfig line in the /etc/rc.d/rc.local file

On webserver1
arptables_jf -A IN -d ip.address.of.webserver1 -j DROP
arptables_jf -A OUT -d public.ip.address.of.webserver -j mangle --mangle-ip-s ip.address.of.webserver1

On webserver2
arptables_jf -A IN -d ip.address.of.webserver1 -j DROP
arptables_jf -A OUT -d public.ip.address.of.webserver -j mangle --mangle-ip-s ip.address.of.webserver1

On each server you need to assign an alias to the ethernet device that the ip.address.of.webserver is on and give that the public.ip.address.of.webserver which you can do by adding the following line to your /etc/rc.d/rc.local

ifconfig eth0:0 public.ip.address.of.webserver netmask.of.ip.address up

Don't worry about having the same IP address on 3 servers, the only one recognized is the IP address on the load balancer.
Once this is done then you will need to start the load balancer by running pulse on the load balancer:

service pulse start

Now you have a webserver that is load balanced and has high availability.

To test this watch the logs on the load balancer:

tail -f /var/log/messages

Now stop one of the webservers, or reboot it. Nanny will determine there is a connection failure and it will remove that webserver from the cluster.

This configuration works the same for up to 256 webservers, you just need to replicate the lines in the lvs.cf and setup all the other servers the same way you setup the two above.

Monday, November 1, 2010

Customizing your spamassassin mail filtering

Thousands of mail servers everyday pass millions of messages through spamassassin, yet most of these installations are using only the standard spamassassin rules. Many servers aren't taking advantage of many of the great features spamassassin has to offer.

The first thing you need to know about enabling custom rules and setting up spamassassin in general is this: do your work in local.cf or unique files call from local.cf and do NOT change the default files for the rules. When there are updates your changes will be overwritten if you modify other rules.

If you open local.cf you will see a default file with some commented out common features, the first feature we want to enable is Bayesian filtering. You can do this by adding the following to the bottom of the file:

use_bayes 1
#bayes_auto_learn 1
bayes_ignore_header X-Bogosity
bayes_ignore_header X-Spam-Flag
bayes_ignore_header X-Spam-Status

This will enable Bayesian filtering and prevent the Bayesian filtering from relying on headers that maybe forged or set by spamassassin itself in other areas. In addition we tell the Bayesian filters to NOT auto classify specific messages as spam or not spam based on statistical analysis... this is a feature will will want eventually but not until we have at least a few hundred of messages classified each as spam and ham.

How do we do manual classification of messages? We use the sa-learn program... it's very easy. On the server open your mailbox in mutt (mutt -f /path/to/box/or/Maildir) then we can save the messages that are SPAM into a spam-folder and the messages that are HAM into a ham folder. Once we have done this for a few hundred messages we run sa-learn against them and classify them.

core:~# sa-learn --showdots --spam /home/testuser/Maildir/spammy
core:~# sa-learn --showdots --ham /home/testuser/Maildir/goodmail

This will teach spamassassin about the specific messages we are receiving... and teach it about mail it shouldn't mark as spam. Once we have at least 100 of each we can turn the bayes_auto_learn on by uncommenting it from the local.cf file. Once we do this spamassassin will then mark items as spam and ham automatically when they are on the extreme ends of the scale. There are some additional useful items to add to the local.cf for bayes filtering as well:

bayes_auto_learn_threshold_spam 10
bayes_auto_learn_threshold_nonspam 0.50

These tell spamassassin to use a threshold score of 10 before adding a message to the bayes database as spam, and it must have a lower score than 0.50 to be auto classified as ham. These are good starting values that can be later tweaked downward as the system becomes more familiar with both types of messages your network receives.

If your mail server is single purpose and doesn't have a wide variety of perl libraries you should probably have at least Net::DNS and its pre-requisites installed to correctly utilize spamassassin's rbl checks.

The next item to review is dns block-lists. Many people feel strongly regarding these either in the positive or negative. To enable them you simply add the following to the local.cf file:
skip_rbl_checks 0

to disable:
skip_rbl_checks 1

You can further customize which lists you wish to set scores for by setting the actual rule name of the list with a score of zero. For example if you wish to disable the dynamic ip address check for sorbs, you would find it in the 20_dnsbl_tests.cf

header RCVD_IN_SORBS_DUL        eval:check_rbl('sorbs-lastexternal', 'dnsbl.sorbs.net.', '127.0.0.10')
describe RCVD_IN_SORBS_DUL      SORBS: sent directly from dynamic IP address
tflags RCVD_IN_SORBS_DUL        net

Which shows the name is RCVD_IN_SORBS_DUL. To disable it in the local.cf you would add a line like this:
score RCVD_IN_SORBS_DUL 0 
while still keeping the rest of the dnsbls intact.

A further thing which many people neglect to do is alter the weighting of the rules. This is as easy as determining the rules name and applying a score to it in the local.cf file.

score RULE_NAME newscore

For example, if you wanted to alter the weighting for the rules related to some types of viagra spam you might add the following.

score TT_OBSCURED_VIAGRA 5
score FM_VIAGRA_SPAM1114 4
score DRUG_ED_GENERIC 3
score DRUG_ED_ONLINE 3
score DRUG_ED_CAPS 2

The last thing you might want to do is write a filter for a custom type of spam you're receiving. Lets make the assumption you're frequently getting a spam for fooglesnaps. The rule for this is very easy to write.

body LOCAL_FOOGLESNAPS_RULE /\bfooglesnaps\b/i
score LOCAL_FOOGLESNAPS_RULE 0.5
describe LOCAL_FOOGLESNAPS_RULE  This is to help catch the fooglesnaps spam.

What this rule says is anytime you see fooglesnaps regardless of case (case insensitive) with a word break on both sides, this rule applies. The next line says what the base scoring for the rule is, in this case half a point. Always start around 0.1-0.5 and work your way up to make sure you don't mark mail incorrectly. The final line is just a human readable description of the rule. You can use pretty much any perl regex rule to filter your spam. The sky is the limit, however you should be sure you NEED a new rule and can't just use a black or white-list to correct your delivery issue because rules are more expensive on the cpu and memory than simple black and white lists.

This covers some of the basic and common setup tasks for a new spamassassin installation that many users miss or or don't enable. As always if you need further assistance with this or any other open source application or issue, the experts at Pantek Inc. are available 24/7 at info@pantek.com, 216-344-1614, and 1-877-LINUX-FIX! We look forward to working with you.

Monday, October 18, 2010

OpenVZ, backups, and you.

Virtualization technologies are moving to the forefront of computing. VMWare, OpenVZ (Virtuozzo), VirtualBox, Xen, KVM, Hyper-V... the list grows. Today we'll take a look at the most basic and critical of functions in any environment - backups. In today's example we'll take a look specifically at backups in OpenVZ. First, lets talk about what kind of virtualization OpenVZ provides.

OpenVZ is OS level virtualization, as opposed to the full virtualization you see in VMWare or the paravirtualization options you see with KVM. The system functions as a series of chrooted jails that completely segregate each container from the other containers on the system. Because they share most common files there is often a significant savings of disk space on a host with many containers. Because there is less emulation of hardware occurring, this also tends to yield good performance compared to paravirtualzation. The ability to update the host alone and subsequently all guests relying on the host as well has made this an attractive option to many hosting providers and companies with a large infrastructure to maintain.

So let's dig into backups a bit. OpenVZ provides vzdump for working with containers. Vzdump takes a snapshot of the configuration and private space of a container and backs it up to a directory you specify as a tar ball. This backup can be later restored to the same or a different machine with little difficulty.

There are three basic forms that vzdump can operate in. The first is stop the container and back it up, which requires significant downtime. The second is rsync and suspend/resume the container, requiring minimal downtime. The third involves the use of lvm2 shadow snapshots, which requires no downtime.

In it's most simple form it consists of the following:

vzdump [container-id-number]

This will simply take the private area and configuration file and dump them as a tar ball to the default directory (/vz/dump). It does stop the container to perform this operation which can take anywhere from five minutes to several hours to complete. For development servers this is an acceptable option, but for most production servers, this kind of downtime is unacceptable.

The second way we can perform backups is to suspend the vm long enough for rsync to take a snap shot of the differences between the start of the backup and the completion. This still results in downtime but it is minimal. This makes this option much more desirable.

vzdump --suspend [container-id-number] --dumpdir /backups

The options here are fairly simple. The --suspend tells the vzdump program to use rsync and the --dumpdir parameter tells vzdump to place the backups outside of the default area in the /backups directory. The short amount of downtime makes this a much more acceptable method of backing up for most companies. Most of us want no downtime, which brings us to our third option.

The third option is to use lvm2 to create a snapshot of the os. This option isn't syntactically more difficult than the previous two options, but it does offer a full backup with no downtime.

vzdump --snapshot [container-id-number]

Here we take a simple backup and dump it to the /vz/dump directory (the default), and we tell vzdump to make it a snapshot backup so there is no downtime involved in getting the backup. This is by far the best option for most operators, as host downtime can often lead to lost revenue.

So now you have a backup made, what do you do with it? Well, vzdump is the answer there as well. The tool that makes the backups also restores them. The syntax for that is what you would expect.

vzdump --restore /backup/vzdump-containeridnumber.tar [container-id-number]

Some versions of OpenVZ do not support vzdump --restore and if this is the case then you should look at using vzrestore like so:

vzrestore /backup/vzdump-containeridnumber.tar [container-id-number]

This will provide exactly the same effect as using vzdump --restore.

If you're unsure of the id of your container you can get a full list of ids by running vzlist. There is always the option of using --all instead of a specific container id which will perform that operation on all containers running on that specific host.

This covers the basics of using vzdump and how to restore the backups created with it. Virtuozzo offers a lot of flexibility in performing backups and if the option you prefer isn't available for your os, there are a lot of third party tools available as well. For example, vzbackup from Parallels for Virtuozzo which supports backing up to remote sites. You can even schedule simple tar backups, remote rsync backups, or code your backups to fit into your existing backup scheme. Just be sure to correctly backup and test your restores no matter what method you use, any backup is only as good as your ability to restore it!

As always, if you need further assistance with this or any other open source application or issue, the experts at Pantek Inc. are available 24/7 at info@pantek.com, 216-344-1614, and 877-LINUX-FIX! We look forward to working with you.

Friday, September 10, 2010

Tar, from basic to advanced a high quality reliable backup tool

Tar is one of the earliest applications used for backups in unix and its still a very functional backup tool. Tar is both the file format the tar application generates and the application itself and for that reason the files generated by tar are generally referred to as tarballs.

Tar stands for Tape ARchiver and it backs up in a sequential manner, storing permissions, directory structure, and filesystem information as well as special attributes by default. Typically a tarball will have .tar as an extension unless it's compressed in which case you'll typically have .tar.ext, in windows the 3 letter extension convention is typically followed by shortening the file names .tar.gz -> .tgz, .tar.bz2 -> .tb2, etc. The actual structure of a tarball is fairly simple and is a concatenation of the files being archived each with a small header (512 bytes) and ending with zero padding rounded up to the next number divisible by 512 plus 1024 bytes of 0's. This makes the record divisible without remainder by 512 bytes and delineates the end of the record. Therefore, anything backed up in a tar archive will be a minimum of 1536 bytes per file plus necessary header, ownership, and file system information. This yields a realistic minimum size of ~8-12kb. The biggest problem with tar is that it is entirely sequential, and there is no metadata relating to where to find each individual piece of information in the tarball (like an index or table of contents), and thus its often hard to extract a single piece quickly in a large tarball.

So now that we understand the basics of what tar is, lets talk about how to use it...

The most common options we'll use with tar for creation of an archive are c (create), f (file), v (verbose), z (gzip), p (preserve acl), and j (bzip2). Lets talk about what a few of these do. Any time you create a new tarball you will use the c option, this means create. Most often, unless you are backing up to tape, you will use the f option as well. This means read and write your input to and from a file. If you've got ACLs you would like backed up you need to use the p option. The z and j options are mutually exclusive. Although less common, you may also see other extensions that denote alternate compression formats (lz for example), these however are not standard and change from version to version of tar.

The most common options for decompression of a tarball are x (extract) and t (test). Extract does exactly what you imagine it would do-- it extracts the contents of the tar ball to the current location unless you specify an alternate location with the -C option. Test shows you what files are in the archive and where they extract to.

You will also occasionally see the u (update) option and it cannot be used in conjunction with the x (extract) or c (create) options. It updates the archive with additional files and changes to the existing files on a file level (not block). So lets see a few examples of commands you will commonly use with tar.

tar -xvzf tarball.tar.gz

This command will extract a gzip compressed tarball into the current location with the stored path.

tar -cvzf tarball.tar.gz .

This command will store the current directory as a gzip compressed tarball.

tar -tvzf tarball.tar.gz

Will display the contents of the tarball without extracting anything.

Those are the bare minimum basics of tar and with them they cover 90%+ of all times you will use tar... but tar has many more features available.

For instance you can exclude files by using the --exclude "path/filename" syntax.
tar --exclude "/etc/resolv.conf" --exclude "/dev" -czvf tarball.tar.gz /


One caveat for the --exclude syntax, some versions of tar require the excludes to occur before the path to tar, some require it after. Check the man page for the syntax for the version of tar you're using.

You can use -C to extract a tarball to a different directory.
tar -xzvf tarball.tar.gz -C /usr/local/src


You can utilize the -f option to extract to standard out by specifying the filename as -
cat /usr/local/src/tarball.tar.gz | tar -xzvf -


The last brings us to one nice option you can use with tar, because it correctly handles piping you can pipe it over remote connections like netcat or ssh--
cd /usr/local/configuration && ssh root@hostname.domain.tld "cat /backups/server1/configuration.tar.gz" | tar -xzvf -

tar -cvzf - /usr/local/configuration | ssh root@hostname.domain.tld "cat > /backups/server1/configuration.tar.gz"


The last thing people generally want to do with tar is either update an existing tarball with additional files or create an incremental backup from an existing tarball and directory structure this is fairly easily done by using the following commands, first to update a tar ball...

tar -cvzf tarball.tar.gz /path/to/backup

First create an initial tarball as above

tar -uzvf tarball.tar.gz /path/to/backup

Then update it with the changed contents.

Easy enough, but what if you need previous revisions? As easy as setting up tar to do incremental backups.

tar --listed-incremental /backups/server1/index.snar -czvf $(date +%Y%m%d%H%M%S) /path/to/backup 

This command will update the original tarball to make it current (this will overwrite existing files)

tar --listed-incremental /backups/server1/index.snar -cfvz $(date +%Y%m%d%H%M%S).tar.gz /path/to/backup

The major requirement if you're using this method is that you decompress all of the files in order as tar will remove and create files as required which is fairly trivial with a simple for loop.

As you can see tar is a very functional backup tool that exists on almost every unix distribution world wide, so the next time you're looking for a quick backup solution without installation of additional applications take a look at tar, it really is a high quality, tested backup tool that enables you to reliably archive and restore data in a variety of ways.

Remember, backup, backup, backup-- backup before you perform any system changes and you can save yourself dozens of hours of headache.

As always if you need further assistance with this or any other open source application or issue, the experts at Pantek Inc. are available 24/7 at info@pantek.com, 216-344-1614, and 877-LINUX-FIX.

Friday, June 18, 2010

FOP2 Installation on Trixbox 2.8

Trixbox 2.8 is a nice program but the FOP that comes with it is heavily outdated and lacking the visual and functional appeal you would expect in a project that is as slick as Trixbox. Never fear however, that can be solved by installing FOP2 from the same author. The only disadvantage of FOP2 over FOP is that it requires a site license. This costs $40 for the entire site, which is a steal considering how much better it functions than the original FOP and how affordable that is compared to other operator panels. If you don't have more than 15 extensions, queues, conferences and trunks you can use it in trial mode and see all the features as well. You can download a copy of FOP2 and register it at the FOP2 site which is located at http://www.fop2.com/. Without further ado here is the basic installation procedure.

First and foremost before any changes to a system... ensure you have a valid working backup!

Make a temporary directory and download the package and uncompress it.
mkdir -p /usr/local/src/packages/fop2
cd /usr/local/src/packages/fop2
curl http://www.fop2.com/file.php?file=1 > fop2.tgz
tar xfvz fop2-2.11-centos5.i386.tgz


Then change directory to fop2 and run the installation, this requires make to be installed.
cd fop2
make install

This will copy the necessary files to various locations on the system, mostly under /usr/local/fop2 and /var/www/html/fop2.

Next stop the original FOP and copy the extensions override to the appropriate file in asterisk.
amportal stop_fop
cd /usr/local/fop2
cat extensions_override_freepbx.conf >> /etc/asterisk/extensions_override_freepbx.conf


After that step is complete we need to install the mysql database for the visual phone book.
cd /var/www/html/fop2
mysqladmin -u root -p create fop2
mysql -u root -p fop2 < mysql.db
mysql -u root -p -e "grant all privileges on fop2.* to fop2@'localhost' identified by 'xxxxxxxxxxx'"
Next lets edit a few files to set credentials and privileges, the first file is the config.php file in the current directory, it needs to have the database credentials you just setup put in it.
vi config.php
The asterisk manager should have originate rights so edit...
vi /etc/asterisk/manager.conf
and add ",originate" to the end of the read and write lines. We need to make sure we generate callevents so add "callevents=yes" to to the sip_custom.conf file.
vi /etc/asterisk/sip_custom.conf
For the queues_custom.conf file you need to add "eventwhencalled=yes" to the queues as an example:
vi /etc/asterisk/queues_custom.conf
[testqueue]
eventwhencalled=yes
Finally verify that the auto config script for users will run correctly by executing...
/usr/local/fop2/autoconfig-users-freepbx.sh
If you have extensions that start with the number 0 you will likely need to add 10# to force it to use decimal and not octal numbers. Finally have FOP2 perform an internal self test by running...
/usr/local/fop2/fop2_server --test
If all is well at this point we're ready to move onto the final step to make amportal start FOP2 instead of FOP.
cd /var/lib/asterisk/bin
mv freepbx_engine freepbx_engine.orig
You can either download the updated script from http://www.cadvision.com/blanchas/freepbx_engine or alternately paste it in from here
#!/usr/bin/env bash

ROOT_UID=0       # root uid is 0
E_NOTROOT=67     # Non-root exit error


echo
# check to see if we are root
if [ "$UID" -ne "$ROOT_UID" ]
then
echo "Sorry, you must be root to run this script."
echo
exit $E_NOTROOT
fi

# make sure config file exists
if [ ! -e "/etc/amportal.conf" ]       # Check if file exists.
then
echo;
echo "/etc/amportal.conf does not exist!";
echo "Have you installed the AMP configuration?";
exit;
fi
# Set some defaults which can be re-defined in amportal.conf
AMPDEVUSER=asterisk
AMPDEVGROUP=asterisk
AMPASTERISKUSER=asterisk
AMPASTERISKGROUP=asterisk
AMPASTERISKWEBUSER=$AMPASTERISKUSER
AMPASTERISKWEBGROUP=$AMPASTERISKGROUP
AMPVMUMASK=077

. /etc/amportal.conf

if [ $ASTRUNDIR = /var/run ]
then
echo "**** ERROR IN CONFIGURATION ****"
echo "astrundir in /etc/asterisk/asterisk.conf is set to '/var/run' - THIS IS WRONG."
echo "Please change it to something sensible (eg, '/var/run/asterisk') and re-run"
echo "install_amp"
exit;
fi

if [ ! -d "$ASTRUNDIR" ]
then
echo "**** WARNING: ERROR IN CONFIGURATION ****"
echo "astrundir in /etc/asterisk/asterisk.conf is set to $ASTRUNDIR but the directory"
echo "does not exists. Attempting to create it with: 'mkdir -p $ASTRUNDIR'"
echo
mkdir -p $ASTRUNDIR
RET=$?
if [ $RET != 0 ]
then
echo "**** ERROR: COULD NOT CREATE $ASTRUNDIR ****"
echo "Attempt to execute 'mkdir -p $ASTRUNDIR' failed with an exit code of $RET"
echo "You must create this directory and the try again."
exit
fi
fi

chown_asterisk() {
echo SETTING FILE PERMISSIONS

chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $ASTRUNDIR
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP /etc/asterisk
chmod -R g+w /etc/asterisk
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $ASTVARLIBDIR
chmod -R g+w $ASTVARLIBDIR
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $ASTLOGDIR
chmod -R g+w $ASTLOGDIR
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $ASTSPOOLDIR
chmod -R g+w $ASTSPOOLDIR
chown -R $AMPASTERISKWEBUSER:$AMPASTERISKWEBGROUP $AMPWEBROOT/admin
chmod -R g+w $AMPWEBROOT/admin
chown -R $AMPASTERISKWEBUSER:$AMPASTERISKWEBGROUP $FOPWEBROOT
chmod -R g+w $FOPWEBROOT
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $AMPWEBROOT/recordings
chmod -R g+w $AMPWEBROOT/recordings
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $AMPWEBROOT/_asterisk
chmod u+x,g+x $ASTVARLIBDIR/bin/*
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $ASTVARLIBDIR/bin/*
chown -R $AMPASTERISKUSER:$AMPASTERISKGROUP $AMPBIN/*


if [ "$ASTAGIDIR" != "" ]; then
chmod u+x $ASTAGIDIR/*
else
chmod u+x $ASTVARLIBDIR/agi-bin/*
fi

chmod u+x,g+x $AMPBIN/bounce_op.sh
chmod u+x,g+x $FOPWEBROOT/*.pl
chmod u+x $FOPWEBROOT/safe_opserver
chown $AMPASTERISKUSER /dev/tty9

# Ensure that various hardware devices are owned correctly.
[ -e /dev/zap ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/zap
[ -e /dev/dahdi ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/dahdi
[ -e /dev/capi20 ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/capi20
[ -e /dev/misdn ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/misdn
[ -e /dev/mISDN ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/mISDN
[ -e /dev/dsp ] && chown -R $AMPDEVUSER:$AMPDEVGROUP /dev/dsp

echo Permissions OK
}

check_asterisk() {
# check to see if asterisk is running
# Note, this isn't fool-proof.  If safe_asterisk is constantly restarting a dying asterisk, then there is a chance pidof will return non zero.  We call this twice to reduce chances of this happening
pid_length=`pidof asterisk|awk '{print length($0)}'`
if [ "$pid_length" == "0" -a "$pid_length" != "" ]
then
killall -9 safe_asterisk
killall -9 mpg123 > /dev/null
echo
echo "-----------------------------------------------------"
echo "Asterisk could not start!"
echo "Use 'tail $ASTLOGDIR/full' to find out why."
echo "-----------------------------------------------------"
exit 0
fi
}

run_asterisk() {
# check to see if asterisk is running
echo
echo "STARTING ASTERISK"
pid_length=`pidof asterisk|awk '{print length($0)}'`
if [ "$pid_length" != "0" -a "$pid_length" != "" ]
then
echo "Asterisk is already running"
else
# su - asterisk -c "export PATH=$PATH:/usr/sbin && export LD_LIBRARY_PATH=/usr/local/lib && /usr/sbin/safe_asterisk"
export LD_LIBRARY_PATH=/usr/local/lib
umask $AMPVMUMASK
/usr/sbin/safe_asterisk -U asterisk -G $AMPASTERISKGROUP
sleep 5
check_asterisk
sleep 1
check_asterisk
echo "Asterisk Started"
fi
}

stop_asterisk() {
echo
echo "STOPPING ASTERISK"
pid_length=`pidof asterisk|awk '{print length($0)}'`
if [ "$pid_length" != "0" -a "$pid_length" != "" ]
then
/usr/sbin/asterisk -rx "core stop gracefully" | grep -v "No such command"
/usr/sbin/asterisk -rx "stop gracefully" | grep -v -E "No such command|deprecated"
echo "Asterisk Stopped"
fi
}

check_fop2() {
#check to see if FOP2 is running
pid_length=`pidof -x fop2|awk '{print length($0)}'`
if [ "$pid_length" == "0" -a "$pid_length" != "" ]
then
ps -ef | grep fop2 | grep -v grep | awk '{print $2}' | xargs kill -9
echo
echo "-----------------------------------------------------"
echo "The FOP2's server could not start!"
echo "Please correct this problem"
echo "-----------------------------------------------------"
exit 0
fi
}

run_fop2() {
# check to see if FOP2 is running
echo
echo "STARTING FOP2 SERVER"
pid_length=`pidof -x fop2|awk '{print length($0)}'`
if [ "$pid_length" != "0" -a "$pid_length" != "" ]
then
echo "FOP2 server is already running"
else
/etc/init.d/fop2 start
# Don't really like to run fop2 with root privileges. should be user: AMPASTERISKUSER = asterisk
fi
}

stop_fop2() {
echo
echo "STOPPING FOP SERVER"
/etc/init.d/fop2 stop
}

kill_amp() {
echo
echo "KILLING AMP PROCESSES"
killall -9 safe_asterisk
killall -9 asterisk
killall -9 mpg123
ps -ef | grep safe_opserver | grep -v grep | awk '{print $2}' | xargs kill -9
killall -9 op_server.pl
}

case "$1" in
start)
chown_asterisk
run_asterisk
if [ -z "$FOPRUN" -o "$FOPRUN" == "true" -o "$FOPRUN" == "TRUE" -o "$FOPRUN" == "True" -o "$FOPRUN" == "yes" -o "$FOPRUN" == "YES" -o "$FOPRUN" == "Yes" ]
then
if [ -z "$FOPDISABLE" -o "$FOPDISABLE" == "false" -o "$FOPDISABLE" == "FALSE" -o "$FOPDISABLE" == "False" -o "$FOPDISABLE" == "no" -o "$FOPDISABLE" == "NO" -o "$FOPDISABLE" == "No" ]
then
run_fop2
fi
fi
;;
stop)
stop_asterisk
stop_fop2
;;
restart)
stop_asterisk
stop_fop2
sleep 1
chown_asterisk
run_asterisk
if [ -z "$FOPRUN" -o "$FOPRUN" == "true" -o "$FOPRUN" == "TRUE" -o "$FOPRUN" == "True" -o "$FOPRUN" == "yes" -o "$FOPRUN" == "YES" -o "$FOPRUN" == "Yes" ]
then
if [ -z "$FOPDISABLE" -o "$FOPDISABLE" == "false" -o "$FOPDISABLE" == "FALSE" -o "$FOPDISABLE" == "False" -o "$FOPDISABLE" == "no" -o "$FOPDISABLE" == "NO" -o "$FOPDISABLE" == "No" ]
then
run_fop2
fi
fi
;;
stop_fop2)
stop_fop2
;;
start_fop2)
run_asterisk
run_fop2
;;
restart_fop2)
stop_fop2
run_asterisk
run_fop2
;;
chown)
chown_asterisk
;;
kill)
kill_amp
;;
*)
if [ -z "$FOPRUN" -o "$FOPRUN" == "true" -o "$FOPRUN" == "TRUE" -o "$FOPRUN" == "True" -o "$FOPRUN" == "yes" -o "$FOPRUN" == "YES" -o "$FOPRUN" == "Yes" ]
then
if [ -z "$FOPDISABLE" -o "$FOPDISABLE" == "false" -o "$FOPDISABLE" == "FALSE" -o "$FOPDISABLE" == "False" -o "$FOPDISABLE" == "no" -o "$FOPDISABLE" == "NO" -o "$FOPDISABLE" == "No" ]
then
FOPUSAGE="start_fop2|stop_fop2|restart_fop2|"
fi
fi

echo "-------------FreePBX Control Script-----------------------------------------------"
echo
echo "Usage:       amportal start|stop|restart|${FOPUSAGE}kill|chown"
echo
echo "start:       Starts Asterisk and Flash Operator Panel server if enabled"
echo "stop:        Gracefully stops Asterisk and the FOP server"
echo "restart:     Stop and Starts"
if [ -z "$FOPRUN" -o "$FOPRUN" == "true" -o "$FOPRUN" == "TRUE" -o "$FOPRUN" == "True" -o "$FOPRUN" == "yes" -o "$FOPRUN" == "YES" -o "$FOPRUN" == "Yes" ]
then
if [ -z "$FOPDISABLE" -o "$FOPDISABLE" == "false" -o "$FOPDISABLE" == "FALSE" -o "$FOPDISABLE" == "False" -o "$FOPDISABLE" == "no" -o "$FOPDISABLE" == "NO" -o "$FOPDISABLE" == "No" ]
then

echo "start_fop2:   Starts FOP server and Asterisk if not running"
echo "stop_fop2:    Stops FOP serverg"
echo "restart_fop2: Stops FOP server and Starts it and Asterisk if not running"
fi
fi
echo "kill:        Kills Asterisk and the FOP server"
echo "chown:       Sets appropriate permissions on files"
echo
exit 1
;;
esac
Last but not least, lets get permissions set and make changes to the interface to show FOP2
chmod 770 freepbx_engine
chown asterisk:asterisk freepbx_engine
cd /var/www/html/admin/views
cp panel.php panel.php.orig
vi panel.php
cd ../../user/templates/modules/04_fop
cp fop.tpl fop.tpl.orig
vi fop.tpl
In the panel.php change the src to "../fop2/index.html" and in the fop.tpl change the src= to "../fop2/" Now restart asterisk
amportal stop
amportal start


Now you can test your installation by visiting http://host.domain.tld/fop2 and login with your extension.

I would also suggest you install the admin module which is available on the fop2 site for changing passwords and managing what you want on and off the panel.

As always if you need further assistance with this or any other open source application or issue, the experts at Pantek Inc. are available 24/7 at info@pantek.com, 216-344-1614, and 877-LINUX-FIX.