Tripwire
Implement a system to detect file tampering on Linux servers by crackers.
This time, Tripwire, a host-based IDS (IDS=Intrusion Detection System), will be installed as the file tampering detection system.
Tripwire creates a database of file status at the time of installation, and detects file additions/changes/deletions by comparing the database with the current status of the file.
1 Installation and Configuration
# apt -y install tripwire




Creating a Site Key Passphrase
Tripwire requires a site passphrase to secure the "tw.cfg" tripwire configuration file and the "tw.pol" tripwire policy file. The specified passphrase is used to encrypt both files. The site passphrase is also required for a single instance of tripwire.


Creating a Local Key Passphrase
A local passphrase is required to protect the tripwire database and report file; a local key used by tripwire to avoid unauthorized modification of the tripwire baseline database.


Installation will proceed and complete.

2 Configuration File Settings
Tripwire configuration file (twcfg.txt)
The tripwire configuration file (twcfg.txt) is detailed below. The paths to the encrypted policy file (tw.pol), site key (site.key), and local key (hostnamelocal.key), etc. are as follows
ROOT =/usr/sbin #executable file
POLFILE =/etc/tripwire/tw.pol
DBFILE =/var/lib/tripwire/$(HOSTNAME).twd #database file
REPORTFILE =/var/lib/tripwire/report/$(HOSTNAME)-$(DATE).twr
SITEKEYFILE =/etc/tripwire/site.key
LOCALKEYFILE =/etc/tripwire/$(HOSTNAME)-local.key
EDITOR =/usr/bin/editor
LATEPROMPTING =false
LOOSEDIRECTORYCHECKING =false
MAILNOVIOLATIONS =true
EMAILREPORTLEVEL =3
REPORTLEVEL =3
SYSLOGREPORTING =true
MAILMETHOD =SMTP
SMTPHOST =localhost
SMTPPORT =25
TEMPDIRECTORY =/tmp
3 Initial setup including key creation, database creation, etc.
①Edit twcfg.txt
# cd /etc/tripwire
# vi twcfg.txt
Line 9 : Changed to "true
LOOSEDIRECTORYCHECKING =true
Line 12:Change as needed (maximum report level: 4)
REPORTLEVEL =4
② configuration file generation
# twadmin -m F -c tw.cfg -S site.key twcfg.txt
Please enter your site passphrase: <Site key pass>
Wrote configuration file: /etc/tripwire/tw.cfg
③ Optimize policies
Use the following policy optimization scripts to optimize your policy
# vi twpolmake.pl
Policy Optimization Script Contents
#!/usr/bin/perl
$POLFILE=$ARGV[0];
open(POL,"$POLFILE") or die "open error: $POLFILE" ;
my($myhost,$thost) ;
my($sharp,$tpath,$cond) ;
my($INRULE) = 0 ;
while (<POL>) {
chomp;
if (($thost) = /^HOSTNAME\s*=\s*(.*)\s*;/) {
$myhost = `hostname` ; chomp($myhost) ;
if ($thost ne $myhost) {
$_="HOSTNAME=\"$myhost\";" ;
}
}
elsif ( /^{/ ) {
$INRULE=1 ;
}
elsif ( /^}/ ) {
$INRULE=0 ;
}
elsif ($INRULE == 1 and ($sharp,$tpath,$cond) = /^(\s*\#?\s*)(\/\S+)\b(\s+->\s+.+)$/) {
$ret = ($sharp =~ s/\#//g) ;
if ($tpath eq '/sbin/e2fsadm' ) {
$cond =~ s/;\s+(tune2fs.*)$/; \#$1/ ;
}
if (! -s $tpath) {
$_ = "$sharp#$tpath$cond" if ($ret == 0) ;
}
else {
$_ = "$sharp$tpath$cond" ;
}
}
print "$_\n" ;
}
close(POL) ;
# perl twpolmake.pl twpol.txt > twpol.txt.new
# twadmin -m P -c tw.cfg -p tw.pol -S site.key twpol.txt.new
Please enter your site passphrase: <Site key pass>
Wrote policy file: /etc/tripwire/tw.pol
Exclude the Tripwire database itself from the check
# echo ! "/var/lib/tripwire/`hostname`.twd ;" >> /etc/tripwire/twpol.txt.new
④Database Creation
# tripwire -m i -s -c tw.cfg
Please enter your local passphrase: <local key pass>
If it stops with an error on the way, reexecute with the "--verbose" option.
# tripwire -m i -c tw.cfg --verbose
Please enter your local passphrase: <local key pass>
Display the progress, check the files and directories that stop with errors, set the owner and access rights, and execute the following again
# tripwire -m i -s -c tw.cfg
Please enter your local passphrase: <local key pass>
In our case, the error occurred in the following file
--- Generating information for: /usr/lib/firmware/intel
Software interrupt forced exit: Segmentation Fault
Segmentation fault
I solved the problem by changing the ownership of /usr/lib/firmware/intel to root
# chown -R root:root /usr/lib/firmware/intel
4 Perform checks
①Create test files
# echo test > /root/test.txt
②Check Tripwire operation
# tripwire -m c -s -c /etc/tripwire/tw.cfg
If successful, the following display appears
Open Source Tripwire(R) 2.4.3.7 Integrity Check Report
Report generated by: root
Report created on: Sat 30 May 2026 09:02:52 AM JST
Database last updated on: Never
===============================================================================
Report Summary:
===============================================================================
Host name: Lepard
Host IP address: Unknown IP
Host ID: None
Policy file used: /etc/tripwire/tw.pol
Configuration file used: /etc/tripwire/tw.cfg
Database file used: /var/lib/tripwire/Lepard.twd
Command line used: tripwire -m c -s -c /etc/tripwire/tw.cfg
===============================================================================
Rule Summary:
===============================================================================
-------------------------------------------------------------------------------
Section: Unix File System
-------------------------------------------------------------------------------
Rule Name Severity Level Added Removed Modified
--------- -------------- ----- ------- --------
Other binaries 66 0 0 0
Tripwire Binaries 100 0 0 0
Other libraries 66 0 0 0
Root file-system executables 100 0 0 0
* Tripwire Data Files 100 1 0 0
System boot changes 100 0 0 0
Root file-system libraries 100 0 0 0
(/lib)
Critical system boot files 100 0 0 0
Other configuration files 66 0 0 0
(/etc)
Boot Scripts 100 0 0 0
Security Control 66 0 0 0
* Root config files 100 1 0 0
Devices & Kernel information 100 0 0 0
(/dev)
Invariant Directories 66 0 0 0
Total objects scanned: 40558
Total violations found: 2
===============================================================================
Object Summary:
===============================================================================
-------------------------------------------------------------------------------
# Section: Unix File System
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Rule Name: Tripwire Data Files (/var/lib/tripwire/Lepard.twd)
Severity Level: 100
-------------------------------------------------------------------------------
Added:
"/var/lib/tripwire/Lepard.twd"
-------------------------------------------------------------------------------
Rule Name: Root config files (/root)
Severity Level: 100
-------------------------------------------------------------------------------
Added:
"/root/test.txt"
===============================================================================
Error Report:
===============================================================================
No Errors
-------------------------------------------------------------------------------
*** End of report ***
Open Source Tripwire 2.4 Portions copyright 2000-2018 Tripwire, Inc. Tripwire is a registered
trademark of Tripwire, Inc. This software comes with ABSOLUTELY NO WARRANTY;
for details use --version. This is free software which may be redistributed
or modified only under certain conditions; see COPYING for details.
All rights reserved.
Delete the test file.
# rm -f /root/test.txt
5 Tripwire Autorun
①Create an automated execution script (tripwire.sh) that reports results via email and set it to run automatically.
# cd /opt/script
# vi tripwire.sh
Contents of auto-execute script (tripwire.sh)
#!/bin/bash
PATH=/usr/sbin:/usr/bin:/bin:/usr/local/tripwire/sbin
# Passphrase setting
LOCALPASS=xxxxx # local key passphrase
SITEPASS=xxxxx # site key passphrase
#Email Address for Notification
MAIL="<your mailaddress>"
cd /etc/tripwire
# Tripwire check run
tripwire -m c -s -c tw.cfg|mail -s "Tripwire(R) Integrity Check Report in `hostname`" $MAIL
# Policy File Update
twadmin -m p -c tw.cfg -p tw.pol -S site.key > twpol.txt
perl twpolmake.pl twpol.txt > twpol.txt.new
twadmin -m P -c tw.cfg -p tw.pol -S site.key -Q $SITEPASS twpol.txt.new > /dev/null
rm -f twpol.txt* *.bak
# Database modernization
rm -f /usr/local/tripwire/lib/tripwire/*.twd*
tripwire -m i -s -c tw.cfg -P $LOCALPASS
②Give execute permission and execute periodically by Cron.
# chmod 700 tripwire.sh
# crontab -e
0 5 * * * /opt/script/tripwire.sh
Execute the following and confirm that the results are delivered to the specified e-mail address
# /opt/script/tripwire.sh
Logwatch
Logwatch compiles various logs together and delivers them as a report via email on a regular daily basis. This is a useful tool for detecting unauthorized access and problems and monitoring servers.
①Install
# apt -y install logwatch
②Copy the default configuration file
# cp /usr/share/logwatch/default.conf/logwatch.conf /etc/logwatch/conf/
➂Change email address, etc.
# vi /etc/logwatch/conf/logwatch.conf
Line 52 : Add the email address where you want to receive notifications below as a comment.
#MailTo = root
MailTo = [E-mail address]
Line 85 : Set the level of detail for log notifications
#Detail = Low
Detail = High
④Creating Directories
# mkdir /var/cache/logwatch
⑤Confirmation of Operation
When logwatch is installed, cron is registered by default, so report mail is delivered every day.
Test if the report is delivered to the address you set.
# /etc/cron.daily/00logwatch
Disk Usage Check Script
1. Script creation
# cd /opt/script/
# vi disk_capacity_check.sh
Contents of disk_capacity_check.sh
#!/bin/bash
#Specify notification email address
MAIL="<your mailaddress>"
DVAL=`/bin/df / | /usr/bin/tail -1 | /bin/sed 's/^.* \([0-9]*\)%.*$/\1/'`
if [ $DVAL -gt 80 ]; then
echo "Disk usage alert: $DVAL %" | mail -s "Disk Space Alert in `hostname`" $MAIL
fi
# chmod 700 disk_capacity_check.sh
2. Execution check
①Check current usage
# df -h
It appears as follows
Filesystem Size Used Avail Use% Mounted on
udev 1.9G 0 1.9G 0% /dev
tmpfs 388M 2.5M 386M 1% /run
/dev/sda2 28G 4.2G 23G 16% /
tmpfs 1.9G 0 1.9G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/loop0 106M 106M 0 100% /snap/core/17292
/dev/sda1 511M 5.9M 506M 2% /boot/efi
/dev/loop1 74M 74M 0 100% /snap/certbot/5603
/dev/loop2 67M 67M 0 100% /snap/core24/1643
tmpfs 388M 4.0K 388M 1% /run/user/1000
②Create a dummy file (in the example, it is called "dummyfile" and is about 20G) so that the utilization is 80% or more.
# dd if=/dev/zero of=dummyfile bs=1M count=20000
③Check again
# df -h
Verify that it is running and has reached over 80%.
④Run disk space check script
# /opt/script/disk_capacity_check.sh
You will receive an e-mail to the e-mail address you have set up with the body of the message as "Disk usage alert : 90%".
⑤Delete the "dummyfile" you created.
# rm dummyfile
⑥Periodic Execution Setting
# crontab -e
30 2 * * * /opt/script/disk_capacity_check.sh
DNS Update
Whenever the internet connection is lost or the router reboots, causing the global IP address to change, you must access the dynamic DNS service to notify it of the new IP address.
Create a dedicated Python file and schedule it for regular execution via Cron.
This time, it's about DNS settings in Valudomain.
# cd /opt/script
# vi ddnsset.py
Content of ddnsset.py
#setddns.py
import requests
import ipaddress
from datetime import datetime
from pathlib import Path
# SETTING DATA
MY_DOMAIN = "example.jp" ←Self-hosted domain
MY_PASS = "xxxxxxxxxx" ←Password
MY_HOSTNAME = "xxxx" ←Host name
OUT_FILE = Path("/tmp/ipadress") ←IP Address Log File
def time_msg():
now = datetime.now()
return now.strftime("%Y/%m/%d %H:%M:%S")
def is_valid_ip(ip_str):
try:
ipaddress.ip_address(ip_str)
return True
except ValueError:
return False
def main():
# Check Global IP Address
url_get_ip = "https://dyn.value-domain.com/cgi-bin/dyn.fcg?ip"
try:
response = requests.get(url_get_ip, timeout=10)
response.raise_for_status()
current_ip = response.text.strip()
except requests.RequestException as e:
print(f"{time_msg()} Failed to get IP: {e}")
return
# IP check
mssg = time_msg()
if not current_ip:
print(f"{mssg} invalid IP NULL")
return
if not is_valid_ip(current_ip):
print(f"{mssg} invalid IP={current_ip}")
return
# Read previous IP
previous_ip = ""
if OUT_FILE.exists():
with open(OUT_FILE, "r") as f:
previous_ip = f.read().strip()
if current_ip == previous_ip:
print(f"{time_msg()} no change IP={current_ip}")
return
else:
print(f"change IP from {previous_ip} to {current_ip}")
# Update DDNS
mssg = time_msg()
print(f"{mssg} access to value-domain")
url_set_ddns = (
f"https://dyn.value-domain.com/cgi-bin/dyn.fcg?"
f"d={MY_DOMAIN}&p={MY_PASS}&h={MY_HOSTNAME}"
)
try:
response = requests.get(url_set_ddns, timeout=10)
response.raise_for_status()
# Convert line breaks to spaces and consolidate consecutive spaces into a single space.
result = ' '.join(response.text.strip().split())
except requests.RequestException as e:
print(f"{time_msg()} Failed to update DDNS: {e}")
return
mssg = time_msg()
print(f"{mssg} {MY_HOSTNAME}.{MY_DOMAIN} {result} IP={current_ip}")
# Only save the IP address if the DDNS update is successful.
if "status=0" in result:
with open(OUT_FILE, "w") as f:
f.write(current_ip)
print(f"{mssg} Successfully saved new IP: {current_ip}")
else:
print(f"{mssg} DDNS update failed, IP not saved")
if __name__ == "__main__":
main()
IP Address Log File Creation
# touch /tmp/ipadress
Run periodically
# crontab -e
* 00 * * * /usr/bin/python3 /opt/script/ddnsset.py >> /var/log/ddns_updater.log 2>&1
