Monday, April 5, 2010

Buck-security - Security scanner for Ubuntu Servers

Buck-Security is a security scanner for Debian and Ubuntu Linux. It helps you to harden your system by running some important security checks.

For example, it finds world-writable files and directories, setuid and setgid programs, superuser accounts, and installed attack tool packages.

It also checks your umask and checks if the sticky bit is set for /tmp, among other checks.

It was designed for Debian and Ubuntu servers, but can be useful for any Linux system.

By now the following tests are implemented:
* Searching for worldwriteable files
* Searching for worldwriteable directories
* Searching for programs where the setuid is set
* Searching for programs where the setgid is set
* Checking your umask
* Checking if the sticky-bit is set for /tmp
* Searching for superusers
* Checking firewall policies
* Checking if sshd is secured
* Creating and checking checksums of system programs
* Searching for installed attack tools packages


How to run Buck-security in Ubuntu servers
First you need to download latest version from here
unzip the the zip-file.
unzip buck-security_0.5.zip
To start the checks run the buck program (type ./buck while in the buck-security directory).
cd buck-security_0.5
sudo ./buck
For more information check buck security documentation

Saturday, April 3, 2010

Making Bash Error Messages Friendlier

Trapping and Befriending Error Messages


The command line! The bane of the novice Linux user! It's so useful -- yet it can be challenging to learn.


The error messages don't help much. "Command not found." "Permission denied." As a newbie, you need to know more.


Isn't that the right command? Why was permission denied? How are you to figure out what the real problem was? And why can't the shell help you with that?


Ubuntu has taken some steps in that direction already. They've set up the bash shell so that if you get "Command not found", most of the time you'll also see suggestions on what you might have meant: commands that are spelled similarly, or commands that aren't installed along with which package you need to install to get them.


It looks like this:


$ catt /etc/fstab
No command 'catt' found, did you mean:
Command 'cat' from package 'coreutils' (main)
Command 'cant' from package 'swap-cwm' (universe)
catt: command not found


It's an excellent step. Perhaps still not 100% clear -- you still need to know what those packages are and how to install them -- but it's a good start!


But what about other errors, like the all too common "Permission denied"? Ubuntu's error handling uses a function built into bash for that specific purpose, a function called command_not_found_handle that can't be used for other types of errors.


Happily, bash has a more general error trapping mechanism that you can use to handle any kind of error the user might make.


The key is bash's trap command. First you define an error handler function:

function err_handle {
echo "Place your error handling code here"
}


Then use trap to tell the shell to call your error handler any time it gets an error:

trap 'err_handle' ERR


In the error handler, you can check the shell variable $? to find out what the error code was. So the first step is to figure out which errors you need to catch.


How do you do that? The easiest way is to write a very simple error handler that just prints the numeric code.

function err_handle {
status=$?
echo status was $status
}
trap 'err_handle' ERR


Then try typing some commands you know are wrong. For instance, you might misspell the command name:

$ catt foo.html
catt: command not found
status was 127


Or suppose you type the name of an existing file instead of a command:

$ /etc/passwd
bash: /etc/passwd: Permission denied
status was 126


Clearly 126 and 127 are two cases worth handling. There's one other case that's easy for anybody, not just beginners, to hit: a typo in a filename.

$ ls bogusfile
/bin/ls: cannot access bogusfile: No such file or directory
status was 2


So let's catch error 2 as well as 126 and 127. If you have other errors you or people you know tend to hit frequently, you can find out their error codes the same way.


Now you can check in your error handler to make sure you're only handling the types of errors you're prepared to catch:

function err_handle {
status=$?
echo status was $status

if [[ $status -ne 2 && $status -ne 126 && $status -ne 127 ]]; then
return
fi


The next problem is to get the exact line the user typed. You'd think that would be easy, but it's the hardest part of the whole endeavor: bash doesn't give you a good way to do it.


Here's the best I've found, with help from a number of bash hackers:

  # Get the last typed command.
lastcmd=$(history | tail -1 | sed 's/^ *[0-9]* *//')


Then split the line into the command (the first word) and arguments (everything else). You can use bash's read command for that:

  read cmd args <<< "$lastcmd"


Now you know the error code and the command. The rest is just a matter of figuring out what sorts of errors your users are likely to hit, then offering them useful suggestions in each case.



For instance, if the user typed the name of a file instead of an executable program, wouldn't it be handy to check the type of the file and suggest programs they might have intended? Something like this:

$ /tmp
bash: /tmp: is a directory
status was 126
Perhaps you meant: cd /tmp

$ schedule.html
bash: ./schedule.html: Permission denied

schedule.html is an HTML file. Did you want to run: firefox schedule.html

That's easy to do. You 
can check for a directory with the shell construct
if [[ -d. If it's a file, you can use the file
command to guess what type it is.


  if [[ -e $cmd ]]; then
if [[ -d $cmd ]]; then
echo "Perhaps you meant: cd $cmd"

elif [[ ! -x $cmd ]]; then
echo ""
filetype=$(file $cmd)

# HTML must come before text, since file says "HTML document text"
if [[ $filetype = *HTML* ]]; then
echo "$cmd is an HTML file. Did you want to run: firefox $cmd"
[ ... ]


You can use similar methods for each file type you want to handle -- you might want to suggest apps the user could call for image files, text files, movies and so on.



What about that case of a filename missing a slash? That's easy to check for too: look through the list of arguments, check whether each file exists, and if it doesn't, see if adding a slash to the beginning gives you the name of an existing file:



  if [[ $status -eq 2 ]]; then
# loop over args looking for the first one that might be missing a slash
for f in $cmd "${args[@]}"; do
if [[ $f = */* && ! -e $f ]]; then
if [[ -e /$f ]]; then
echo ""
echo "$f doesn't exist, but /$f does."
echo "Did you forget a leading slash?"
return
fi
fi
done
You can even check for cases where the file isn't readable, and suggest that the user might need to be root.
  if [[ -e $cmd ]]; then
if [[ -d $cmd ]]; then
echo "Perhaps you meant: cd $cmd"
elif [[ ! -x $cmd ]]; then
if [[ ! -r $cmd ]]; then
echo ""
echo "$cmd is a file but it's not readable or executable."
echo "Maybe you need to be root?"


A sample error-handling script
Here's a basic example of a bash error handler. You can add this to the end of your .bashrc; or save it as a separate file, like ~/.bash-error, then add this line to your .bashrc:


. $HOME/.bash-errs


Here's the script:


#
# Offer slightly friendlier error messages for certain types of errors.
#
function err_handle {
status=$?

if [[ $status -ne 2 && $status -ne 126 && $status -ne 127 ]]; then
return
fi

# Ucky pipeline which is, amazingly enough,
# the only way to get the last typed command from bash.
# fc -n -l -1 doesn't always have the command yet,
# !! doesn't work from inside functions
# and BASH_COMMAND gets confused by functions like ls().
lastcmd=$(history | tail -1 | sed 's/^ *[0-9]* *//')

# cool way to split a string into component words:
read cmd args <<< "$lastcmd"

# Handle possible errors involving forgetting a leading slash if the
# command was okay but the error was 2, "no such file or directory".
if [[ $status -eq 2 ]]; then
# loop over args looking for the first one that might be missing a slash
for f in $cmd "${args[@]}"; do
if [[ $f = */* && ! -e $f ]]; then
if [[ -e /$f ]]; then
echo ""
echo "$f doesn't exist, but /$f does."
echo "Did you forget a leading slash?"
return
fi
fi
done
return
fi

if [[ -e $cmd ]]; then
if [[ -d $cmd ]]; then
echo "Perhaps you meant: cd $cmd"
elif [[ ! -x $cmd ]]; then
if [[ ! -r $cmd ]]; then
echo ""
echo "$cmd is a file but it's not readable or executable."
echo "Maybe you need to be root?"
echo "You could try sudo less $cmd"
echo "or sudo $(myeditor) $cmd"
return 127
fi

#
# By now, we know it's a file and it's readable.
# Figure out the file's type, and print appropriate messages:
#
echo ""
filetype=$(file $cmd)

# HTML must come before text, since file says "HTML document text"
if [[ $filetype = *HTML* ]]; then
echo "$cmd is an HTML file. Did you want to run: firefox $cmd"

elif [[ $filetype = *text* ]]; then
echo "$cmd is a text file. Did you want to run:"
echo " less $cmd"
echo " vim $cmd"

elif [[ $filetype = *image* ]]; then
echo "$cmd is an image file. Did you want to run:"
echo " pho $cmd"
echo " gimp $cmd"

else
# "file" gives terribly complex output for MS Office documents
# so get the mime type to detect those:
mimetype=$(xdg-mime query filetype $cmd | sed 's/;.*$//')
if [[ $mimetype == application/msword ]]; then
echo "$cmd is a Microsoft Word file."
echo "Perhaps run: ooffice $cmd"
elif [[ $mimetype =~ application/.*ms- ]]; then
echo "$cmd is a file of type"
echo " $mimetype (Microsoft)."
echo "Perhaps try: ooffice $cmd"

else
#
# Unknown file type -- bomb out.
#
echo "$cmd is a file of type $mimetype."
echo "What do you want to do with it?"
fi
fi

else
echo "Hmm, $cmd exists and is executable -- not sure what went wrong"
fi
# else
# echo "Sorry, $cmd doesn't exist"
# If we want to be REALLY nice we could look for similarly named progs.
# But it turns out Ubuntu's command-not-found-handle does that already.
fi
}

# Trap errors.
trap 'err_handle' ERR


The Basics of SQL Joins in MySQL

When making your first forays into relational database development, you can use simple SQL statements to mine your data easily enough.

However, as your data grows in both size and breadth, you'll need to begin employing more sophisticated strategies for exploiting increasingly complex data relations.

After all, pulling data from a single table is easy, but what if you need to query for data spanning three, four, or even eight different tables?

Retrieving interrelated data stored within multiple tables is most effectively accomplished using a SQL JOIN clause, of which there are several variants.

The JOIN clause relies upon related fields found in two tables to determine the commonality of the data stored within each, producing a data set that you can then easily save or further manipulate.

In this article, I introduce three of the most commonly used JOIN variants: the INNER JOIN, OUTER JOIN, and SELF JOIN, and provides MySQL examples for using them.

Although these examples will be MySQL-specific, you'll be able to use what you learn here within most -- if not all -- other relational database solutions.


The Inner Join
Suppose you were tasked with creating reports that extracted data from a customer relationship management (CRM) application.

Specifically, the sales team wanted a list of all customers and their associated professions. Simplified versions of the customers and professions tables look like this:


CREATE TABLE customers (
 -> id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(255) NOT NULL,
-> profession_id INTEGER UNSIGNED NOT NULL
);

CREATE TABLE professions (
-> id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> name VARCHAR(255) NOT NULL
);

The shared commonality between these two tables is a profession ID, represented by the id column in the professions table, and the profession_id column in the customers table.

Knowing this, you can use an INNER JOIN to retrieve each customer name and the associated profession name like this:

SELECT * FROM customers INNER JOIN professions ON customers.profession_id = professions.id;

Executing this will produce a result set containing all of the values found in each interrelated row:


+----+------------+---------------+----+---------------+
| id | name       | profession_id | id | name          |
+----+------------+---------------+----+---------------+
| 1 | Acme, Inc. | 1 | 1 | Manufacturing |
+----+------------+---------------+----+---------------+

Because you're interested only in the customer and profession names, you can revise the query to look like this:

SELECT customers.name, professions.name FROM customers 
INNER JOIN professions
ON customers.profession_id = professions.id;

Executing the revised query produces the following output:

+------------+---------------+
| name | name |
+------------+---------------+
| Acme, Inc. | Manufacturing |
+------------+---------------+

Filtering Records
You can attach other SQL clauses to JOINs to produce sorted or filtered output. For instance, to retrieve only customers whose professions are "Technical writers," you would use this query:

SELECT customers.name, FROM customers 
INNER JOIN professions
ON customers.profession_id = professions.id
WHERE professions.name = "Technical writer";

The OUTER JOIN
The INNER JOIN will return rows only when a matching value is found in both tables.

However, what if you discovered some data inconsistencies, which arose due to the mass import of customers from another CRM solution, and you needed to know which customers have not yet been assigned a profession?

You can use an OUTER JOIN for that job, of which there are two types: the LEFT OUTER JOIN (or LEFT JOIN) and RIGHT OUTER JOIN (RIGHT JOIN).

The LEFT OUTER JOIN will retrieve all rows in the table located on the "left" side of the JOIN, regardless of whether a related row is found in the table located on the JOIN's "right" side.

In cases where no matching row is found, NULL will serve as a placeholder. For instance, the following LEFT JOIN will produce a list of all customers and professions, even if no profession assignment has been made:

SELECT customers.name, professions.name FROM customers 
LEFT JOIN professions
ON customers.profession_id = professions.id;

Suppose the customer "Taylor Made Teapots" lacked a corresponding profession. Executing a LEFT JOIN would produce the following output:

+---------------------+---------------+
| name | name |
+---------------------+---------------+
| Acme, Inc. | Manufacturing |
| Taylor Made Teapots | NULL |
+---------------------+---------------+

What if you wanted to retrieve just a list of customers lacking a profession designation? You can use the WHERE clause in conjunction with the IS NULL predicate, like this:

SELECT customers.name, professions.name FROM customers 
LEFT JOIN professions
ON customers.profession_id = professions.id;
WHERE professions.name IS NULL;

The RIGHT JOIN works identically to the LEFT JOIN, except that all rows on the right side of the JOIN will be returned, regardless of whether a shared row is found in the table residing on the left side of the JOIN.

For instance, you could use a RIGHT JOIN to determine which professions are not represented within the customer database:

SELECT professions.name FROM customers 
RIGHT JOIN professions
ON customers.profession_id = professions.id
WHERE customers.name IS NULL;

Executing this RIGHT JOIN produces output similar to the following:

+---------------+
| name |
+---------------+
| Plumber |
| Airline Pilot |
+---------------+

The SELF JOIN
Believe it or not, it's also possible to join a table to itself. For 
instance, suppose your company instituted a customer referral program,
providing customers with a cash incentive for inviting other
organizations to do business with you.

You'd naturally want to track
referral histories, which you could do easily enough by adding a column
named referrer_id to the customers table:
CREATE TABLE customers (
-> id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
-> referrer_id INTEGER UNSIGNED NOT NULL,
-> name VARCHAR(255) NOT NULL,
-> profession_id INTEGER UNSIGNED NOT NULL
);
For each customer, the referrer_id cell will be set to either 0, meaning nobody referred the customer, or an integer representing another customer's primary key:
+----+-------------+-------------------------+---------------+
| id | referrer_id | name | profession_id |
+----+-------------+-------------------------+---------------+
| 1 | 0 | Acme, Inc. | 1 |
| 2 | 1 | Taylor Made Teapots | 4 |
| 3 | 0 | Robin's Egg Farm | 1 |
| 4 | 2 | Paul's Plumbing | 3 |
| 5 | 2 | Charlie's Chicken Coops | 5 |
+----+-------------+-------------------------+---------------+
Using the SELF JOIN, you can create a list of customers and their referring counterpart:
SELECT c.name AS "Customer", r.name AS "Referred By" 
FROM customers c, customers r
WHERE c.referrer_id = r.id;
Executing this SELF JOIN produces output similar to the following:
+-------------------------+---------------------+
| Customer | Referred By |
+-------------------------+---------------------+
| Taylor Made Teapots | Acme, Inc. |
| Paul's Plumbing | Taylor Made Teapots |
| Charlie's Chicken Coops | Taylor Made Teapots |
+-------------------------+---------------------+

Conclusion
Mastering JOINs will elevate your ability to effectively manage large datasets. Just like learning to ride a bicycle though, it takes some practice to get used to the unfamiliar syntax. However, after some time you'll wonder how you ever got along without this powerful feature!

Encrypt Backup Tape Using Tar & OpenSSL

How do I make sure only authorized person access my backups stored on the tape drives (DAT, DLT, LTO-4 etc) under Linux or UNIX operating systems? How do I backup /array22/vol4/home/ to /dev/rmt/5mn or /dev/st0 in encrypted mode?

You can easily encrypt data to tape using combination of tar and openssl commands. The following is software based solution based upon encryption algorithms supported by openssl tool.

Encrypted backup should be used when storing sensitive data on removable media or when storing backups on shared NAS / SAN servers or online backup servers.

When using encryption the openssl ask for a password before you can create, view, open, or restore the files included in the backup. This is based upon pipes concept.

Backup Data

The following shows an example of writing the contents of "tapetest" to tape:

# tar zcvf - /array22/vol4/home | openssl des3 -salt | dd of=/dev/st0

An encryption password would be entered by the administrator or backup operator i.e. the above will encrypt a tape using triple DES in CBC mode using a prompted password.

You can put password in script itself:

# tar zcvf - /array22/vol4/home | openssl des3 -salt  -k "Your-Password-Here" | dd of=/dev/st0

Reading (listing) Files
Type the command as follows:

# dd if=/dev/st0 | openssl des3 -d -salt | tar ztvf -

OR

# dd if=/dev/st0 | openssl des3 -d -salt -k "Your-Password-Here" | tar ztvf -

Restore The Data
Use the following command to read and restore data back:

# dd if=/dev/st0 | openssl des3 -d -salt | tar xzf -

OR

# dd if=/dev/st0 | openssl des3 -d -salt -k "Your-Password-Here" | tar xzf -

Where,
  • dd : Convert and copy a file.
  • /dev/st0 : Tape device name.
  • openssl : The OpenSSL toolkit command line utility.
  • tar : The tar archiving utility.
  • des3 : Triple-DES Cipher (Triple DES is the common name for the Triple Data Encryption Algorithm).
  • -salt : The -salt option should ALWAYS be used if the key is being derived from a password unless you want compatibility with previous versions of OpenSSL and SSLeay. Without the -salt option it is possible to perform efficient dictionary attacks on the password and to attack stream cipher encrypted data. The reason for this is that without the salt the same password always generates the same encryption key. When the salt is being used the first eight bytes of the encrypted data are reserved for the salt: it is generated at random when encrypting a file and read from the encrypted file when it is decrypted. (source enc man page)

Hardware vs Software Encryption

The software encryption is different from the hardware encryption. The hadrware based encryption needs additional software+hardware and it use keys (and/or password) to protect data.

I suggest you read vendor site such as HP or IBM to get further details on hardware encryption which may or may not be supported by your backup devices.

See also:

Secure Your SSH Server with Denyhosts

As soon as you connect to the internet to do any of your daily tasks or connect your server to provide some service, it means that you are exposing your system to lots of threat and to people who are ready to play with your system just for fun or some personal interest.

SSH (Secure Shell) is one of the very common ways which is used to login to your machine and perform some tasks and which simply means that this is one of the gateway between hackers/crackers and your system.

So, most of the people would try different cracking techniques like Brute force or Dictionary attacks to gain access to your system with this service.

DenyHosts is a tool i use to secure my SSH server from these type of people. Written in python, this tool serves as a very active security guard and helps me to keep my system safe from lots of prying eyes.

Every day, I usually found at least couple of entries in the /etc/hosts.deny file. If you believe that your system operates on DHCP or no one could know your IP address, hence can’t launch any attack against your system, then this is the time to wake up.

Hackers have their scripts which don’t target a specific hosts or machine, they usually picks a network block and launches random attacks on all the machines available in that block and those scripts informs them as soon as they find something which could be of any interest to the hacker.

So which means that your machine is equally vulnerable to these attacks as much is mine.

What is Denyhosts:
DenyHosts is a python program that automatically blocks ssh attacks by adding entries to /etc/hosts.deny.

DenyHosts will also inform Linux administrators about offending hosts, attacked users and suspicious logins.

Installation:
Most of the time, there are two ways by which you can install a package, one is compile through source and other is to install by a package.

I will be explaining both here, so if you feel lazy (and don’t want to chase different locations for the dependencies), install it through package or else you could follow the source installation anytime.

Package Installation:
Package installation is pretty much simple. Usually I use my favorite tool aptitude to do the installation.

# aptitude install denyhosts -y

The package is not so big so it won’t take long for aptitude to search and install it. The package will install and configure on it’s own and get started to secure your system.

Source Installation:
I had already told you the easy way to install and configure the package, but still if you would like to opt the harder way, then download the source package from Denyhosts download.

Unzip and untar it and go into the Denyhosts directory.

# tar zxvf DenyHosts-2.6.tar.gz
# cd DenyHosts-2.6

and then use this simple command to install the package.

# python setup.py install

As you must know this, that installing the package from the source is quite a pain because you have to do all the configuration manually, instead of the way it was done automatically with the package.

Now go to the /usr/share/denyhosts directory and copy denyhosts.cfg-dist and daemon-control-dist to their respective to their non -dist version.

# cd /usr/share/denyhosts
# cp denyhosts.cfg-dist denyhosts.cfg
# cp daemon-control-dist daemon-control

I am sure you want the service to be started automatic at the next reboot. To do the same follow the steps given below.

# chown root daemon-control
# chmod 700 daemon-control
# ln -s /usr/share/denyhosts/daemon-control /etc/init.d/denyhosts
# chkconfig –add denyhosts

Now use this command to start the service

# /etc/init.d/denyhosts start

Denyhosts is now running and safe guarding your system from most of the attacks and will also start automatically at the next reboot.

Configuration:
The package installed now is with the default configuration and which works pretty much well for most of the cases, but there are also chances where you may be needing something different for yourself.

denyhosts.cfg is the file which you must be looking for if you would like to do some changes. The file is pretty much self explanatory, there are different parameters given inside the file which you can change and configure according to your needs. But there is one parameter which is worth mentioning.

BLOCK_SERVICE: This parameter is used by Denyhosts to block the listed services for the offenders. By default it will block the “ssh” service.

But if needed that can be changed to list of services or to “ALL” services. Simple put the parameter like this “#BLOCK_SERVICE = ALL” to block all services for those who are trying to mess up with your system.

But be CAREFUL, by mistake you could possibly block some of your clients with this.

Like if someone is trying some attacks from a company network, and you have have blocked all the services for that IP, then by mistake you are blocking services like HTTP/MAIL for all the people of that company.

There are various other parameters which can be changed and configured according to your needs like from where you should read the logs (SECURE_LOG), after how many days you purge an entry from the deny file (PURGE_DENY), after how many tries an IP would be put into the deny files, configuring Denyhosts to send you information and lot more. Have fun browsing through the config file.

Obviously, there are lots of other advance features in this software like Synchronization, means uploading the blacklisted hosts to a central server and downloading blacklists from other DenyHosts users which are using this service around the globe, but this is something i won’t be explaining here and will leave it for you to explore.

Here, I am not saying that Denyhosts will make your system completely secure but this is a very small piece of work which could give you great peace of mind.

Small configuration and your system will be safe from lots of un-wanted activities. So, I believe everyone must be using this to secure their system.

If not then drop an email/comment and I would like to hear the reason for the same.

Using smartctl to get SMART status information on your hard drives

Computer hard drives today come with SMART (Self-Monitoring, Analysis, and Reporting Technology) built-in, which allows you to see the status or overall “health” of a hard drive.

This information is invaluable in providing early warning signs of problems with a hard drive.

All Linux distributions provide the smartmontools package, which contain the smartctl program used to display SMART information from attached drives.

This package also provides the smartd daemon which periodically polls the drives to obtain SMART information.

Using smartd is essential as it can let you know immediately when a SMART attribute fails.

To begin, edit /etc/smartd.conf and add entries for your drives:
/dev/sda -d ata -H -m root
/dev/sdb -d ata -H -m root
...

The above tells smartd to perform a very silent check and to email the root user if the overall SMART health status fails.

It also tells smartd that these are ATA devices. There are a number of other options that can be added as well; the smartd.conf file has examples of these.

When smartd is configured, make sure to enable the monitoring daemon if it is not already started. On a Red Hat Enterprise Linux system, use:
# chkconfig smartd on
# service smartd start

The smartctl program also allows for you to view and test SMART attributes of a drive. You can quickly check the overall health of a drive by using:
# smartctl -H /dev/sda
smartctl version 5.38 [x86_64-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen
Home page is http://smartmontools.sourceforge.net/
=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

Obtaining information on the drive is useful as well. With the -i option, you can view the type of drive, its serial number, and so forth.

In a system with a lot of drives, having this information recorded can assist in knowing which drive device (i.e., /dev/sda) corresponds with which physical drive. For instance:
# smartctl -i /dev/sda
smartctl version 5.38 [x86_64-redhat-linux-gnu] Copyright (C) 2002-8 Bruce Allen
Home page is http://smartmontools.sourceforge.net/
=== START OF INFORMATION SECTION ===
Model Family:     Seagate Barracuda 7200.10 family
Device Model:     ST3320620AS
Serial Number:    9QF26NGD
Firmware Version: 3.AAJ
User Capacity:    320,072,933,376 bytes
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   7
ATA Standard is:  Exact ATA specification draft version not indicated
Local Time is:    Sun Mar  7 14:20:18 2010 MST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

Next, the -a option shows the specifics of the SMART attributes and test history.

This shows various SMART status information, such as the drive temperature, how many hours it has been powered on, and so forth.

It also indicates when tests have been performed and what the results of those tests were.

Finally, smartctl can be used to initiate long and short tests for the drive. These should be run periodically to do quick, or full, self-tests of the drive:
# smartctl --test=short /dev/sda
# smartctl --test=long /dev/sda
# smartctl -a /dev/sda

The above will first perform a short test of the /dev/sda device. This usually takes about a minute to perform, and the smartctl output will tell you when you can check the results.

Next, the long test: this one can take quite a bit longer (about two hours here on a 320GB SATA drive).

Finally, use the -a option to view the results, which may look like this:
SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed without error       00%     17877         -
# 2  Extended offline    Completed without error       00%      8449         -
# 3  Short offline       Completed without error       00%      8446         -
# 4  Short offline       Completed without error       00%      1307         -
# 5  Short offline       Completed without error       00%         2         -
# 6  Extended offline    Self-test routine in progress 90%     17877         -

In the above example, tests have been run over the lifetime of the drive and the short offline test was recently completed without error, while there is still 90% of the extended test remaining.

Being pro-active with the health of your hard drives can pay off huge by being aware of most problems before they can lead to catastrophic failures.

While SMART monitoring is not an exact thing (it won’t always report failures before they occur), the chances of catching a problem and being able to retrieve data before replacing a drive are more likely to not result in data loss or other problems than if you did not use it.

Wednesday, March 31, 2010

8 of the Best Free Linux Astrology Software

Astrology is a set of traditions, beliefs and systems which hold that there is a connection between the movement of heavenly bodies and events that take place on Earth such as human affairs, and personality.

Astrologists use the position of the planets to try to predict future events, and to inform the psychological understanding of an individual's psyche.

Up until the 17th century astrology and astronomy were inextricably intertwined. However, it is important to recognise that astronomy and astrology are two very different disciplines.

Astronomy is the scientific study of celestial objects and is widely respected in the scientific community, whereas astrology is based on universal, timeless symbolism, it is often regarded as a pseudo-science, and thought of as an art.

This article highlights the best astrology software that runs natively under Linux. There is not a wide selection of software available in this genre, and some popular Linux distributions (e.g. Ubuntu) do not include a single piece of astrology software in their standard repositories.

Nevertheless, there are some great astrology applications listed below for anyone who wants to try to improve his or her understanding of themselves or others.


To provide an insight into the quality of software that is available, we have compiled a list of 8 top quality open source astrology applications.

Hopefully, there will be something of interest for anyone interested in intuitive perception.

Now, let's explore the 8 astrology applications at hand. For each title we have compiled its own portal page, a full description with an in-depth analysis of its features, a screenshot of the software in action, together with links to relevant resources and reviews.

Astrology Software
OpenAstro.org Fully featured astrology application
Cenon Astro Astrology module for Cenon
Maitreya Vedic and Western Astrology
Skylendar Modern astrology software for KDE with SQL support
Astrolog Award winning software
Morinus Uses the Swiss ephemeris for accuracy
Oroboros Python based astrology software
SymSolon Analyze horoscopes wiyh Symbolon cards