Server security is not something that should be ignored. If an attacker gets on to your servers, do you know what they changed? Sure you’ve removed the gigabytes of malware with a virus scanner and manually cleaned up countless directories of illegal software, but is that all they left behind? Did they modify any of your important files, such as ‘su’ or ‘cp’ or ‘rm’? How would you know this? One answer is the Open Source project Tripwire. This tutorial will cover how to install, configure and maintain Tripwire on a Fedora 11 machine. This tutorial should be easily translatable to RedHat and CentOS 5.x with few (if any modifications) and to other Linux distributions with only minor changes.
Everything in this tutorial needs to be run as root. Tripwire itself needs to run as root as well, because it will be checking restricted file locations to ensure that no tampering as occurred. We will begin by installing tripwire. With Fedora 11 this is as simple as:
yum install tripwire
Now we need to configure tripwire to operate correctly on the system.
/usr/sbin/tripwire-setup-keyfiles
During install it will ask you to set up a site keyfile passphrase and a local keyfile passphrase. There are used to administer Tripwire, and encrypt the Tripwire policy files. This is to protect them against attackers. After all, what good would Tripwire be, if an attacker can just modify it to not show their dirty deeds. Both of these passphrases should be long random strings and should be stored securely. Additionally, they should be different from one another. You will need to enter them a few times to ensure you have entered them correctly.
After tripwire-setup-keyfiles completes, we need to set up the initial Tripwire policy and run it so that we can turn off false positives.
/usr/sbin/twadmin -m P /etc/tripwire/twpol.txt
You need to enter the site passphrase to run this command. This command will take a few minutes to run.
Next, we initialize the Tripwire database.
/usr/sbin/tripwire -m i
You will need to enter the local passphrase to run this command. This command will also take a few minutes to run.
Now we can do our first run of Tripwire. This run should report many out of compliance problems. This is because the default configuration checks many files that may not exist on your server. This can be because you didn’t install the software, because you removed software or because you installed it from source. Whatever the reason, we want to turn off these false positives so that we don’t get huge reports each time Tripwire runs.
/usr/sbin/tripwire -m c | grep Filename >> ~/twtest.txt
After this has completed, you will find a file in root‘s home directory called twtest.txt. In this file you will find a list of all files Tripwire checked for but did not find on your system. To prevent these from appearing each time this is run, we need to stop checking for them. To make this easier, we are going to run a few scripts to automatically change these settings for us.
cp /etc/tripwire/twpol.txt ~/twpol.txt
Next we will set up the input file to properly escape the path names we want to comment out.
vi ~/twtest.txt
Paste the following into vi and press Enter.
:%s/\//\\\\\\\//g
You should now see something like \\\/path\\\/to\\\/file for each line in the file. Save and quit vi.
:wq
The next step is to run the following shell script. This script assumes both twtest.txt and twpol.txt are in root‘s home directory. If you have been following along, they are.
nano Clean_TripwirePolicies.sh
Paste this code into the empty file you just created. Then exit nano with a ctrl-X and save the file
#!/bin/sh
cat ~/twtest.txt |
while read line
do
FILE=`echo $line | awk '{ print $2 }'`
sed -i "/^[ \t]*${FILE}/ s/^/#/" ~/twpol.txt
done
Give this script execution priviledges and run it.
chmod 700 Clean_TripwirePolicies.sh ./Clean_TripwirePolicies.sh
Next we reset the policies and rerun tripwire. Enter passphrases as appropriate.
cp ~/twpol.txt /etc/tripwire/twpol.txt /usr/sbin/twadmin -m P /etc/tripwire/twpol.txt /usr/sbin/tripwire -m i /usr/sbin/tripwire -m c | grep Filename >> ~/twtest2.txt
If ~/twtest2.txt is an empty file, the next step is to remove the clear text configuration files. If it is not empty, rerun the vi and shell scripts above, using twtest2.txt as the input.
rm /etc/tripwire/twcfg.txt /etc/tripwire/twpol.txt ~/twtest*.txt ~/twpol.txt
Finally, since we just cleared a few entries in /root and in /etc/tripwire, both of which are checked by Tripwire. If we don’t reset it up these will be flagged during each run.
/usr/sbin/tripwire -m i /usr/sbin/tripwire -m c
The last thing to do is to run Tripwire on a regular schedule. For this, we’ll set up a crontab under the root user.
crontab -e i 0 2 * * * /usr/sbin/tripwire -m c | mail -s "Tripwire Report" example@example.com > /dev/null <ESC> :wq
This will run Tripwire every morning at 2am, server time. The resulting Tripwire report will be emailed to example@example.com (change as appropriate). You are now set up.
A few notes about this set up before you just let this run. A report is only good if you actually look at it. The Tripwire report will get emailed each morning around 2am (depending on how long it takes Tripwire to run on your system), but if someone isn’t looking at it then its not doing anything for you. If you run any updates on the system (ie. yum update), the next run of Tripwire will flag many things as changed. In that case, you’ll need to reset the Tripwire policy. The cause of all these new violations is not because the system was attacked, but because the files Tripwire monitors changed when they were updated. You expect this to happen with updates, therefore you need to tell Tripwire the changes are acceptable.
After you have checked a report and verified that everything reported is acceptable, run the following command to prevent all violations in the report from being reported again.
/usr/sbin/tripwire --update --twrfile /var/lib/tripwire/report/<name>.twr
<name> will be the name of the report you want to update the database with. This means if you update the database using a report a week old, anything in that report will be flagged as acceptable, but if last night’s report reported something else, it will still be reported.
Finally, you may want to look at previous reports at some point. Tripwire stores the reports in a nonhuman readable format. To read the reports you will first need to find the file you are looking for
ls -l /var/lib/tripwire/report/
Note the name of the report you want to read. Replace <name> with that file name in the following command.
You can now read any previous report and update your policy file based on previous reports. If you want more information about Tripwire remember man tripwire is your friend./usr/sbin/twprint -m r --twrfile /var/lib/tripwire/report/<name>
#1 by Jean Paul on February 17, 2010 - 8:12 am
Quote
This is great..just found one typo on the cron job entry..should be /usr/sbin/tripwire not /usr/bin/tripwire…
#2 by Andy on February 22, 2010 - 2:16 pm
Quote
Thank you Jean Paul. I’ve corrected the typo.
#3 by George Murrow on July 26, 2010 - 1:44 pm
Quote
This is wonderful. It is folks like you that make the open source community such a great place for development. Thank you so much.
#4 by security system on September 29, 2010 - 12:38 pm
Quote
I’m glad that I’ve found your http://www.syntaxtechnology.com web site.
Thanks for taking the time to discuss this, I feel strongly about information and love learning more on this. If possible, as you gain expertise, would you mind updating your blog with more information? It is extremely helpful for me.
#5 by Matt on October 12, 2010 - 1:43 pm
Quote
cron tab is setup incorrectly, with a * in the minutes slot, the system will generate 60 emails, one for every minute while 2 is the hour. Should be “0 2 * * *”
#6 by Nathan on November 11, 2010 - 5:41 pm
Quote
Thanks, interesting tut on tripwire.. checking it out right now.. though I suggest adding a part about how to just pick a directory to watch for example.
#7 by cboldt on November 14, 2010 - 2:33 pm
Quote
I run a Gentoo system, and am writing a policy generator that builds a policy from my system configuration. I’m sure the generator won’t work for Red Hat, but the concept might be portable with a few changes.
In the Gentoo scheme, the policy generator is given a list of package names, and the program builds tripwire policy from the database of installed packages, and for each package, a list of installed files.
The bash script is still being worked on, but a workable version is at http://bugs.gentoo.org/344577
#8 by Neil Squires on January 6, 2011 - 8:04 am
Quote
I followed this guide and have installed tripwire on 2 Fedora Core 14 servers. A nice guide that has made it easy to install.
I have also developed a simple script to allow you to update the tripwire policy. Saves time as tripwire is scheduled to run after the yum updates.
#9 by Andy on January 14, 2011 - 1:15 pm
Quote
Neil, would you mind sharing that script to update the policy?
#10 by cboldt on January 17, 2011 - 9:17 pm
Quote
Not tripwire update scripts, but easy enough to remeber, and they work. Put these lines in your .bashrc (or .bash_profile), or where ever convenient on your system:
alias tripwire.report=’twprint –print-report –twrfile `ls /var/lib/tripwire/report/* | tail -1`’
alias tripwire.update=’tripwire –update –twrfile `ls /var/lib/tripwire/report/* | tail -1`’
#11 by Andrew on May 1, 2011 - 4:34 pm
Quote
Hi, I don’t much like vi and prefer nano too. But your crontab example is using vi.
This can be fixed easily by running:-
export EDITOR=nano
and then running crontab -e
Hope this helps.
A.
#12 by Neil Squires on July 1, 2011 - 5:42 pm
Quote
Here is the script.
#!/bin/bash
REPORT_DIR=”/var/lib/tripwire/report/”
UPDATE=”/usr/sbin/tripwire –update –twrfile”
SYSNAME=$HOSTNAME
CONFIRM=”n”
# Test if root
if [ $(id -u) != "0" ]; then
echo “You must be the superuser to run this script” >&2
exit 1
fi
echo “Updating Tripwire DB for $SYSNAME.”
echo “Please select the report file to update from:”
ls -l $REPORT_DIR
read -p “Enter name of report:” REPORT
REPORT=”$REPORT_DIR”"$REPORT”
read -p “Confirm you wish to update the database with $REPORT (Y/n):” CONFIRM
if [ "$CONFIRM" != "Y" ]
then
echo Exiting
exit 1
else
echo Updating database
echo “Running command $UPDATE”"$REPORT”
# echo -n “Please enter local passphrase:”
# read PASS_PHRASE
$UPDATE $REPORT
fi
#13 by Dennis Granau on January 28, 2012 - 6:14 am
Quote
Excellent article! Thank you very much! Worked on Fedora 16, 64 bit, like a charm!