OXY NOTES

rsyslogを利用したログファイル作成と、logrotateを利用したログのローテーション

セキュリティ対策の健康診断、適切なログの収集

iptableのパケットフィルタリングで侵入を予防することも大切ですが、攻撃の兆候を察知して対応するほうが安全性は高まります。

このページでは前回の投稿で設定したログファイルの接頭辞を利用してログファイルを切り分け、適切な期間ログファイルを保持する方法を解説します。


目次

rsyslogでiptableのログを振り分け
logrotateによるローテーションの仕組み
logrotateの基本設定とソフトごとの設定
iptablesのローテーションを設定する
rsyslogの再起動と、ローテーションの動作確認


rsyslogでiptableのログを振り分け

それではiptableで設定したログの接頭辞をフラグとしてログファイルの切り分けを行います。
rsyslogの設定方法について詳細は「前回の投稿」をご覧ください。

iptableで設定したログファイルの接頭辞は以下の3つでした。

Ping of Death攻撃用

"[IPTABLES PINGATTACK] : "

DNS Amp攻撃用

"[IPTABLES DNSAMP] : "

全ての条件に当てはまらない通信用

"[IPTABLES DROP INPUT] : "

この接頭辞をフラグにrsyslogの設定ファイル「/etc/rsyslog.conf」に「プロパティベースのフィルター」でフィルタリングします。
またログデータはそれぞれ「/var/log/」以下に書きだすものとします。

#### RULES ####

以降に、以下の設定を追記してください。

:msg, contains, "IPTABLES PINGATTACK"    -/var/log/iptables-ping-ataack.log
:msg, contains, "IPTABLES DNSAMP"       -/var/log/iptables-dnsamp.log
:msg, contains, "IPTABLES DROP INPUT"   -/var/log/iptables-input-drop.log

msg」でログメッセージを指定。
contains」で一致するパターンに、テキストの一部を指定。
“hoge”」この部分が一致するテキスト。
-/dir/」先頭に「ハイフン(-)」を付けることで非同期での書き込みを指定しています。こうすることでサーバへの負荷は劇的に下がります。反面、サーバが停止した直前のログを取り損ねる場合があリます。そのため、サーバの停止に関わるようなログを取得している場合は注意が必要です。

iptablesのログの例と見方

例えば「IPTABLES DROP INPUT」のログの場合は以下の様に出力されます。

Aug 17 15:52:40 example.com kernel: [IPTABLES DROP INPUT] : IN=eth0 OUT= MAC=00:16:3e:4a:04:85:f8:22:ea:d8:34:ff:08:00 SRC=69.171.247.113 DST=111.122.40.105 LEN=71 TOS=0x00 PREC=0x00 TTL=80 ID=4364 PROTO=UDP SPT=19436 DPT=53 LEN=51
Aug 17 15:52:40 日時
example.com ルータのホスト名
kernel: kernel からのメッセージであることを示す
[IPTABLES DROP INPUT] : –log-prefix で指定されたフラグ
IN=eth1 OUT= データがどちらのネットワークデバイスから入り, どちらから出るかを示す
SRC=69.171.247.113 データの送信元
DST=111.122.40.105 データの宛先
LEN=71 TOS=0x00 その他色々
PREC=0x00 TTL=80 ID=4364 その他色々
PROTO=UDP TCP or UDP or ICMP]
SPT=19436 送信元ポート
DPT=53 宛先ポート
LEN=51 その他色々

http://www.ep.sci.hokudai.ac.jp/~epdns/dvlop/dhcp/iplog.htmlより


logrotateによるローテーションの仕組み

このままだと際限なくログを収集するのでサーバが一杯になってしまします。そこで、logrotateを利用して、ログのローテーションを設定します。ローテーションとは、定められたファイルを利用してログを上書きしていくことです。

図を交えると理解がしやすいと思います。

1周間に1度、2つのファイルを使う場合の例

1週間目、まずは第1週のログを「ファイルlog」に出力

2週間目、まず第1週のログはファイル「log.1」へ改名されます。第2週のログは先週と同じようにファイル「log」へ出力。

3週間目、同じように新しいログを出力しますが、ファイル「log.1」に出力された第1週のログは破棄される。

このように同じファイルをローテーションして使うことで、ログを保存する期間を限定して、ログの肥大化を防ぐことができます。また、ログの閲覧性が向上するというメリットもあります。

ローテーションのことを世代管理と呼ぶこともあります。


logrotateの基本設定とソフトごとの設定

RedHat系OSではデフォルトでインストールされており、設定ファイルは「/etc/logrotate.conf」にインストールされています。
設定方法は単純で解りやすい構造になっています。

# see "man logrotate" for details
# rotate log files weekly
weekly

# keep 4 weeks worth of backlogs
rotate 4

# create new (empty) log files after rotating old ones
create

# uncomment this if you want your log files compressed
#compress

# RPM packages drop log rotation information into this directory
include /etc/logrotate.d

# no packages own wtmp -- we'll rotate them here
/var/log/wtmp {
    monthly
    minsize 1M
    create 0664 root utmp
    rotate 1
}

3行目weekly」は1週間で書き換え。毎日はdaily、毎月はmonthly
6行目rotate 4」は4世代のファイルを使用。つまりファイルの保存期間は1週間。4世代保存。つまり1ヵ月分のログを保存という設定になっています。
9行目create」はファイルが存在しない場合に新しいファイルを作成。
12行目#compress」は圧縮。コメントアウトされているので圧縮を有効にする場合はコメントアウトを削除してください。
15行目include /etc/logrotate.d」はソフトごとの設定ファイルの保存場所を指定します。つまり、この設定ファイルが全体の基本設定で、ソフトごとの設定は「/etc/logrotate.d」に作成する、ことになります。
18行目/var/log/wtmp{ … }」これは「/var/log/wtmp」に対する処理を個別に設定しています。

設定に利用できるコマンドは以下のとおりです。

compress ローテーションしたログをgzipで圧縮
copytruncate ログファイルをコピーし、内容を削除
create [パーミッション ユーザー名 グループ名] ローテーション後に空のログファイルを新規作成。ファイルのパーミッション、ユーザー名、グループ名を指定可能
daily ログを毎日ローテーションする
delaycompress ログの圧縮作業を次回のローテーション時まで遅らせる。compressと共に指定
ifempty ログファイルが空でもローテーションする
missingok ログファイルが存在しなくてもエラーを出さずに処理を続行
monthly ログを毎月ローテーションする
nocompress ローテーションしたログを圧縮しない
nocreate 新たな空のログファイルを作成しない
nomissingok ログファイルが存在しない場合にエラーを出す
noolddir ローテーション対象のログと同じディレクトリにローテーションしたログを格納
notifempty ログファイルが空ならローテーションしない
olddir [ディレクトリ名] 指定したディレクトリ内にローテーションしたログを格納
postrotate~endscript postrotateとendscriptの間に記述されたコマンドをログローテーション後に実行
prerotate~endscript postrotateとendscriptの間に記述されたコマンドをログローテーション前に実行
rotate 回数 ローテーションする回数を指定
size [ファイルサイズ] ログファイルが指定したファイルサイズ以上になったらローテーションする
sharedscripts 複数指定したログファイルに対し、postrotateまたはprerotateで記述したコマンドを実行
weekly ログを毎週ローテーションする

@ITからlogrotateの設定ファイルで指定できる主なコマンドより

個別の設定ファイルsyslogの場合

それでは個別の設定ファイルについても見ていきます。今回はsyslog用の設定を取り上げます。通常は「/etc/logrotate.d/syslog」にあります。

/var/log/messages /var/log/secure /var/log/maillog /var/log/spooler /var/log/boot.log /var/log/cron {
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
    endscript
}

/etc/logrotate.conf」と同じ構造です。1行目スペース区切り複数のログファイルが指定されています。
ローテーションなどの設定はされていないので、「/etc/logrotate.conf」の基本設定で動作していることがわかります。

2行目sharedscripts」は以下のスクリプトを一度だけ実行するという意味です。

3~5行目postrotate」から「endscript」の間に実行するスクリプトを記述します。

4行目は、ログファイルによくある特殊なスクリプトです。入り組んだ構造で分かりにくいスクリプトですが、せっかくなので詳しく解説します。

/bin/kill -HUP プロセスID」は設定ファイルの読み込みを意味します。なぜ設定を読み込み直すかというと、新しいローテート用のファイルに書き込むためです。ちなみにHUPシグナルreloadでも送られるので、rcスクリプトで定義されていればreloadでも構いません。

同じファイルをローテーションして使うんじゃないの?」と思うかもしれませんが、その辺の詳しい話はこちらのサイトで詳しく解説されています。

cat /var/run/syslogd.pid」でプロセスIDを取得しています。

続く「2>」は標準エラー出力を意味していて、後に続くファイルに標準エラーを出力するという意味になリます。

/dev/null」は空ファイルを意味しています。「空ファイルに書き出す=捨てる」という意味になります。
つまり「`」で囲まれた部分は「cat /var/run/syslogd.pid」の出力エラーを破棄するという意味になります。

さらに「2> /dev/null」と続くのは「/bin/kill -HUP プロセスID」に関するエラーを捨てるという設定です。

さらに続けて「|| true」となっているので、エラーの場合も処理を続行します。

要約すると「HUPシグナルでソフトを再読み込みするがエラが出力されても全て破棄。再読み込みの成否に関わらず、処理は続行。」という意味になります。

ファイルの有効期限について

ソフトごとの設定で注意しないといけないのが、ファイルの有効期限です。ソフトごとの設定ファイルで「day」と設定しても、基本設定である「/etc/logrotate.conf」で「weekly」となっていると1週間ごとにしかファイルは更新されません。

なぜかというと、logrotateの実行はcronで行っているからです。そのため「/etc/logrotate.conf」で「weekly」とすると、cronがlogrotateを1週間ごとに実行します。そのため、ソフトごとの設定ファイルの場所を示す「include /etc/logrotate.d」の行も1週間ごとに読み込まれます。
logrotateはソフトごとの設定にある「day」を「前回ログファイルを作成してから1日以上経っていたら実行」と評価します。

そのため「/etc/logrotate.conf」の実行間隔はローテーションしたい期間が最も短いログファイルに合わせる必要があります。


iptablesのローテーションを設定する

それではいよいよiptablesの設定ファイルを作成します。

/var/log/iptables-dnsamp.log /var/log/iptables-forward-drop.log /var/log/iptables-input-drop.log /var/log/iptables-ping-attack.log {
	weekly
	rotate 4
	create
	postrotate
		/etc/init.d/iptables reload > /dev/null 2> /dev/null || true
	endscript
}

それぞれのログファイルのパスをスペース区切りで指定して、HUPの代わりにreloadで再読み込みをしています。実行間隔は1週間、ローテーションは4回。つまり1ヵ月分のログを保存する設定になっています。


rsyslogの再起動と、ローテーションの動作確認

以上の設定が終わったら、rsyslogを再起動して設定を有効にします。

# service rsyslog restart

すると指定したディレクトリ(上の例では/var/log/以下)にログファイルが作成されているはずです。

また念の為に自動起動が有効になっているか調べておいてください。

rsyslogの自動起動を確認
# chkconfig --list rsyslog
以下のように3番がonになっていれば自動起動は有効です。
rsyslog           0:off   1:off   2:on    3:on    4:on    5:on    6:off

有効でない場合は以下のコマンドで有効にしておいてください。

# chkconfig rsyslog on

ローテートされているか確認

logrotateはcronで実行されるため、自動起動を設定する必要はありません。しかしcronで実行されるまで動作確認ができないと不便です。テストのために以下のコマンドを実行してください。

# /usr/sbin/logrotate /etc/logrotate.conf

そしてローテートされたステータスを表示します。このファイルには前回ログファイルが作成された日時とパスが記載されています。

# cat /var/lib/logrotate.status
…
"/var/log/iptables-input-drop.log" 2013-11-13
"/var/log/iptables-ping-death.log" 2013-11-13
"/var/log/iptables-ping-attack.log" 2013-11-13

iptablesのログファイルのパスと日時があると思います。
このままでも1週間後にファイルが更新されますが、日時を編集してローテーションさせることもできます。

viで直接ファイルを編集して、日時を10日程度巻き戻してください。11月13日なら11月3日に変更。

# vi /var/lib/logrotate.status
"/var/log/iptables-input-drop.log" 2013-11-3
"/var/log/iptables-ping-death.log" 2013-11-3
"/var/log/iptables-ping-attack.log" 2013-11-3

そして再びlogrotateを実行します。

# /usr/sbin/logrotate /etc/logrotate.conf

指定したディレクトリ「/var/log/」に「ログファイル名.1」というファイルが作成されていることを確認してください。


これでiptablesの設定とログファイルの書き出し。
さらにログファイルのローテンションの設定という一連の流れは終了です。