2026年11月13日
2026年11月13日
Set Up Tripwire File Integrity Checks on Ubuntu/Debian
This article is a localized edition of the Japanese original. Read the Japanese original
Tripwire records the hash values, permissions, owners and other attributes of the files you monitor as a "known good" state in a database, then compares against it later and reports what changed. It does not prevent tampering; it is a tool for noticing that something changed without your knowledge.
This article walks through installing Open Source Tripwire on Ubuntu/Debian and setting up the basic workflow for monitoring important files across the whole server. The steps were tested on Ubuntu 24.04 (tripwire 2.4.3.7) as of November 2026. A sample policy for monitoring WordPress files is covered in How to detect file tampering with Tripwire (for WordPress servers).
How Tripwire works and its main files
Tripwire only trusts files signed with its keys. You write the configuration and policy as text, then convert them into key-signed versions before Tripwire uses them.
| File | Role |
|---|---|
/etc/tripwire/twcfg.txt |
Text version of the configuration (for editing) |
/etc/tripwire/tw.cfg |
Signed configuration (what Tripwire actually reads) |
/etc/tripwire/twpol.txt |
Text version of the monitoring policy (for editing) |
/etc/tripwire/tw.pol |
Signed policy (what Tripwire actually reads) |
/etc/tripwire/site.key |
Site key. Signs the configuration and policy |
/etc/tripwire/<hostname>-local.key |
Local key. Signs the database and reports |
/var/lib/tripwire/<hostname>.twd |
Database holding the known good state |
/var/lib/tripwire/report/*.twr |
Check reports |
Editing the text version alone has no effect. Forgetting to re-sign and then wondering why a change "doesn't work" is the most common early stumbling block.
Installing and creating keys
sudo apt update
sudo apt install tripwire
During installation you are asked, one after another, whether to set passphrases for the site key and local key and whether to create the configuration and policy files. If you set them here, the keys and signed files in the table above are created.
Do not store the passphrases in a file on the server; keep them somewhere else, such as a password manager. An attacker who knows the passphrases can rebuild the database and erase the traces of their changes.
If you did not create keys during installation, or want to recreate them, create them with twadmin and sign the configuration and policy.
sudo twadmin --generate-keys --site-keyfile /etc/tripwire/site.key
sudo twadmin --generate-keys --local-keyfile /etc/tripwire/$(hostname)-local.key
sudo twadmin --create-cfgfile -S /etc/tripwire/site.key /etc/tripwire/twcfg.txt
sudo twadmin --create-polfile -S /etc/tripwire/site.key /etc/tripwire/twpol.txt
On RHEL-family systems (AlmaLinux/Rocky Linux 9 and similar), tripwire is available from the EPEL repository (2.4.3.7 confirmed in EPEL 9 as of November 2026). The twadmin and tripwire commands are the same, but check where the files are installed with rpm -ql tripwire before you continue.
Adjusting the policy to your environment
The default twpol.txt is written for a generic Linux system and lists many files that don't exist on your machine. If you initialize or run a check with it as is, you get a flood of warnings like this:
### Warning: File system error.
### Filename: /root/.tcshrc
### No such file or directory
Keep a copy of the original first, then edit the file and comment out the lines for paths that don't exist with #.
sudo cp /etc/tripwire/twpol.txt /etc/tripwire/twpol.txt.orig
sudo nano /etc/tripwire/twpol.txt
The top of the policy defines variables that express how strictly each item is monitored.
| Variable | Meaning |
|---|---|
SEC_CRIT |
Critical files that must not change |
SEC_BIN |
Programs that should not change ($(ReadOnly)) |
SEC_CONFIG |
Configuration files that may be changed ($(Dynamic)) |
SEC_LOG |
Files that grow but whose owner and similar attributes do not change ($(Growing)) |
SIG_LOW / SIG_MED / SIG_HI |
Severity (33 / 66 / 100) |
To add your own monitoring targets, append a rule block at the end. The following example monitors the web server configuration and the programs in the public directory, and sends this rule's findings to a specific address when something changes. Adjust the paths to your environment.
(
rulename = "Web server config",
severity = $(SIG_HI),
emailto = admin@example.com
)
{
/etc/nginx -> $(SEC_CONFIG) ;
/etc/php -> $(SEC_CONFIG) ;
/var/www/html -> $(SEC_BIN) ;
!/var/www/html/wp-content/uploads ;
!/var/www/html/wp-content/cache ;
}
Paths prefixed with ! are excluded from monitoring. If you don't exclude places that change every day, such as uploads and caches, you get so many notifications that the changes you really need to see get buried.
When you finish editing, rebuild the signed policy.
sudo twadmin --create-polfile -S /etc/tripwire/site.key /etc/tripwire/twpol.txt
Initializing the database
Initialization records "the current state of the files is correct." If you initialize on a server that has already been compromised, Tripwire will remember the tampered state as correct. Do it right after installing the OS, or after verifying your packages. On Debian-based systems, sudo debsums -s from the debsums package checks whether files installed from packages are identical to what was distributed.
sudo tripwire --init
After you enter the local key passphrase, the database is created at /var/lib/tripwire/<hostname>.twd and the output ends with "The database was successfully generated." If "No such file or directory" warnings remain, fix the corresponding lines in the policy, then sign and initialize again.
Running a check and reading the report
sudo tripwire --check
The results are shown on screen and also saved to /var/lib/tripwire/report/<hostname>-date-time.twr. The report can't be read as is, so display it with twprint.
sudo ls -t /var/lib/tripwire/report/
sudo twprint --print-report --twrfile /var/lib/tripwire/report/hostname-20261110-020001.twr
The report lists, per rule, the number of Added, Removed and Modified objects, followed by the affected paths and the attributes that changed (size, hash, modification time and so on). To check only a specific rule, use sudo tripwire --check --rule-name "Web server config"; to check only a specific file, use something like sudo tripwire --check /etc/passwd.
When you find changes, checking them in this order makes them easier to judge:
- Can they be explained by your own work, such as package updates or configuration changes? (Compare with
/var/log/apt/history.logand your change records.) - Are there added files you can't explain, especially executables or scripts?
- Have files that attackers commonly modify after a break-in changed, such as
/etc/passwd,/etc/shadow,/etc/ssh/sshd_configor the cron configuration?
Daily checks and email notifications
The Debian/Ubuntu package installs /etc/cron.daily/tripwire, which runs the following command every day. You don't need to add it to crontab yourself.
/usr/sbin/tripwire --check --quiet --email-report
With --email-report, reports go to the emailto addresses written in the policy rules. To send every result to a single address, add GLOBALEMAIL to twcfg.txt. The default delivery method is MAILMETHOD=SMTP with SMTPHOST=localhost and SMTPPORT=25, so the server needs to be able to send mail (with Postfix or similar).
GLOBALEMAIL =admin@example.com
After changing twcfg.txt, sign it again and send a test email to confirm delivery.
sudo twadmin --create-cfgfile -S /etc/tripwire/site.key /etc/tripwire/twcfg.txt
sudo tripwire --test --email admin@example.com
By default MAILNOVIOLATIONS=true, so you receive a result even on days with no changes. If a day's email doesn't arrive, you can treat that as a sign that either Tripwire or mail delivery has stopped.
Updating the database after changes
After legitimate changes such as apt upgrade, the next check reports a large number of changes. Review them, then update the database using that report.
sudo tripwire --check
sudo tripwire --update --twrfile /var/lib/tripwire/report/latest-report.twr
Running --update opens the report in an editor, with [x] marked on the lines for changes to be accepted. Remove the x from changes you don't want to accept, save, and enter the local key passphrase to update the database. There is also --accept-all, which accepts everything without review, but it takes away your chance to spot changes unrelated to your work, so for day-to-day operation we recommend reviewing in the editor.
To change what is monitored, edit twpol.txt and then replace the policy with the following command. You are asked for both the site key and local key passphrases.
sudo tripwire --update-policy /etc/tripwire/twpol.txt
Operational notes
- Because the Tripwire binaries, database and keys live on the same server, an attacker with root access may be able to rewrite them. Keeping copies of the freshly initialized database, the signed policy and the keys outside the server (on read-only media or another server) protects your baseline for comparison.
- Recovery after you detect a change is done with backups and reinstallation. Tripwire only goes as far as detection.
- AIDE, which plays a similar role, can be installed from the standard repository (AppStream) on RHEL-family systems. Choosing the tool your distribution treats as standard is another option.
- Combine Tripwire with a separate tool for rootkit scanning. See also How to detect rootkits with rkhunter.
Summary
- Tripwire reads the signed
tw.cfgandtw.pol, so re-sign withtwadminafter editing the text versions - The default policy includes paths that don't exist, so comment them out before initializing
- Initialize only once you have confirmed the system has not been tampered with
- On Debian/Ubuntu,
/etc/cron.daily/tripwireruns a check every day and sends the results to theemailtoorGLOBALEMAILaddress - After legitimate changes, review the report and then update the database with
tripwire --update
Questions about WordPress? The publisher of this site is based in Japan and replies in Japanese. Contact (Japanese)