こんにちは。植松です。

Webサイトの改ざんによって個人情報が不正に取得されるニュースをちらほら目にします。
弊社がイチから構築・運用しているサーバでは被害に遭ったことが無いのですが、もし被害に遭ったらと思うと恐ろしい。。

今回は改ざんが行われたことを検知するツール「AIDE」を導入し、検知ツールとしてどれくらい有用か調べてみました。

AIDEとは

AIDEとはオープンソースのホスト型(サーバインストール型)の監視ツールで、「ファイルとディレクトリが改ざんされたか」どうかを判定する監視ツールです。
常駐型でなくバッチ型なので、リアルタイムにファイルが改ざんされたことを検知することができません。cronで定期的に実施し結果をメールで受け取るなど一工夫必要。
主要なLinuxディストリビューションに標準パッケージとして含まれているので、手軽に導入が可能。
詳しくは公式サイトを参照。

動きとしては、まずチェック対象の構成等をデータベースに保存しておきます。
任意のタイミングでチェックコマンドを実行。保存してあるデータベースと現在の状態を比較しファイルやディレクトリの整合性をチェックしています。

導入手順

AmazonLinux2023に導入します。

インストール

# dnf install aide

設定

設定ファイルで、チェックするルールを設定します。

# vim /etc/aide.conf

設定ファイルの中身


# Example configuration file for AIDE.
@@define DBDIR /var/lib/aide
@@define LOGDIR /var/log/aide
# The location of the database to be read.
database_in=file:@@{DBDIR}/aide.db.gz
# The location of the database to be written.
#database_out=sql:host:port:database:login_name:passwd:table
#database_out=file:aide.db.new
database_out=file:@@{DBDIR}/aide.db.new.gz
# Whether to gzip the output to database
gzip_dbout=yes
# Default.
report_url=file:@@{LOGDIR}/aide.log
report_url=stdout
#report_url=stderr
#NOT IMPLEMENTED report_url=mailto:root@foo.com
#NOT IMPLEMENTED report_url=syslog:LOG_AUTH
# These are the default rules.
#
#p:      permissions
#i:      inode:
#n:      number of links
#u:      user
#g:      group
#s:      size
#b:      block count
#m:      mtime
#a:      atime
#c:      ctime
#S:      check for growing size
#acl:           Access Control Lists
#selinux        SELinux security context
#xattrs:        Extended file attributes
#md5:    md5 checksum
#sha1:   sha1 checksum
#sha256:        sha256 checksum
#sha512:        sha512 checksum
#rmd160: rmd160 checksum
#tiger:  tiger checksum
#haval:  haval checksum (MHASH only)
#gost:   gost checksum (MHASH only)
#crc32:  crc32 checksum (MHASH only)
#whirlpool:     whirlpool checksum (MHASH only)
FIPSR = p+i+n+u+g+s+m+c+acl+selinux+xattrs+sha256
#R:             p+i+n+u+g+s+m+c+acl+selinux+xattrs+md5
#L:             p+i+n+u+g+acl+selinux+xattrs
#E:             Empty group
#>:             Growing logfile p+u+g+i+n+S+acl+selinux+xattrs
# You can create custom rules like this.
# With MHASH...
# ALLXTRAHASHES = sha1+rmd160+sha256+sha512+whirlpool+tiger+haval+gost+crc32
ALLXTRAHASHES = sha1+rmd160+sha256+sha512+tiger
# Everything but access time (Ie. all changes)
EVERYTHING = R+ALLXTRAHASHES
# Sane, with multiple hashes
# NORMAL = R+rmd160+sha256+whirlpool
NORMAL = FIPSR+sha512
# For directories, don't bother doing hashes
DIR = p+i+n+u+g+acl+selinux+xattrs
# Access control only
PERMS = p+i+u+g+acl+selinux
# Logfile are special, in that they often change
LOG = >
# Just do sha256 and sha512 hashes
LSPP = FIPSR+sha512
# Some files get updated automatically, so the inode/ctime/mtime change
# but we want to know when the data inside them changes
DATAONLY =  p+n+u+g+s+acl+selinux+xattrs+sha256
# Next decide what directories/files you want in the database.
/var/www/html/ NORMAL

ざっと説明をします。

  • database_in:前回実行時記録されたデータベース
  • database_out:今回実行時記録されたデータベース
  • report_url:複数定義可能。今回は結果をログと標準出力に出力
  • FIPSR、ALLXTRAHASHES、EVERYTHING、NORMAL、DIR、PERMS、LOG、LSPP、DATAONLY:カスタムプロファイル
    それぞれを説明するの非常に長くなるので割愛。デフォルトルールを組み合わせて任意のルールを定義
  • /var/www/html/ NORMAL:監視対象とチェックルールを設定(行頭に「!」をつけるとチェック対象から除外)
    デフォルトだとかなりのディレクトリが設定されているので、監視対象は厳選したほうがいいです。後述しますが、監視対象が多いと処理に時間がかかります。

初期化

AIDEのデータベースファイルを作ります。

# aide --init

チェック対象が多いとここでえらい時間かかります。このコマンドを実行すると、database_outで定義したファイルが作られます。
次回実行時に備えてファイル名を変更します。

# mv -f /var/lib/aide/aide.db.new.gz /var/lib/aide/aide.db.gz

稼働確認

チェックコマンドは以下のどちらか

# aide --check
# aide -C

変更がない場合は以下が表示されます。

AIDE found NO differences between database and filesystem. Looks okay!!

FTPなどでファイルを変更して差分がある状態にし、再度チェックコマンドを実行。以下のように、変更があったファイルやディレクトリが記録されていました。


AIDE found differences between database and filesystem!!
---------------------------------------------------
Added entries:
---------------------------------------------------
f++++++++++++++++: /var/www/html/test/download/test.html
d++++++++++++++++: /var/www/html/test/testfolder
f++++++++++++++++: /var/www/html/test/testfolder/index.html
---------------------------------------------------
Removed entries:
---------------------------------------------------
f----------------: /var/www/html/test/privacy/index_test.html
---------------------------------------------------
Changed entries:
---------------------------------------------------
d = ... mc.n ... : /var/www/html/test
f > ... mc..H... : /var/www/html/test/.htaccess
d > ... mc.. ... : /var/www/html/test/download
d < ... mc.. ... : /var/www/html/test/privacy

※↑はログの中から一部抜粋しただけです。

定期実行

一連の作業を定期的に実行するスクリプトを作りました。


#!/bin/bash
CURRENT_DATE=$(date +"%Y%m%d_%H%M")
CURRENT_DATE_FOLDER=$(date +"%Y/%m/%d")
LOG_FILE="/var/log/aide/aide_$CURRENT_DATE.log"
S3_DESTINATION="s3://bucket/$CURRENT_DATE_FOLDER/"
SUBJECT="AIDE Alert: Filesystem Modification Detected"
MAIL_TO="root"
DATABASE_IN="/var/lib/aide/aide.db.gz"
DATABASE_OUT="/var/lib/aide/aide.db.new.gz"
aide --check > "$LOG_FILE"
if ! grep -q "Looks okay!" "$LOG_FILE"; then
    ADDED_COUNT=$(grep "Added entries" $LOG_FILE | awk -F':[[:space:]]*' '{print $2}')
    REMOVED_COUNT=$(grep "Removed entries" $LOG_FILE | awk -F':[[:space:]]*' '{print $2}')
    CHANGED_COUNT=$(grep "Changed entries" $LOG_FILE | awk -F':[[:space:]]*' '{print $2}')
    if [ "$ADDED_COUNT" -gt 10 ] || [ "$REMOVED_COUNT" -gt 10 ] || [ "$CHANGED_COUNT" -gt 10 ]; then
	    MODIFIED_ITEMS=$(grep -E "(added|changed|removed)" "$LOG_FILE")
	    MESSAGE="AIDE has detected filesystem changes.\n\nModified items:\n\n$MODIFIED_ITEMS\n\nCheck the full log for more details."
	    echo -e "$MESSAGE" | mail -s "$SUBJECT" -a "$LOG_FILE" "$MAIL_TO"
    fi
fi
aide --init
aws s3 cp "$LOG_FILE" "$S3_DESTINATION"
if [ $? -eq 0 ]; then
    rm -f "$LOG_FILE"
else
    echo -e "S3 upload failed. Local log retained: $LOG_FILE" | mail -s "$SUBJECT" -a "$LOG_FILE" "$MAIL_TO"
fi
mv -f $DATABASE_OUT $DATABASE_IN
exit 0

AIDEを定期実行してファイルシステム変更を検出し、大量変更時(追加・変更・削除のいずれかが10件を超える場合)のみアラートメールを送信。実行ログはS3に送信し、最後にAIDEのデータベースを更新して最新状態を記録しています。これをcronで定期実行するようにcrontabに設定し完了です。

最後に

改ざんにあった場合、なるべく早く検知する仕組みを作ってみました。どんなに対策を講じてもやられる時はやられてしまうので、攻撃は受ける前提で受けた後のことを考えておくことはインフラ管理の観点からは重要かと思います。
AIDEはリアルタイム検知ではないので、導入する際は定期実行が必須になります。検知対象やアラートを送る基準なども運用環境で変わってきますが、設定ファイル1つで調整できますし、簡単に導入できる点ではなかなか良いソフトだなという印象を持ちました。