Section 11.2. Using Tripwire

Among the most celebrated and useful things to come out of Purdue's COAST project (http://www.cerias.purdue.edu/coast/) was the Unix integrity checker Tripwire, created by Dr. Eugene Spafford and Gene Kim. Tripwire was originally both open source and free, but in 1997, Tripwire went commercial, and fee-free use was restricted to academic and other noncommercial settings.

Happily, a couple of years ago, Tripwire, Inc. released "Tripwire Open Source, Linux Edition." Until Tripwire Open Source was released, the older Academic Source Release (ASR) lacked features long available in commercial versions of Tripwire. But Tripwire Open Source is a more-or-less current version of the commercial product. Although it still lacks a few "enterprise" features such as centralized management of multiple systems (Tripwire, Inc. understandably still wishes to differentiate its commercial product line), it is functionally very similar to the commercial Tripwire for Servers.

Note that Tripwire Open Source is free for use only on noncommercial Unices (i.e., Linux and Free/Net/OpenBSD). In fact, it's officially supported only on Red Hat Linux and FreeBSD, although there's no obvious reason why it shouldn't compile and run equally well on other Linux and BSD distributions. (I run it not only on Red Hat, but also on SuSE and Debian Linux, with no problems to report). For commercial Unices such as Sun Solaris and HP-UX, commercial Tripwire is still the only legal option in commercial settings.

11.2.1 Obtaining, Compiling, and Installing Tripwire

As of this writing, the most current version of Tripwire Open Source is 2.3.1-2. If your Linux distribution of choice doesn't provide a reasonably current Tripwire package (Debian 2.2 and SuSE 7.3, for example, both ship with Tripwire 1.2, the 1994 Academic Source Release!), then I strongly recommend that you obtain, compile, and install the latest version. Needlessly running old security software is seldom a good idea; furthermore, as Linux users, we're eligible to use Tripwire Open Source. Tripwire Open Source can be downloaded as a source-code tarball at http://sourceforge.net/projects/tripwire/.

To compile Tripwire Open Source, move the archive to /usr/src and untar it, e.g.:

tar -xzvf ./tripwire-2.3.1-2.tar.gz.

Next, check whether you have a symbolic link from /usr/bin/gmake to /usr/bin/make. (Non-Linux Unices don't all come with GNU make, so Tripwire explicitly looks for gmake ? but on most Linux systems, this is simply called make). If you don't have such a link, create one.

Another thing to check for is a full set of subdirectories in /usr/share/man ? Tripwire will need to place manpages in man4, man5, and man8. On my Debian system, /usr/man/man4 was missing; as a result, the installer created a file called /usr/man/man4, which of course was actually a manpage that was incorrectly copied to that name rather than within it.

Now change your working directory to Tripwire source's root directory ? e.g., /usr/src/tripwire-2.3.1-2 ? and read the files README and INSTALL. They're both brief but important.

Finally, change to the source tree's src directory (e.g., /usr/src/tripwire-2.3.1-2/src), and make any necessary changes to the variable definitions in src/Makefile. Be sure to verify that the appropriate SYSPRE definition is uncommented (SYSPRE = i686-pc-linux, or SYSPRE = sparc-linux, etc.).

Now you're ready to compile. While still in Tripwire's src directory, enter this command:

make release

The build will take a while, so now is a good time to grab a sandwich. When it's done (Tripwire, not the sandwich), navigate up one directory level (e.g., to /usr/src/tripwire-2.3.1-2) and execute these two commands:

cp ./install/install.cfg .

cp ./install/install.sh .

Now open install.cfg with your favorite text editor to fine tune the variables within: while the default paths are probably fine, you should at the very least examine the Mail Options section. This is where we initially tell Tripwire how to route its logs (I say "initially" because these settings can be changed later).

If you set TWMAILMETHOD=SENDMAIL and specify a value for TWMAILPROGRAM, Tripwire will use the specified local mailer (sendmail by default) to deliver its reports to a local user or group. If instead you set TWMAILMETHOD=SMTP and specify values for TWSMTPHOST and TWSMTPPORT, Tripwire will mail its reports to an external email address via the specified SMTP server and port.

If you or other system administrators routinely log on to and read email on the system on which you're installing Tripwire, then the SENDMAIL method is probably preferable. But if you typically administer this host remotely from other systems, the SMTP method is probably better. Again, if you change your mind later, these settings can be changed in Tripwire's configuration file at any time.

Once install.cfg is set to your liking, it's time to install Tripwire. While still in the root directory of the Tripwire source distribution, enter the following:

sh ./install.sh

You will be prompted for site and local passwords: the site password protects Tripwire's configuration and policy files, whereas the local password protects Tripwire's databases and reports. This allows the use of a single policy across multiple hosts in such a way as to centralize control of Tripwire policies but distribute responsibility for database management and report generation.

If you do not plan to use Tripwire across multiple hosts with shared policies, there's nothing wrong with setting the site and local Tripwire passwords on a given system to the same string. In either case, choose a strong passphrase that contains some combination of upper-and lowercase letters, punctuation (which can include whitespace), and numerals.

If you install Tripwire from an RPM binary package, the main difference in your postinstallation procedure from the one I just described is that after you run rpm, you'll need to run /etc/tripwire/twinstall.sh to generate site and local passwords.

11.2.2 Configuring Tripwire

Justly or not, Tripwire has a reputation of being unintuitive to configure. In my opinion, the configuration syntax in Tripwire Version 2 is much simpler than Version 1's (which is yet another reason to run Tripwire Open Source rather than ASR!). Regardless, I think you'll find the time you spend reading the next section and fine-tuning Tripwire on your own systems to be well worth the effort.

Let's examine the tasks that comprise Tripwire configuration and usage, one at a time.

11.2.2.1 Managing the configuration file

When you install Tripwire (whether via binary package or source build), a default configuration file is created, /etc/tripwire/tw.cfg. You can't edit this file because it's an encrypted binary, but for your convenience, a clear-text version of it, called twcfg.txt, should also reside in /etc/tripwire. This is the file to change if you've had second thoughts about any of the settings you gave the installation script when you installed Tripwire.

Example 11-1 lists a sample (clear-text) Tripwire configuration.

Example 11-1. Sample Tripwire configuration
ROOT          =/usr/sbin

POLFILE       =/etc/tripwire/tw.pol

DBFILE        =/var/lib/tripwire/$(HOSTNAME).twd

REPORTFILE    =/var/lib/tripwire/report/$(HOSTNAME)-$(DATE).twr

SITEKEYFILE   =/etc/tripwire/site.key

LOCALKEYFILE  =/etc/tripwire/squeezebox-local.key

EDITOR        =/bin/vi

LATEPROMPTING =false

LOOSEDIRECTORYCHECKING =false

MAILNOVIOLATIONS =true

EMAILREPORTLEVEL =3

REPORTLEVEL   =3

MAILMETHOD    =SMTP

SYSLOGREPORTING =false

SMTPHOST      =mail.polkatistas.org

SMTPPORT      =25

Many of the settings shown in Example 11-1 are self-explanatory; others are things you already considered when you installed Tripwire. Specifically, MAILMETHOD corresponds to the Tripwire postinstallation script's variable TWMAILMETHOD, MAILPROGRAM corresponds to TWMAILPROGRAM, SMTPHOST to TWSMTPHOST, and SMTPPORT to TWSMTPPORT. It's unlikely that you'll need to change these settings very often, if at all, but if you do, a complete reference is available in the twconfig(4) manpage.

One setting you should strongly consider customizing is DBFILE. As I mentioned earlier in the chapter, an integrity checker should ideally refer to a database stored on read-only media. For example, if you create a directory called /mnt/twdb and specify /mnt/twdb/myhostname.db as the value of DBFILE in your Tripwire configuration (substituting myhostname.db with your host's name), Tripwire will write its configuration to this directory when you initialize it. You can then burn this file to a CD-ROM, erase it from /mnt/twdb, and mount the database CDROM on /mnt/twdb.

I should point out one more setting, one brought to my attention by Tripwire Open Source Project Manager, Ron Forrester: MAILNOVIOLATIONS. If this is set to false, then Tripwire will email its reports only when violations are found. But setting it to true causes a report to be emailed each time a Tripwire check is run, even if there are no violations. This provides a "heartbeat" function that makes it obvious if an intruder suppresses Tripwire activity.

Don't confuse Tripwire's configuration with its policy. The configuration controls basic characteristics of Tripwire's operating environment and behavior, which are certainly important but don't change very often. The policy, on the other hand, determines what Tripwire looks for and how it reacts. Even if only to minimize the number of false alarms Tripwire sends you, you'll probably tweak your Tripwire policy far more frequently than you change its configuration.

Any time you edit the clear-text version of your Tripwire configuration, re-encrypt it with the command:

twadmin --create-cfgfile --site-keyfile  ./site.key twcfg.txt 

where site.key is the name of the site key created at installation time and twcft.txt is the name of the clear-text configuration file you just edited and wish to encrypt; you can name them whatever you like. Don't forget to specify the site-keyfile, or twadmin will return an error.

You should not, as a matter of practice, leave clear-text copies of your Tripwire configuration or policy files on your hard drive. After editing and encrypted them, delete the clear-text versions. You can always retrieve them later with the commands:

twadmin --print-cfgfile >  myconfig.txt 

and:

twadmin --print-polfile >  mypolicy.txt 

Omitting the file-redirect in these commands prints the configuration or policy directly to the screen.

Long-Form Commands Versus Short-Form

Throughout this chapter, I use the long form of Tripwire commands: any flag or directive beginning with a double-dash (" -- ") is a long form and has a corresponding short form. For example, these two commands are equivalent:

twadmin --print-cfgfile

twadmin -m f

Once you're comfortable using Tripwire, you'll probably want to learn the short forms. As Neal Stephenson points out in his essay, "In the Beginning Was the Command Line," repetitive stress disorder is to us geeks what black lung is to miners. I'd hate for anyone to think I was responsible for inflicting either on my gentle readers!

Just starting out, however, you'll probably have a much easier time dealing with Tripwire's more English-like long command syntax. The Tripwire Open Source Reference Card (see "References" later in this chapter) has a handy matrix of long-form versus short-form flags for Tripwire executables.

11.2.2.2 Editing or creating a policy

Tripwire's policy file is its brain: it specifies what to look at, what to look for, and what to do about it. It's also a little on the user-hostile side, though not nearly so bad in this regard as, say, sendmail.cf (but prepare to memorize some abbreviations!).

Tripwire Open Source comes with a default policy file, and you may, if you like, use this as your own personal Tripwire policy. But since the default policy was created for a Red Hat system running nearly everything in the distribution, you should probably edit this policy rather than use it as is.

If your policy doesn't check enough files or doesn't look closely enough at the ones it does check, Tripwire's purpose is defeated: shenanigans will go undetected. Conversely, if the policy looks too closely at files that you expect to change, Tripwire will generate false positives; too many of these may distract your attention from actual discrepancies.

But, to repeat my admonition from the beginning of the chapter, some false positives are acceptable; no false negatives are! Err, therefore, on the sake of "noisiness" rather than convenience.

You'll almost certainly need to adjust your policy on an ongoing basis and especially after the first time you run an integrity check. Thus, even if you do have a Red Hat system with exactly the same configuration as that for which the default Tripwire Open Source policy was designed, you still need to learn proper Tripwire policy syntax.

11.2.2.3 Policy file structure and syntax

I'm going to explain policy file structure and syntax by dissecting a working policy file piece by piece. The first piece is from the very beginning of a sample policy file (Example 11-2).

Example 11-2. Some variable definitions
WEBROOT=/home/mick/www;

CGIBINS=/home/mick/www/cgi-bin;

TWPOL="/etc/tripwire";

TWDB="/var/lib/tripwire";

As you can see, this first piece of policy shows some variable definitions. All of the variables in Example 11-2 are policy-specific variables; none of them hold intrinsic meaning to Tripwire binaries. They're here to save typing later on in the policy.

Example 11-3 lists the next piece of our sample policy.

Example 11-3. Fancier variable definitions
BINS          = $(ReadOnly) ;       # Binaries that should not change

DIR_SEMISTATIC = +tpug ;            # Dir.s that shouldn't change perms/ownership

SIG_MED       = 66 ;                # Important but not system-critical files

Like the variables in Example 11-2, these are policy-specific variables. But as you can see, they create more typing, not less: these have been declared to attach meaningful labels to abstract values. The first line shows us how to set one variable to the value of another. This is very similar to BASH-shell syntax, but note the parentheses around the second variable's name.

Both lines one and two in Example 11-3 define property masks . Property masks are abbreviations of the file properties Tripwire examines. Since property mask strings can be cryptic and unwieldy, most people prefer to use variables to refer to them. In fact, Tripwire comes with a number of predeclared variables set to common property masks. The first line of this listing actually refers to one of these, ReadOnly, which is a property mask for files that shouldn't change in any way (e.g., binaries). We'll discuss property masks shortly.

The third line of Example 11-3 creates a name for a severity level. Severity levels can be used to differentiate between rules of various importance. When the tripwire command is invoked with the --severity N parameter, only rules that have been assigned severity levels equal to or greater than N will be run. In Tripwire's default twpol.txt file, three example severity levels are helpfully defined.

If this parameter is not used, all rules will be run. But note that if a rule has no severity level associated with it, its severity will be zero by default (i.e., that rule will only be run when the --severity parameter isn't specified).

Now that we've got a feel for policy variables and what they're used for, let's look at some actual rules (Example 11-4).

Example 11-4. A group of rules
# Mick's Web Junk

(

  rulename = "MickWeb",

  severity = $(SIG_MED),

  emailto = mick@uselesswebjunk.com

)

{

  $(WEBROOT)               -> $(ReadOnly) (recurse=1) ;

  !$(WEBROOT)/guestbook.html ;

  $(CGIBINS)               -> $(BINS)     ;

  /var/log/httpd           -> $(Growing)  ;

  /home/mick               -> $(DIR_SEMISTATIC) (recurse=0)

}

Rules may either stand alone or be grouped together based on common attributes; Example 11-4 shows a group of rules (contained within "curly brackets") preceded by several shared attributes (in parentheses). This group's rulename is "MickWeb," the group's severity is 66 (see Example 11-3), and reports involving this group will be emailed to mick@uselesswebjunk.com. Note that attributes are comma delimited, and rules are semicolon delimited.

Attributes can also be assigned both to rule groups and to individual rules: the first rule in Example 11-4 has the attribute recurse set to 1, which means that the directory /home/mick/www will be checked down one level (i.e., the directory itself plus everything immediately below, but no further). By default, directories are recursed as far down as they go; in effect, the recurse attribute has a default value of True.

Attributes assigned to single rules usually override those assigned to rule groups. The exception is the attribute emailto, which is cumulative: if a group has a shared emailto string and one of that group's rules has a different emailto string, reports relevant to that rule will be emailed to both email addresses.

There are only four different attributes: rulename, severity, emailto, and recurse. For more detailed information, see the documentation cited in Section 11.5 at the end of this chapter.

After the group attributes for MickWeb, we have some actual rules (lines 8 through 11). Note the use of variables to specify both objects (the Tripwire term for files and directories) and property masks. In fact, none of the rules in Example 11-4 uses a longhand property mask! This is common practice, as it makes the policy more readable.

The first rule in Example 11-4:

$(WEBROOT) -> $(ReadOnly) (recurse=1) ;

tells Tripwire to treat the first level of my WWW directory as read-only. Next, we have a statement beginning with an exclamation point:

!$(WEBROOT)/guestbook.html ;

Such a statement is called a stop point: it defines an exception to a rule. In this case, the stop point tells Tripwire to ignore changes to the file /home/mick/www/guestbook.html. Attributes do not apply to (nor may they be assigned to) stop points.

Examples 11-2 through 11-4 constitute a semantically complete policy file, but not a useful one ? it doesn't check any system binaries or configuration files at all. Real policies are much longer. Here's the policy in one listing (Example 11-5).

Example 11-5. A sample policy file
WEBROOT=/home/mick/www;

CGIBINS=/home/mick/www/cgi-bin;

TWPOL="/etc/tripwire";

TWDB="/var/lib/tripwire";

BINS  = $(ReadOnly) ;         # Binaries that should not change

DIR_SEMISTATIC = +tpug ;      # Directories that shouldn't change perms/ownership



SIG_MED = 66 ; # Important but not system-critical files



# Mick's Web Junk

(

  rulename = "MickWeb",

  severity = $(SIG_MED),

  emailto = mick@uselesswebjunk.com

)

{

  $(TWPOL)    -> $(Readonly) ;

  $(WEBROOT)  -> $(ReadOnly) (recurse=1) ;

  !$(WEBROOT)/guestbook.html ;

  $(CGIBINS)  -> $(BINS)     ;

  /var/log/httpd -> $(Growing)  ;

  /home/mick  -> $(DIR_SEMISTATIC) (recurse=0)

}

You may have noticed that this entire file contains only one explicit reference to a property mask: the variable declaration in which DIR_SEMISTATIC is set to +tpug. What does that mean?

11.2.2.4 Property masks

A property mask is a series of file or directory properties that should be checked or ignored for a given object. Properties following a + are checked; those following a - are ignored. The properties are abbreviated as follows (Table 11-1).[1]

[1] Adapted from the twpolicy(4) manpage.

Table 11-1. Allowed properties in property masks

Property

Description

-

Ignore the following properties

a

Access timestamp

b

Number of blocks allocated

c

Inode timestamp (created/modified)

d

ID of device on which inode resides

g

File owner's group ID

i

Inode number

l

File is increasing in size (a "growing file")

m

Modification timestamp

n

Number of hard links (inode reference count)

p

Permissions and file mode bits

r

ID of device pointed to by inode (valid only for device objects)

s

File size

t

File type

u

File owner's user ID

C

CRC-32 hash value (CRC-32 is fast to compute but noncryptographic ? i.e., relatively forgeable)

H

Haval hash value (Haval is cryptographically strong but slow to compute)

M

MD5 hash value (cryptographically strong but slow)

S

SHA hash value (cryptographically strong but slow)

Tripwire's own documentation describes these properties in depth. If you're unfamiliar with some of the more arcane file attributes (e.g., "inode reference count"), I recommend the paper "Design and Implementation of the Second Extended Filesystem" by Card, Ts'o, and Tweedie (see Section 11.5 at the end of this chapter).

As for hash types, note that you generally won't want to use more than one or two cryptographic hashes per rule: these are CPU intensive. On the other hand, do not rely solely on CRC-32 hashes, which are fast but much easier to subvert. Remember, Tripwire doesn't compare file attributes directly: it compares hashes. So give this matter some thought and choose your hash types carefully.

As I mentioned earlier, Tripwire has a number of predefined (hardcoded) variables that describe common property masks (Table 11-2).

Table 11-2. Predefined property masks (adapted from the twpolicy(4) manpage)

Name

Description

Mask

ReadOnly

Files that are widely available but read-only

+pinugtsdbmCM-rlacSH

Dynamic

User directories and other things you expect to change regularly

+pinugtd-srlbamcCMSH

Growing

Intended for files that should get larger but not change in other ways

+pinugtdl-srbamcCMSH

Device

Devices or other files whose attributes (but not their contents) should be checked

+pugsdr-intlbamcCMSH

IgnoreAll

Checks a file's presence or absence but nothing else

-pinugtsdrlbamcCMSH

IgnoreNone

Checks all properties. Can be used for defining custom masks (e.g., mymask = $(IgnoreNone) -ar;)

+pinugtsdrbamcCMSH-l

Which Files and Directories Should I Monitor?

Since there are so many different things you can use a Linux system for, there really isn't a "one size fits all" recommendation for configuring integrity checkers such as Tripwire. Having said that, in my opinion, you should be monitoring at least these files and directories (precise paths may differ on your system) on any Linux system.

Note that on most systems, checking all of /usr/bin, /usr/sbin, /lib, and /usr/lib doesn't make sense ? such large directories make for a slow Tripwire check. Therefore, I recommend checking files in those directories individually, as indicated here, despite the length this adds to your policy:

/usr/sbin/siggen         # tripwire binaries...

/usr/sbin/tripwire       #                    ...

/usr/sbin/twadmin        #                    ...

/usr/sbin/twprint        #                    ...

/bin/                    # all core system binaries

/sbin/                   # all core admin. binaries

/usr/bin/                # user binaries, especially:

/usr/bin/at      /usr/bin/awk        /usr/bin/bzcat

/usr/bin/bzgrep  /usr/bin/bzip2      /usr/bin/crontab

/usr/bin/csh     /usr/bin/diff       /usr/bin/dir

/usr/bin/du      /usr/bin/Emacs      /usr/bin/expect

/usr/bin/file    /usr/bin/find       /usr/bin/finger

/usr/bin/flex    /usr/bin/gawk       /usr/bin/gdb

/usr/bin/grep    /usr/bin/gruff      /usr/bin/gzip

/usr/bin/ident   /usr/bin/idle       /usr/bin/less

/usr/bin/lsof    /usr/bin/nm         /usr/bin/nroff

/usr/bin/passwd  /usr/bin/perl       /usr/bin/pdksh

/usr/bin/php     /usr/bin/pico       /usr/bin/quota

/usr/bin/rexec   /usr/bin/rlogin     /usr/bin/ssh

/usr/bin/strings /usr/bin/strip      /usr/bin/sudo

/usr/bin/swatch  /usr/bin/sz         /usr/bin/tail

/usr/bin/tailf   /usr/bin/tcsh       /usr/bin/top

/usr/bin/troff   /usr/bin/up2date    /usr/bin/users

/usr/bin/vi      /usr/bin/vim        /usr/bin/which

/usr/bin/yacc    /usr/bin/zsh

/usr/libexec/            # some core system daemons

/usr/sbin/               # superuser binaries, especially:

/usr/sbin/anacron        /usr/sbin/atd

/usr/sbin/chroot         /usr/sbin/crond

/usr/sbin/httpd          /usr/sbin/identd

/usr/sbin/in.fingerd     /usr/sbin/in.rexecd

/usr/sbin/in.rlogind     /usr/sbin/in.rshd

/usr/sbin/in.telnetd     /usr/sbin/iptables

/usr/sbin/lpd            /usr/sbin/lsof

/usr/sbin/named          /usr/sbin/ntpd

/usr/sbin/postfix        /usr/sbin/pppd

/usr/sbin/rpc.rstatd     /usr/sbin/safe_finger

/usr/sbin/sendmail       /usr/sbin/showmount

/usr/sbin/smrsh          /usr/sbin/snmpd

/usr/sbin/snmptrapd      /usr/sbin/squid

/usr/sbin/sshd           /usr/sbin/stunnel

/usr/sbin/suexec         /usr/sbin/tcpd

/usr/sbin/tmpwatch       /usr/sbin/visudo

/usr/sbin/xinetd         /usr/sbin/xinetd-ipv6

/usr/local/bin/          # local system binaries

/usr/local/sbin/         # local superuser binaries

/usr/local/libexec/      # some local system daemons

/etc/                    # system configuration files

/var/log/                # system logs (use "Growing"

                         #   built-in property mask!)

/lib/                    # system libraries, especially:

/lib/libc.so.6

/lib/modules/            #    use recurse=0 -- this is large

/lib/security/           #    PAM lives here

/usr/lib/                # more libraries, especially:

/usr/lib/libc.a

/usr/lib/libc.so

/usr/lib/libc_nonshared.a

/usr/local/lib/          # local apps' libraries

To these, add any other directories containing things you don't want or expect to change (e.g. chroot jails, web content hierarchies, ftp archives, etc.).

In most cases, it's much simpler to use the predefined property masks than to "roll your own" masks. If you need a property mask that's only slightly different than a predefined mask, you can still use it: simply combine it with additional properties, e.g.:

/dev/console  -> $(Dynamic)-u ;    # Dynamic, but UID can change

which is the same as:

/dev/console  -> +pingutd-srlbamcCMSH-u ;     # Dynamic, but UID can change

Note that in the longhand example, the +....u near the beginning of the mask is canceled out by the -u at the very end. This works, but it is notated that way here only to illustrate the literal translation of $(Dynamic)-u.

11.2.2.5 Installing the policy file

After you've created what seems like a reasonable policy, you need to install it. The command to encrypt, sign, and install a system's first Tripwire policy is as follows:

twadmin --create-polfile  policyfile.txt 

Use this command only for your initial policy; if you edit your policy again later, use the method described in the next section.

Also, as with configuration files, you should remove the clear-text policy file from your system once you've created the binary file. If you need to refer to or edit the policy later, you can retrieve it with the command:

twadmin --print-polfile >  mypol.txt 

The last step in setting up Tripwire for the first time on a system is to create (initialize) its database:

tripwire --init

Tripwire installation, configuration, and initialization should occur as soon as possible after OS installation and system hardening, before the system is connected to a network.

Later is better than never, but installing Tripwire on a system that's already been connected to a network reduces the trustworthiness of its Tripwire database: the system may already have been compromised in some way.

Use the --init directive only when creating a new database. We'll see how to update the database in the next section.

11.2.3 Running Tripwire Checks and Updates

Once you've got a database installed, you can run periodic checks against it. At its simplest, the command to do so is the following:

tripwire --check

This compares all protected files against the hash database and prints a report both to the screen and to a binary file. The report can be viewed again with the command:

twprint --print-report --report-level  N  --twrfile  /path/file 

where N is a number from 0 to 4, 0 being a one-line summary and 4 being a full report with full details; /path/file is the full path and name of the latest report. By default, the report will reside in /var/lib/tripwire/report, with a time-/date-stamp appended to its filename (e.g. /var/lib/tripwire/report/myron.polkatistas.org-20020311-221057.twr).

To have Tripwire automatically email the report to all recipients specified in the policy, you can run your check like this:

tripwire --check --email-report

Note that the report will still be printed to standard output and saved in /var/lib/tripwire/report, in addition to being emailed. This is a handy command to run as a cron or anacron job: since it doesn't require you to authenticate with your site or local key, it can be run in this mode unattended.

If you've just installed the Tripwire RPM on a Red Hat 7 system, your system is already set up with such a cron job: the Tripwire RPM installs the script /etc/cron.daily/tripwire-check. (See Example 11-6, modified to allow for Tripwire paths besides /var/lib/tripwire). If you've installed Tripwire from source or otherwise need to set up the cron job yourself, add this script to /etc/cron.daily manually.

Example 11-6. Script for automated Tripwire checks
#!/bin/sh

HOST_NAME=`uname -n`

TWHOME = /var/lib/tripwire

if [ ! -e $TWHOME/${HOST_NAME}.twd ] ; then

        echo "****    Error: Tripwire database for ${HOST_NAME} not found.    **

**"

        echo "**** Run "/etc/tripwire/twinstall.sh" and/or "tripwire --init". **

**"

else

        test -f /etc/tripwire/tw.cfg &&  /usr/sbin/tripwire --check

fi

If you've configured the emailto attribute in your Tripwire policy, you may wish to edit the second-to-last line of the tripwire-check script so that Tripwire emails its results and suppresses its standard output (so you don't receive email both from Tripwire and from crond):

test -f /etc/tripwire/tw.cfg && /usr/sbin/tripwire --check --email-report --no-tty-

output --silent

Here's the same Tripwire command, this time in standard crontab format (and with short-form tripwire directives due to the length of the line):

30 1,5,14 * * *       /usr/sbin/tripwire -m c -M -n -s

I highly recommend you schedule Tripwire checks to run at least daily ? better still, several times per day. Hourly may even make sense on systems that are at high risk (e.g., publicly accessible web servers). But if you run Tripwire that frequently, you'll definitely want to be judicious with regard to the number of files Tripwire checks, especially if your hardware isn't very fast: the cryptographic computations Tripwire uses can be both time- and CPU-consuming.

If that becomes a problem, you may need to replace some of the directories in your policy with lists of specific files (e.g., rather than all of /usr/bin, do checks on /usr/bin/du, /usr/bin/find, etc.). The sidebar "Which Files and Directories Should I Check?" lists the bare-minimum files I recommend checking.

If you use this technique, you can still include a line for the directory itself; just set recurse=0. This will cause Tripwire to check the directory's size, modification time, and other attributes, just not its contents. Changes to files in that directory that are not specifically checked will still trigger a violation (i.e., by causing their parent directory's modification time to change).

11.2.3.1 Updating Tripwire's database after violations or system changes

So, what happens when Tripwire reports violations? First, you need to determine whether each violation resulted from legitimate system changes, from a too-restrictive Tripwire policy, or from skullduggery. Unless your system is high profile, high risk, or just plain unlucky, the vast majority of reported violations will be false positives ? i.e., not skullduggery related.

If all the violations reported by Tripwire are from legitimate changes, you'll want to update the Tripwire database to reflect your new system state. This way, you don't have to see the same violations again next time. (You may want to tweak your policy too, but more on that shortly.) There are two ways to do this.

The first is to run the command tripwire in update mode:

tripwire --update --twrfile  /path/to/report/myhost-date.twr 

where the last argument is the absolute path to the report you wish to use as the basis for this update; by default, Tripwire saves its reports to /var/lib/tripwire/report. Running tripwire in update mode opens the specified report with your editor of choice (as indicated in tw.cfg). This allows you to review the items Tripwire has flagged with an x as needing to be updated in its database. By default, all changed files will be flagged; you can leave them that way or unflag them as you see fit. When you exit the editing session, Tripwire will update the attributes and hashes in its database accordingly.

Example 11-7 shows an excerpt from a tripwire -- update session.

Example 11-7. Updating the Tripwire database (session excerpt)
Remove the "x" from the adjacent box to prevent updating the database

with the new values for this object.

Modified:

[x] "/home/mick/www"

In Example 11-7, if I delete the x from the entry, exit the editor, and run a check, the change to /home/mick/www will be reported again; the database will not have updated to reflect this change. In short, if the change is legitimate, leave the x there. If it isn't or you're not sure, remove the x.

The second way to update the Tripwire database is by doing the actual check in "interactive" mode, which immediately triggers an update session after the check finishes. Thus, the single command:

tripwire --check --interactive

is equivalent to these two commands:

tripwire --check 

tripwire --update --twrfile  /path/to/reportname.twr 

but with the added advantage of saving you the trouble of looking up the report's filename (which, since it includes a timestamp, isn't easily guessed). Being interactive, of course, this method can't be used for automated checks (e.g., cron jobs). (Updating the Tripwire database should never be done unattended, even though it's possible. You'll never hear how from me, though; it's that dumb of an idea.)

11.2.4 Changing Tripwire's Policy

I needn't bother repeating my mantra "some false positives are okay, no false negatives are!" But after your first Tripwire check or two, you'll probably want to adjust your Tripwire policy to exclude some things, include others, and watch still others less closely.

Earlier, I mentioned that the twadmin command should be used to install only the initial policy, not updated policies. If you need to change your Tripwire policy after the database has been initialized (i.e., after you've run tripwire -- init), use the following commands to dump, edit, and install it again (Example 11-8).

Example 11-8. Dumping, editing, and reinstalling Tripwire's policy
twadmin --print-polfile >  mypolicy.txt              # dump current installed policy

vi  mypolicy.txt                                     # make changes to policy

...

tripwire --update-policy  mypolicy.txt               # install the updated policy

When you use the -- update-policy directive, Tripwire will parse the specified policy text file, generate a new database, and compare all records that the old and new databases have in common. If those records match, Tripwire will encrypt, sign, and install your new policy and apply the corresponding changes to its database.

If, however, any of the common records don't match, Tripwire will not update the policy or the database. You'll need to run a Tripwire check, followed by a database update (now is the perfect time to use tripwire -- check -- interactive) and then run the policy update again.

A Tip from Ron Forrester

Here's a Tripwire tip from Ron Forrester, Tripwire Open Source Project Manager:

I always leave a violation or two (say /etc/sendmail.st) in ? this makes it more difficult for an intruder to forge a report ? it is quite easy to forge a report with no violations, but add a known violation or two, and it gets much more difficult.

I think this is excellent advice. The whole point of using Tripwire is because you acknowledge the possibility that a host may be compromised; you therefore need to take what measures you can to protect the burglar alarm from the burglars. Intentionally leaving or even creating a violation or two (e.g., by adding an extra comment line to a Tripwire-protected file in /etc) is a simple way to do so.