This is a multi-part post because the tutorial is a bit too long for 1 post
Synopsis
This is a tutorial which I've been planning to write for approximately 2 years now. I discovered Tripwire back in my Linux days and I was immediately a fan. I like that it utilizes several features to keep its data safe, ranging from encryption right down to minor "security through obscurity". When I had just migrated from Linux to FreeBSD, roughly 3 years ago, Tripwire "sort off" worked. Things have changed, and after revising a LAN server earlier this week I got immediately reminded about how much I like this program. So... time to finally write that tutorial.
Intrusion Detection System aka IDS
An IDS is a program which can collect all kinds of information from the files (and/or directories) which you want it to monitor. This data is then stored into a database and used to check against later in order to detect any possible changes. There are several IDS solutions available, FreeBSD even includes a simple one in its base system: mtree(8). My favorite though is security/tripwire.
Lets start from scratch!
Although Tripwire provides options to automatically generate some of its files during installation I personally prefer not to. In this tutorial we're going to start out from scratch and slowly work our way towards a fully working setup. The underlying reasoning should be obvious: a little bit of paranoia can't hurt when using security software, so instead of relying on automated scripts we're going to actually make things happen ourselves. This also helps us to understand what is happening, and why.
Now, the first thing to know about Tripwire is that it requires 2 aspects to be set up: a configuration file which tells it where to find all the files it needs (and also to customize the way it operates) and the so called policy file. The policy file tells Tripwire what it should monitor and how.
Here's where things become interesting: all the data which Tripwire uses gets encrypted. So good look to you if you suddenly discover that my policy file is /usr/local/etc/tripwire/tw.pol. Even if you manage to obtain this file then it won't do you much good because the file is, as said, encrypted.
Step one: Generate your keys
We will need a key in order to encrypt something, and Tripwire works no different. Tripwire utilizes two keys: a site (or global) key and a local key. Basically the site key is mostly used to handle the configuration files, while the local key is used to sign the database.
So go to the Tripwire configuration directory which is /usr/local/etc/tripwire by default, then issue this command:
Tripwire will also be using two passwords. For ease of use you could consider to use the same password for both keyfiles, but I'd still advice you to use different passwords. One password is used to control the Tripwire configuration (site key) while the other is used to protect the database integrity (local key).
Step two: Set up a configuration file
Tripwire needs to know where to find the files it needs. From the key files, the policy file right up to the database file which we'll be eventually creating. All this information is stored in the configuration file. As mentioned above: all files which Tripwire needs will end up getting encrypted, so we're going to start by creating a textfile which will eventually get processed. I prefer to call this file twconfig.txt so that there can be no confusion with other files.
A good place to determine what needs to be configured is the twconfig(5) manualpage. Not only does this explain to you what format we can use (keyword = value) but it also presents us with the minimal required settings:
So all we have to do is to copy and paste this into our configuration file and change some of the values. For example; by default Tripwire stores its database in /var/lib/tripwire, as can be seen above, but that's not the right location for FreeBSD. Instead we'll be using: /var/db/tripwire.
Also notice the $(HOSTNAME) substitution in the file above, used for the local key? If you're following my tutorial then this needs to be changed into local.key. So eventually we end up with this:
However, I strongly suggest that you read over the twconfig(5) manualpage to see if there are other options which you'd like to use.
For example, even though I prefer vi for most of the configuration editing I do I'm actually pointing the EDITOR option to /usr/local/bin/vim, for the simple reason that it has a larger undo buffer as well as an option to split the screen (which makes it easy to work in more places within the same file).
Another option which you might appreciate, especially if we're a little paranoia, is LATEPROMPTING; this ensures that the password prompts during operation will happen as late and as close together as possible, thus reducing the time when the passwords are kept in active memory.
When we're all done its time to create the actual configuration file by encrypting the textfile. Because Tripwire has no configuration yet we have to specify every file we need (including the keyfile) manually. So here goes:
Step three: Setting up a policy file
Now that we have successfully configured Tripwire it's time to put it to good use. And to do so we'll need to tell it what it should monitor and how. Tripwire can monitor nearly every aspect of a file system entry (file or directory); from access time (+a), modification time (+m), file size (+s) and file type (+t) right down to file or group owner (+u and +g respectfully).
Of course these won't be enough. After all: if you keep track of file size then this gives you no guarantees that nothing changed. Lets say I have a textfile which contains: "Peter likes playing Minecraft", very sensitive information indeed These are 30 characters.
So now lets look at this: "Peter likes playing Warcraft!". I don't like Warcraft, I don't even know if this is actually a game of some sort. But if we were only keeping track of file statistics then we wouldn't even be noticing this change at all. What's that? Access and creation dates of the file you say? That's nothing which touch(1) can't handle. I'll use stat(1) up front to check for the current timestamps, and after I changed the file to my liking I'll use touch to set them back again.
And that's why Tripwire can also generate hash checksums. Using not one but four different methods: CRC32 (+C), Haval (+H), MD5 (+M) and SHA (+S), all of which can be used either individually, grouped or all at once. If you like to learn more about cryptographic hash functions then check out this wikipedia page.
Now, my policy file example consists of several rules where each rule can check one or more files or directories. However, Tripwire is a very flexible program and it allows us to define these rules in more than one way. Instead of one rule which checks multiple files I can also set up one rule per file (or directory). But for clarity sake I'll be focusing on one specific format only, while also briefly mentioning the other format near the end of this section.
So:
Rule definition
Here we configure the attributes of our rule. Things like the rulename, severity and optionally an e-mail address which will be used if a violation has been discovered, this is defined using emailto.
Severity can be a number ranging from 0 (default) to 1,000,000. Its primary use is to control which rules to check. By default all the rules in the policy will be checked against the database, but you could also set it up so that only a specific selection of rules is checked, for example only those which have a severity of 80 and higher.
Monitor directives
Here you configure the properties which I mentioned earlier, they determine which aspects are being monitored and which hash functions are to be used. A directive can be turned on by using a + and turned off, or excluded, by using a -.
Here is a full list of all the directives which you can use, it's actually from the header of my own Tripwire policy file:
For a complete overview I suggest that you check out the twpolicy(5) manualpage.
Now, before we set up our first rule there are 2 more things which I'd like to address: variables and directives.
Policy variables
As you can see there are 14 monitoring directives which we can use. And trust me when I say that you might be able to remember them if you've been working with Tripwire for a while, but after a few weeks you won't anymore. And then it can become quite bothersome to add a new file or directory to monitor, because what directives are you going to use again?
So to make things a bit easier on us we can also use variables. There are 6 variables defined by default:
And of course we're also free to create our own. For example: if you look closely then you'll notice that IgnoreNone also includes the +a (access time) directive. This basically means that as soon as a file gets accessed then Tripwire will notice it. Can you imagine what will happen if you use this for a directory such as /bin?
So to prevent all that nastiness I created some variables of my own:
A variable can be used in almost the same way as in a shellscript: $(variable). So if I were to check a directory of binaries and I wanted to check everything but the access time then I'd use this: "/bin -> $(CheckAll);" (without the ""'s obviously). I hope you can agree with me that it's much easier to use and understand than the substitute: "/bin -> +pinugtsdrbamcCMSH-al".
Policy directives
Now, I'm only going to address these briefly because in a regular situation you won't be needing these. But it is good to realize that they exist, because they can make your life a whole lot easier, especially if you're using Tripwire on a server farm or if you need to bugfix your policy file.
@@ifhost, @@else, @@endif. These can be used to include rules in your policy file which are only to be used on specific hosts. This allows you to maintain one policy file and then use that across all your servers. For example:
This would ensure that Tripwire will only check for /usr/local/etc/pksd.conf while it's being used on my pks server. As you can see this rule also looks much different than the template I shared at the start of this section. This is the other format which I mentioned earlier.
@@print and @@error. These can be used to bugfix your policy file, they will output a message to either stdout or stderr which allows you to determine which parts Tripwire is processing.
And finally there's @@section and @@end. You can ignore @@section because its use is pretty redundant. Some package maintainers on Linux use this in their template but it's meaningless because all it basically does is to allow Tripwire to ignore certain policy sections when it's being used on multiple operating systems, Windows in particular. Needless to say: I'm focusing on FreeBSD usage here.
@@end can be useful, this can mark the physical end of the policy file. However its use isn't required.
Our first useful policy file
Here is the first rule of my own Tripwire policy file. As you can see this rule checks my Tripwire installation itself. You'll probably recognize $(CheckAll); this is a variable which I set at the beginning of my template file. (see further above and also in the template which I'm sharing). And you can also see some manually defined directives (+iptug).
But there are also some things which I haven't mentioned. recurse is an attribute which allows you to control how deep Tripwire should scan a directory. When set to false, like here, it will only check the directory entry itself but not its contents. In the example above I use this to check that the database directory doesn't get tampered with, but without checking the actual database files themselves.
The exclamation mark (!) is a stop point, this literally tells Tripwire to ignore certain files or directories. Here we also see the only small caveat of a Tripwire policy: it's not easy to separate file entries from directory entries. Alas: first I told Tripwire that it should check all the files in its configuration directory (/usr/local/etc/tripwire). However; the text files which we're initially editing are not used by Tripwire. So there's no reason to include these in our checks. The same applies to the files with the .bak extension; the very moment you update your policy or configuration file then Tripwire will also make a backup copy. It won't be actively used, so there really is no need to include it.
If you want to simply copy/paste this rule to get you started with an example then I suggest to include my template. Otherwise replace the $(CheckAll) with either $(IgnoreNone)-a or +pinugtsdrbamcCMSH-al.
Now it's time to actually create our policy file!
Just like with the configuration file we need to tell Tripwire to encrypt it. However, because we already have our configuration file in place there's no need to specify any keys. As such we're now using:
Synopsis
This is a tutorial which I've been planning to write for approximately 2 years now. I discovered Tripwire back in my Linux days and I was immediately a fan. I like that it utilizes several features to keep its data safe, ranging from encryption right down to minor "security through obscurity". When I had just migrated from Linux to FreeBSD, roughly 3 years ago, Tripwire "sort off" worked. Things have changed, and after revising a LAN server earlier this week I got immediately reminded about how much I like this program. So... time to finally write that tutorial.
Intrusion Detection System aka IDS
An IDS is a program which can collect all kinds of information from the files (and/or directories) which you want it to monitor. This data is then stored into a database and used to check against later in order to detect any possible changes. There are several IDS solutions available, FreeBSD even includes a simple one in its base system: mtree(8). My favorite though is security/tripwire.
Lets start from scratch!
Although Tripwire provides options to automatically generate some of its files during installation I personally prefer not to. In this tutorial we're going to start out from scratch and slowly work our way towards a fully working setup. The underlying reasoning should be obvious: a little bit of paranoia can't hurt when using security software, so instead of relying on automated scripts we're going to actually make things happen ourselves. This also helps us to understand what is happening, and why.
Now, the first thing to know about Tripwire is that it requires 2 aspects to be set up: a configuration file which tells it where to find all the files it needs (and also to customize the way it operates) and the so called policy file. The policy file tells Tripwire what it should monitor and how.
Here's where things become interesting: all the data which Tripwire uses gets encrypted. So good look to you if you suddenly discover that my policy file is /usr/local/etc/tripwire/tw.pol. Even if you manage to obtain this file then it won't do you much good because the file is, as said, encrypted.
Step one: Generate your keys
We will need a key in order to encrypt something, and Tripwire works no different. Tripwire utilizes two keys: a site (or global) key and a local key. Basically the site key is mostly used to handle the configuration files, while the local key is used to sign the database.
So go to the Tripwire configuration directory which is /usr/local/etc/tripwire by default, then issue this command:
# twadmin -m G -L local.key -S site.key
. This will generate the two key files. By default Tripwire tends to use the hostname for the local key filename, but this is fully customizable. In this tutorial I'll be using local.key, also for easier access.Tripwire will also be using two passwords. For ease of use you could consider to use the same password for both keyfiles, but I'd still advice you to use different passwords. One password is used to control the Tripwire configuration (site key) while the other is used to protect the database integrity (local key).
Step two: Set up a configuration file
Tripwire needs to know where to find the files it needs. From the key files, the policy file right up to the database file which we'll be eventually creating. All this information is stored in the configuration file. As mentioned above: all files which Tripwire needs will end up getting encrypted, so we're going to start by creating a textfile which will eventually get processed. I prefer to call this file twconfig.txt so that there can be no confusion with other files.
A good place to determine what needs to be configured is the twconfig(5) manualpage. Not only does this explain to you what format we can use (keyword = value) but it also presents us with the minimal required settings:
Code:
Required Variables
The following variables must be set in order for Tripwire to operate.
The values listed below are assigned during installation.
POLFILE Default = /usr/local/etc/tripwire/tw.pol
DBFILE Default = /var/lib/tripwire/$(HOSTNAME).twd
REPORTFILE Default = /var/lib/tripwire/report/$(HOSTNAME)-$(DATE).twr
SITEKEYFILE Default = /usr/local/etc/tripwire/site.key
LOCALKEYFILE Default = /usr/local/etc/tripwire/$(HOSTNAME)-local.key
Also notice the $(HOSTNAME) substitution in the file above, used for the local key? If you're following my tutorial then this needs to be changed into local.key. So eventually we end up with this:
Code:
## twconfig.txt, Tripwire configuration file
POLFILE = /usr/local/etc/tripwire/tw.pol
DBFILE = /var/db/tripwire/$(HOSTNAME).twd
REPORTFILE = /var/db/tripwire/report/$(HOSTNAME)-$(DATE).twr
SITEKEYFILE = /usr/local/etc/tripwire/site.key
LOCALKEYFILE = /usr/local/etc/tripwire/local.key
For example, even though I prefer vi for most of the configuration editing I do I'm actually pointing the EDITOR option to /usr/local/bin/vim, for the simple reason that it has a larger undo buffer as well as an option to split the screen (which makes it easy to work in more places within the same file).
Another option which you might appreciate, especially if we're a little paranoia, is LATEPROMPTING; this ensures that the password prompts during operation will happen as late and as close together as possible, thus reducing the time when the passwords are kept in active memory.
When we're all done its time to create the actual configuration file by encrypting the textfile. Because Tripwire has no configuration yet we have to specify every file we need (including the keyfile) manually. So here goes:
# twadmin -m F -S site.key twconfig.txt
. You'll be asked for your site passphrase and after that Tripwire will create the configuration file, by default this will be called /usr/local/etc/tripwire/tw.cfg. You can change this if you'd like by using the -c parameter, but in this tutorial we'll be using the defaults.Step three: Setting up a policy file
Now that we have successfully configured Tripwire it's time to put it to good use. And to do so we'll need to tell it what it should monitor and how. Tripwire can monitor nearly every aspect of a file system entry (file or directory); from access time (+a), modification time (+m), file size (+s) and file type (+t) right down to file or group owner (+u and +g respectfully).
Of course these won't be enough. After all: if you keep track of file size then this gives you no guarantees that nothing changed. Lets say I have a textfile which contains: "Peter likes playing Minecraft", very sensitive information indeed These are 30 characters.
So now lets look at this: "Peter likes playing Warcraft!". I don't like Warcraft, I don't even know if this is actually a game of some sort. But if we were only keeping track of file statistics then we wouldn't even be noticing this change at all. What's that? Access and creation dates of the file you say? That's nothing which touch(1) can't handle. I'll use stat(1) up front to check for the current timestamps, and after I changed the file to my liking I'll use touch to set them back again.
And that's why Tripwire can also generate hash checksums. Using not one but four different methods: CRC32 (+C), Haval (+H), MD5 (+M) and SHA (+S), all of which can be used either individually, grouped or all at once. If you like to learn more about cryptographic hash functions then check out this wikipedia page.
Now, my policy file example consists of several rules where each rule can check one or more files or directories. However, Tripwire is a very flexible program and it allows us to define these rules in more than one way. Instead of one rule which checks multiple files I can also set up one rule per file (or directory). But for clarity sake I'll be focusing on one specific format only, while also briefly mentioning the other format near the end of this section.
So:
Code:
(<rule definition>)
{
/file/system/entry/to/monitor -> <monitor directives>;
}
Rule definition
Here we configure the attributes of our rule. Things like the rulename, severity and optionally an e-mail address which will be used if a violation has been discovered, this is defined using emailto.
Severity can be a number ranging from 0 (default) to 1,000,000. Its primary use is to control which rules to check. By default all the rules in the policy will be checked against the database, but you could also set it up so that only a specific selection of rules is checked, for example only those which have a severity of 80 and higher.
Monitor directives
Here you configure the properties which I mentioned earlier, they determine which aspects are being monitored and which hash functions are to be used. A directive can be turned on by using a + and turned off, or excluded, by using a -.
Here is a full list of all the directives which you can use, it's actually from the header of my own Tripwire policy file:
Code:
## Directives
# a - Access timestamp m - Modification timestamp
# b - Allocated blocks n - Number of links
# c - INode timestamp p - Permission & filemode bits
# d - ID of device r - ID of device pointed to (/dev)
# g - Group ID s - File size
# i - INode number t - File type
# l - Size increase ('growing') u - File owner UID
#
# C - CRC32 hash, H - Haval hash, M - MD5 hash, S - SHA hash.
Now, before we set up our first rule there are 2 more things which I'd like to address: variables and directives.
Policy variables
As you can see there are 14 monitoring directives which we can use. And trust me when I say that you might be able to remember them if you've been working with Tripwire for a while, but after a few weeks you won't anymore. And then it can become quite bothersome to add a new file or directory to monitor, because what directives are you going to use again?
So to make things a bit easier on us we can also use variables. There are 6 variables defined by default:
Code:
## Predefined
# ReadOnly Value: +pinugtsdbmCM-rlacSH
# Dynamic Value: +pinugtd-srlbamcCMSH
# Growing Value: +pinugtdl-srbamcCMSH
# Device Value: +pugsdr-intlbamcCMSH
# IgnoreAll Value: -pinugtsdrlbamcCMSH
# IgnoreNone Value: +pinugtsdrbamcCMSH-l
And of course we're also free to create our own. For example: if you look closely then you'll notice that IgnoreNone also includes the +a (access time) directive. This basically means that as soon as a file gets accessed then Tripwire will notice it. Can you imagine what will happen if you use this for a directory such as /bin?
So to prevent all that nastiness I created some variables of my own:
Code:
CheckAll = $(IgnoreNone)-a;
CheckLog = +iptugl;
A variable can be used in almost the same way as in a shellscript: $(variable). So if I were to check a directory of binaries and I wanted to check everything but the access time then I'd use this: "/bin -> $(CheckAll);" (without the ""'s obviously). I hope you can agree with me that it's much easier to use and understand than the substitute: "/bin -> +pinugtsdrbamcCMSH-al".
Policy directives
Now, I'm only going to address these briefly because in a regular situation you won't be needing these. But it is good to realize that they exist, because they can make your life a whole lot easier, especially if you're using Tripwire on a server farm or if you need to bugfix your policy file.
@@ifhost, @@else, @@endif. These can be used to include rules in your policy file which are only to be used on specific hosts. This allows you to maintain one policy file and then use that across all your servers. For example:
Code:
@@ifhost pks.intranet.lan
/usr/local/etc/pksd.conf -> $(CheckAll) (rulename=GPG_conf, severity=80);
@@endif
@@print and @@error. These can be used to bugfix your policy file, they will output a message to either stdout or stderr which allows you to determine which parts Tripwire is processing.
And finally there's @@section and @@end. You can ignore @@section because its use is pretty redundant. Some package maintainers on Linux use this in their template but it's meaningless because all it basically does is to allow Tripwire to ignore certain policy sections when it's being used on multiple operating systems, Windows in particular. Needless to say: I'm focusing on FreeBSD usage here.
@@end can be useful, this can mark the physical end of the policy file. However its use isn't required.
Our first useful policy file
Code:
## twpolicy.txt
(rulename = "Tripwire config", severity = 100)
{
/usr/local/sbin/tripwire -> $(CheckAll);
/usr/local/sbin/twadmin -> $(CheckAll);
/usr/local/sbin/twprint -> $(CheckAll);
/usr/local/sbin/twtest -> $(CheckAll);
/usr/local/sbin/siggen -> $(CheckAll);
/var/db/tripwire -> +iptug (recurse=false);
/usr/local/etc/tripwire -> $(CheckAll);
!/usr/local/etc/tripwire/tw.pol.bak;
!/usr/local/etc/tripwire/tw.cfg.bak;
!/usr/local/etc/tripwire/twconf.txt;
!/usr/local/etc/tripwire/twconfig.txt;
!/usr/local/etc/tripwire/twpol.txt;
!/usr/local/etc/tripwire/twpolicy.txt;
}
But there are also some things which I haven't mentioned. recurse is an attribute which allows you to control how deep Tripwire should scan a directory. When set to false, like here, it will only check the directory entry itself but not its contents. In the example above I use this to check that the database directory doesn't get tampered with, but without checking the actual database files themselves.
The exclamation mark (!) is a stop point, this literally tells Tripwire to ignore certain files or directories. Here we also see the only small caveat of a Tripwire policy: it's not easy to separate file entries from directory entries. Alas: first I told Tripwire that it should check all the files in its configuration directory (/usr/local/etc/tripwire). However; the text files which we're initially editing are not used by Tripwire. So there's no reason to include these in our checks. The same applies to the files with the .bak extension; the very moment you update your policy or configuration file then Tripwire will also make a backup copy. It won't be actively used, so there really is no need to include it.
If you want to simply copy/paste this rule to get you started with an example then I suggest to include my template. Otherwise replace the $(CheckAll) with either $(IgnoreNone)-a or +pinugtsdrbamcCMSH-al.
Now it's time to actually create our policy file!
Just like with the configuration file we need to tell Tripwire to encrypt it. However, because we already have our configuration file in place there's no need to specify any keys. As such we're now using:
# twadmin -m P twpolicy.txt
. You'll be asked to supply your password again and after that we're all set.Attachments
Last edited: