[PR] 本記事にはプロモーションが含まれています。

Tripwire(ファイル改ざん検知システム)|AlmaLinux 9に入れて、変更があったときだけメールで知らせる設定

自宅サーバー構築
➔ 自宅サーバー構築メモの目次はこちら

【2026年5月26日時点の情報です】

Tripwireは、サーバーの大事なファイルが、知らないうちに書き換えられていないかを確かめるソフトです。
ファイルの状態をデータベースに記録しておき、あとで比べることで、ファイルの追加・削除・変更を見つけます。不正アクセスでプログラムを書き換えられたときに、気づくきっかけになります。

このサーバーでは、毎日深夜に自動でチェックし、変更があったときだけroot宛てにメールで知らせています。root宛てのメールは、AlmaLinux 9 初期設定の記事でGmailに転送するようにしているので、スマホで確認できます。

手順は「CentOSで自宅サーバー構築」を参考にしました。

1. Tripwireをインストールする

Tripwireは、標準のリポジトリではなく、EPEL(追加パッケージのリポジトリ)にあります。先にEPELを使えるようにしてから、Tripwireを入れます。

Bash
[root@almalinux ~]# dnf -y install epel-release  ※EPELリポジトリを使えるようにする

[root@almalinux ~]# dnf -y install tripwire  ※Tripwireをインストール

[root@almalinux ~]# tripwire-setup-keyfiles  ※Tripwireの初期設定
Enter the site keyfile passphrase:  ※サイトパスフレーズを決めて入力
Verify the site keyfile passphrase:  ※もう一度入力

Enter the local keyfile passphrase:  ※ローカルパスフレーズを決めて入力
Verify the local keyfile passphrase:  ※もう一度入力

Please enter your site passphrase:  ※サイトパスフレーズを入力

Please enter your site passphrase:  ※サイトパスフレーズを入力

パスフレーズは2種類あります。サイトパスフレーズは設定やポリシーを変えるときに、ローカルパスフレーズはデータベースを作るときに使います。このあと何度も使うので、忘れないように保管しておきましょう。

【2026年11月の追記】作った鍵のファイル(site.key と ホスト名-local.key)は、だれでも読める形(-rw-r--r--)になっていました。鍵はパスフレーズで守られていますが、ほかのユーザーに写し取られると、パスフレーズを当てる試しを手元でいくらでもできてしまいます。root だけが読める形にしておきます。Tripwire は root で動くので、毎日の確かめには影響しません。

Bash
[root@almalinux ~]# ls -l /etc/tripwire/site.key /etc/tripwire/almalinux-local.key  ※今の権限を見る
-rw-r--r-- 1 root root 931 11月  1 16:38 /etc/tripwire/almalinux-local.key
-rw-r--r-- 1 root root 931 11月  1 16:38 /etc/tripwire/site.key

[root@almalinux ~]# chmod 600 /etc/tripwire/site.key /etc/tripwire/almalinux-local.key  ※rootだけが読み書きできる形にする

[root@almalinux ~]# ls -l /etc/tripwire/site.key /etc/tripwire/almalinux-local.key  ※権限が変わったか確かめる
-rw------- 1 root root 931 11月  1 16:38 /etc/tripwire/almalinux-local.key
-rw------- 1 root root 931 11月  1 16:38 /etc/tripwire/site.key

[root@almalinux ~]# twadmin --print-cfgfile > /dev/null && echo "cfg OK"  ※Tripwireが鍵を使って設定を読めるか
cfg OK
  • ls -l /etc/tripwire/site.key /etc/tripwire/almalinux-local.key:
    2つの鍵のファイルの権限を見る。-rw-r--r-- は、だれでも読める形
  • chmod 600 …:
    持ち主(root)だけが読み書きできる形にする。中身は変わらない
  • twadmin --print-cfgfile > /dev/null && echo "cfg OK":
    Tripwire が site.key を使って設定のファイル(tw.cfg)を読めるか。読めれば「cfg OK」と出る

2. Tripwireを設定する

2-1. 設定ファイルを変更する

Bash
[root@almalinux ~]# vi /etc/tripwire/twcfg.txt  ※Tripwireの設定ファイル(テキスト版)を編集
LOOSEDIRECTORYCHECKING =false
  ↓
LOOSEDIRECTORYCHECKING =true  ※ファイルが変わったときに、入っているディレクトリの変更までは通知しない

REPORTLEVEL   =3
  ↓
REPORTLEVEL   =4  ※レポートを詳しくする

2-2. ポリシーファイルを最適化する

ポリシーファイルは、「どのファイルをチェックするか」を決めるファイルです。初期状態のままだと、このサーバーにはないファイルもチェック対象に入っていて、エラーがたくさん出ます。そこで、存在しないファイルのチェックを無効にし、存在するファイルのチェックを有効にするPerlのスクリプトを作って、ポリシーファイルを整えます。

Bash
[root@almalinux ~]# vi /etc/tripwire/twpolmake.pl  ※ポリシーファイル最適化スクリプトを作成
#!/usr/bin/perl
# Tripwire Policy File customize tool
# ----------------------------------------------------------------
# Copyright (C) 2003 Hiroaki Izumi
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
# ----------------------------------------------------------------
# Usage:
#    perl twpolmake.pl {Pol file}
# ----------------------------------------------------------------
#
$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) ;

スクリプトを使ってポリシーファイルを整え、暗号署名版のポリシーファイルを作ります。

Bash
[root@almalinux ~]# perl /etc/tripwire/twpolmake.pl /etc/tripwire/twpol.txt > /etc/tripwire/twpol.txt.new  ※ポリシーファイルを最適化

[root@almalinux ~]# echo ! "/var/lib/tripwire/`hostname`.twd ;" >> /etc/tripwire/twpol.txt.new  ※Tripwireのデータベース自体はチェックしない

[root@almalinux ~]# echo ! "/tmp/tripwire.log ;" >> /etc/tripwire/twpol.txt.new  ※Tripwireのログはチェックしない(後で作る定期実行のスクリプトで使う)

[root@almalinux ~]# twadmin -m P -c /etc/tripwire/tw.cfg -p /etc/tripwire/tw.pol -S /etc/tripwire/site.key /etc/tripwire/twpol.txt.new  ※最適化したポリシーから、暗号署名版のポリシーファイルを作成
Please enter your site passphrase:  ※サイトパスフレーズを入力
Wrote policy file: /etc/tripwire/tw.pol

[root@almalinux ~]# rm -f /etc/tripwire/twpol.txt*  ※テキスト版のポリシーファイルは削除(中身を見られないようにするため)

テキスト版のポリシーファイルが必要になったときは、次のコマンドで戻せます。

Bash
[root@almalinux ~]# twadmin -m p -c /etc/tripwire/tw.cfg -p /etc/tripwire/tw.pol -S /etc/tripwire/site.key > /etc/tripwire/twpol.txt

2-3. データベースを作る

今のファイルの状態を、データベースに記録します。この記録と比べて、変更を見つけます。

Bash
[root@almalinux ~]# tripwire -m i -s -c /etc/tripwire/tw.cfg  ※Tripwireのデータベースを作成
Please enter your local passphrase:  ※ローカルパスフレーズを入力

3. 動きを確かめる

まず、そのままチェックを実行します。

Bash
[root@almalinux ~]# tripwire -m c -s -c /etc/tripwire/tw.cfg  ※Tripwireのチェックを実行
Open Source Tripwire(R) 2.4.3.7 Integrity Check Report
(途中省略)
* Tripwire Data Files             100               1        0        0
(途中省略)
Total objects scanned:  38977
Total violations found:  1
(途中省略)
Added:
"/var/lib/tripwire/almalinux.twd.bak"

ここでは、Tripwire自身が作ったデータベースのバックアップ(.twd.bak)が1件検知されています。これは問題ありません。

次に、テスト用のファイルを作って、きちんと検知されるか確かめます。

Bash
[root@almalinux ~]# echo test > test.txt  ※テスト用のファイルを作成

[root@almalinux ~]# tripwire -m c -s -c /etc/tripwire/tw.cfg  ※もう一度チェックを実行
(途中省略)
* Root config files               100               1        0        0  ← ファイルの追加を1件検知した
(途中省略)
Total violations found:  1  ← 1件の変更を検知した
(途中省略)
Rule Name: Root config files (/root)
Added:
"/root/test.txt"  ← 追加されたファイル

[root@almalinux ~]# twprint -m r --report-level 1 -c /etc/tripwire/tw.cfg -r /var/lib/tripwire/report/almalinux-20260526-104317.twr  ※チェック結果の要約を表示
Note: Report is not encrypted.
Added:  "/root/test.txt"  ※/root/test.txtの追加を検知した

[root@almalinux ~]# rm -f test.txt  ※テスト用のファイルを削除(後始末)

レポートのファイル名(almalinux-20260526-104317.twr)は、「ホスト名-日付-時刻」になるので、/var/lib/tripwire/report/ の中を ls で確かめてから指定してください。

4. 毎日自動でチェックする

毎日深夜3時に自動でチェックして、dnf の更新などで説明できない変更があったときだけroot宛てにメールで知らせるスクリプトを作ります。チェックが終わったらデータベースを作り直すので、「前の日から変わったファイル」だけが通知されます。

Bash
[root@almalinux ~]# dnf -y install tmpwatch  ※古いファイルを消すツールをインストール

[root@almalinux ~]# vi /usr/local/sbin/tripwire-filter  ※説明できない変化だけを取り出すスクリプトを作成(2026年11月に追加)
#!/bin/bash
# Tripwire の報告から、dnf の更新などで説明できない変化だけを出す。
# 使い方:tripwire-filter 報告ファイル.twr
# 終わりの番号:0 = 全部説明できた、1 = 説明できない変化がある、2 = 報告を読めなかった
set -u
R="$1"
W=$(mktemp -d); trap 'rm -rf "$W"' EXIT
/usr/sbin/twprint -m r -c /etc/tripwire/tw.cfg --twrfile "$R" -t 1 2>/dev/null \
  | grep -oE '^(Added|Modified|Removed):[[:space:]]+"[^"]+"' \
  | sed -E 's/:[[:space:]]+"/\t/; s/"$//' > "$W/all.tsv"
TOTAL=$(wc -l < "$W/all.tsv")
if [ "$TOTAL" -eq 0 ]; then echo "Tripwire の報告を読めなかった:$R"; exit 2; fi
grep -v $'\t/var/log/' "$W/all.tsv" > "$W/c.tsv" || true
awk -F'\t' '$1!="Removed"{print $2}' "$W/c.tsv" | while read -r f; do [ -d "$f" ] || echo "$f"; done | sort -u > "$W/files"
rpm -qal 2>/dev/null | sort -u > "$W/rpmfiles"
rpm -Va 2>/dev/null | awk '{print $NF}' | sort -u > "$W/mismatch"
comm -23 "$W/files" "$W/rpmfiles" | sed 's/^/[パッケージ外] /' > "$W/out"
comm -12 "$W/files" "$W/mismatch" | sed 's/^/[パッケージと違う] /' >> "$W/out"
PREV=$(ls -t /var/lib/tripwire/report/*.twr | grep -A1 -xF "$R" | sed -n 2p)
PREVT=$( [ -n "$PREV" ] && stat -c %Y "$PREV" || echo 0 )
LASTINST=$(rpm -qa --qf '%{INSTALLTIME}\n' | sort -n | tail -1)
if [ "$LASTINST" -le "$PREVT" ]; then
  awk -F'\t' '$1=="Removed"{print "[消えた] "$2}' "$W/c.tsv" >> "$W/out"
else
  awk -F'\t' '$1=="Removed" && $2 !~ /^\/usr\//{print "[消えた] "$2}' "$W/c.tsv" >> "$W/out"
fi
N=$(wc -l < "$W/out")
if [ "$N" -gt 0 ]; then
  echo "Tripwire:説明できない変化 ${N}件(調べた変化 ${TOTAL}件のうち)"
  cat "$W/out"
  echo "くわしい報告:$R"
  exit 1
fi
logger -t tripwire-filter "all ${TOTAL} changes explained ($R)"
exit 0

[root@almalinux ~]# chmod 755 /usr/local/sbin/tripwire-filter

[root@almalinux ~]# vi tripwire.sh  ※定期実行のスクリプトを作成
#!/bin/bash

# 最初からある定期実行の設定を削除
rm -f /etc/cron.daily/tripwire-check

# パスフレーズ(長いでたらめなものにする)
LOCALPASS=xxxxxxxx # ローカルパスフレーズ
SITEPASS=xxxxxxxx  # サイトパスフレーズ

TRIPWIRE=/usr/sbin/tripwire
TWADMIN=/usr/sbin/twadmin
TWPRINT=/usr/sbin/twprint
cd /etc/tripwire

# チェックを実行
# ※dnf の更新などで説明できない変化があったときだけ、root宛てに短くメールする
rm -f /var/lib/tripwire/report/`hostname`-`date +%Y%m%d`-*.twr
${TRIPWIRE} -m c -s -c tw.cfg > /tmp/tripwire.log
REPORT=$(ls -t /var/lib/tripwire/report/`hostname`-`date +%Y%m%d`-*.twr 2>/dev/null | head -1)
VIOL=$(grep "Total violations found" /tmp/tripwire.log | awk '{print $4}')
if [ -z "$REPORT" ] || [ -z "$VIOL" ]; then
    printf 'Subject: Tripwire ERROR on %s\nContent-Type: text/plain; charset=UTF-8\n\nTripwire の調べが終わらなかったか、報告が見つからない\n' "`hostname`" | /usr/sbin/sendmail root
elif [ "$VIOL" -ne 0 ]; then
    /usr/local/sbin/tripwire-filter "$REPORT" > /tmp/tripwire-filter.txt 2>&1
    if [ $? -ne 0 ]; then
        { printf 'Subject: Tripwire unexplained changes on %s\nContent-Type: text/plain; charset=UTF-8\n\n' "`hostname`"; cat /tmp/tripwire-filter.txt; } | /usr/sbin/sendmail root
    fi
fi

# 古いチェック結果を削除(過去90日分を残す)
tmpwatch -m 2160 /var/lib/tripwire/report

# ポリシーファイルを最新にする
${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

# データベースを作り直す
rm -f /var/lib/tripwire/*.twd*
${TRIPWIRE} -m i -s -c tw.cfg -P $LOCALPASS

[root@almalinux ~]# chmod 700 tripwire.sh  ※rootだけが読めて、実行できるようにする

[root@almalinux ~]# echo "0 3 * * * root /root/tripwire.sh" > /etc/cron.d/tripwire  ※毎日3時に実行する
  • /usr/local/sbin/tripwire-filter:
    報告から、記録のファイル(/var/log)と、パッケージの記録(rpm -Va)のとおりに更新されたファイルを外し、残った「説明できない変化」だけを出すスクリプト。何も残らなければ黙る
  • REPORT=…・VIOL=…:
    今日の報告のファイルの名前と、変化の数を取る。どちらかが取れなければ、エラーのメールを出す
  • /usr/local/sbin/tripwire-filter "$REPORT" …; if [ $? -ne 0 ]:
    変化があったら判断のスクリプトを動かし、説明できない変化があったときだけ、その短い結果をメールで送る
  • printf 'Subject: …\nContent-Type: text/plain; charset=UTF-8…' | /usr/sbin/sendmail root:
    件名と文字コードを付けて送る。本文が日本語なので、文字化けしないように UTF-8 を付ける

スクリプトにはパスフレーズをそのまま書くので、必ず chmod 700 で、rootだけが読めるようにしておきます。

tmpwatchがインストールできない場合は、スクリプトの tmpwatch の行を、次の行に置き換えても同じように動きます。

Bash
find /var/lib/tripwire/report -name "*.twr" -mtime +90 -delete

(2026年11月に直しました)はじめは、変化が1つでもあれば報告を丸ごとメールする形にしていました。ところが、毎朝の自動アップデート(dnf-automatic)で更新されたファイルが毎日数千件の変化として届き、読み流すしかなくなっていました。そこで、上のように、パッケージの記録のとおりに更新されたファイルなどを外して、説明できない変化があるときだけ短いメールが来る形にしました。あわせて、見張る場所を広げ、パスフレーズも長いでたらめなものに変えています。くわしくは「Tripwire の毎朝のメールを説明できない変化だけにした記事」にまとめています。

5. チェックしないファイルを追加する

ログのように、変わることが分かっているファイルやディレクトリは、チェック対象から外しておくと、余計な通知を減らせます。

Bash
[root@almalinux ~]# twadmin -m p -c /etc/tripwire/tw.cfg -p /etc/tripwire/tw.pol -S /etc/tripwire/site.key > /etc/tripwire/twpol.txt  ※テキスト版のポリシーファイルを作成

[root@almalinux ~]# echo '!/var/log/sa ;' >> /etc/tripwire/twpol.txt  ※例:ディレクトリ /var/log/sa をチェック対象外にする

[root@almalinux ~]# echo '!/etc/sysconfig/iptables ;' >> /etc/tripwire/twpol.txt  ※例:ファイル /etc/sysconfig/iptables をチェック対象外にする

[root@almalinux ~]# twadmin -m P -c /etc/tripwire/tw.cfg -p /etc/tripwire/tw.pol -S /etc/tripwire/site.key /etc/tripwire/twpol.txt  ※暗号署名版のポリシーファイルを作成
Please enter your site passphrase:  ※サイトパスフレーズを入力
Wrote policy file: /etc/tripwire/tw.pol

[root@almalinux ~]# rm -f /etc/tripwire/twpol.txt /etc/tripwire/tw.pol.bak  ※テキスト版とバックアップを削除

[root@almalinux ~]# rm -f /var/lib/tripwire/*.twd* ; tripwire -m i -s -c /etc/tripwire/tw.cfg  ※データベースを作り直す
Please enter your local passphrase:  ※ローカルパスフレーズを入力

まとめ

Tripwireを入れて、毎日自動でファイルの変更をチェックし、変更があったときだけメールで知らせるようにしました。SELinuxやファイアウォールを止めているぶん、こうした検知の仕組みで安全性を補っています。

次は、不正なプログラム(rootkit)を探すrkHunterを入れます。手順はrkHunterの記事で紹介しています。

コメント