2.サービス毎のログ解析のテクニック
2.1. 各種サービスのログ解析
2.1.1. Webサーバのログ解析
Apacheのログ設定
Apacheのhttpdの設定は大きく以下の2つで設定を行う。
- ログを取るためのモジュールをロードする
- httpd.confによるログそのものの設定
ログを取るためのモジュールはDSOが有効になった状態デコンパイルされているケースがほとんどである。 そのためhttpd.confで以下のようなモジュールが有効になっているか確認を行う。
LoadModule Log_config_module modules/mod_log_config.so
- 標準のアクセスログのカスタムフォーマット設定
LoadModule Log_config_module modules/mod_log_debug.so
- 詳細なデバックログの記録
LoadModule Log_config_module modules/mod_log_forensic.so
- フォレンジックログ(詳細なリクエスト情報の記録)
LoadModule Log_config_module modules/mod_logio.so
- 入出力バイト数のログ記録
LoadModule Log_config_module modules/mod_unique_id.so
- リクエストごとにユニークIDを付与
基本的にはmod_log_config
が有効になっていれば最低限問題ない。
ログの設定はhttpd.confの<IfModule log_config_module>~</IfModule>
内で原則記載される。
もしVirtualHost等を利用する場合は上記とは限らないので注意すること。
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "/var/loghttpd-access.log" combined
</IfModule>
書式 | 意味 |
---|---|
%h | リモートホスト名/IPアドレス |
%l | リモートログ名 |
%u | リモートユーザ名 |
%t | 日時 |
\" | ダブルクォーテーション |
%r | HTTPリクエストの最初の行 |
%>s | HTTPステータスコード |
%b | ヘッダを除く送信バイト数 |
%{foo}i | HTTPヘッダ内のfooの内容 |
Ngtinxのログ設定
nginxではApacheのようなモジュールをロードする記述は不要。 ログ機能(アクセスログ、エラーログ)はnginxのコア機能として常に組み込まれており、個別のモジュールロードは不要となっている。
nginxでは、以下のようにhttpブロック内でログフォーマットを定義し、それを各serverブロックまたはlocationにてaccess_logとして利用する。
http {
##
# ログフォーマット定義
##
log_format combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
log_format common '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent';
##
# アクセスログ出力設定(http全体、またはserver内で個別に指定可)
##
access_log /var/log/nginx/access.log combined;
# 以下、通常の設定(例)
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example-access.log combined;
error_log /var/log/nginx/example-error.log warn;
location / {
root /var/www/html;
index index.html;
}
}
}
Apache設定 | nginxでの対応 |
---|---|
LoadModule mod_log_config | 不要(nginxはコアに含まれる) |
LogFormat | log_format ディレクティブ |
CustomLog | access_log ディレクティブ |
<IfModule log_config_module> | 不要(常に有効) |
mod_log_debug, mod_logio等 | nginxでは個別に未実装だが一部は代替手段あり |
mod_unique_id | $request_idで代替可(http {}内で設定要) |
分析に必要なログの項目
Webサーバの場合出力すべきログの項目は以下の通り。
項目 | Apacheの場合 | 詳細 |
---|---|---|
日時(いつ) | %t | 必須(タイムゾーンに注意すること) |
ユーザID(誰が) | なし | Webアプリの場合は別途紐づけログを作成することを推奨 |
ソースIPアドレス(どこから) | %h | 必須(なおプロキシ(踏み台)やVPNサーバの可能性もあり) |
User-Agent(何を用いて) | %{User-Agent}i | User-Agentの制御でクローラのアクセスをブロックなども可能 |
リクエストURI(何をして) | %r | 必須 |
処理結果(どうなったか) | %b(送信容量のみ) | 任意 |
他にも利用者の導線をトレースできるReferer、Webアプリなどで利用者の特定に使用されるセッションIDによる関連リクエストのトレースなどもある。
Apacheでは%{sessionid}C
の指定でCookieに含まれるSessionIDを指定/記録できる。また、サーバから払い出されるSessionIDは%{set-Cookie}o
により記録できる。
mod_dumpioによる記録
Apacheではmod_dumpio.soを使用するとhttpdに対する入出力の片方、両方をerror_logに保存できる。つまりすべてのHTTP文がログに出力させることができる。
これはPOSTされたデータのログ分析で有用といえる。 ただしログの量が膨大になるため注意が必要。
Webサーバのログ形式
common形式とcombined形式はApache,Nginxで使われ、W3C形式はIISで使用される。
- Common Log Format(共通ログ形式)
- 概要: 最も基本的なログ形式で、ApacheやNginxなど多くのWebサーバで標準的に使われる
- 保存内容: クライアントIPアドレス、ユーザー識別子(通常はハイフン)、認証ユーザー名(通常はハイフン)、アクセス日時、リクエスト行(メソッド・URL・プロトコル)、HTTPステータスコード、レスポンスのバイト数
- 特徴: シンプルで必要最低限のアクセス情報を記録する形式
- Combined Log Format(複合ログ形式)
- 概要: Common Log Formatにさらに2つのフィールドを追加した拡張形式
- 追加される項目:
- Referer(リクエスト元のURL)
- User-Agent(クライアントのブラウザやOS情報)
- 特徴: ユーザーの行動解析やアクセス元の追跡、利用環境の把握に役立つ情報が含まれる
- W3C Extended Log Format(W3C拡張ログ形式)
- 概要: 主にMicrosoft IISで使われるカスタマイズ可能なログ形式
- 特徴: ログに含めるフィールドを自由に設定できるため、必要な情報だけを記録してログサイズを調整可能。フィールドはスペース区切りで、UTC(GMT)時間で記録される。
2.1.2. プロキシのログ解析
プロキシによるフィルタリング
プロキシサーバのフィルタリング機能はURLフィルタリング/ブラックリスト、カテゴリ単位のフィルタリングでフィルタを実施することができる。
ブラックリストに関しては以下URLより利用できる。
- Shalla’s BlackList
- Malware Domain List
- Malc0de
- DNS-BH Malware Domain Blacklist
HTTPS通信とURLフィルタリング
HTTPS通信ではプロキシサーバはURLのパスに関する情報を得ることができず、URLのパスを指定したフィルタはプロキシサーバでは適用できない。
もしパスによるフィルタリングをしたい場合はプロキシサーバ側で一度SSL/TLS通信を復号する必要があり、クライアント-プロキシサーバ間、プロキシサーバ間-接続先サーバ間で別々のSSL/TLSセッションが確立することになる。
この実装を行う場合はクライアント側にプロキシサーバ管理者が用意したCA証明書をインストールする必要がある。
Squidのログ形式
Squidはデフォルトの方法でインストールした場合、/var/log/squid3/access.log
にアクセスログが保存される。形式は以下のようになる。
146578901.643 39 192.168.0.101 TCP_MISS/200 644 GET http://www.example.com/index.html - DDIRECT/192.168.0.254 text/html
記載される情報は以下の通り。
- アクセス日時
- 応答時間
- 送信元IPアドレス
- ステータスコード
- 合計サイズ
- HTTPメソッド
- URL
- ユーザ名
- 送信先IPアドレス
- コンテンツタイプ
Squidのログ形式の変更
SquidのログもApacheなどと同様にsquid,common,combinedなどいくつかの形式がデフォルトで定義されており、柔軟に変更が可能となっている。/etc/squid3/squid.conf
における最大のログ形式combinedの設定は以下の通り。
#logformat combined %>a %ui %un [%tl] "%rm %ru HTTP/%rv" %>Hs %<st "%{Referer}>h" "%{User-Agent}>h" %Ss:%Sh
上記では以下内容を記録する。
- 送信先IPアドレス
- ident認証によるユーザ名
- すべての利用可能なユーザ名
- アクセス日時
- リクエストメソッド
- リクエストURL
- バージョン
- ステータスコード
- レスポンスサイズ
- Referer情報
- User-Agent
- Squidリクエストステータス
- Squid階層情報
注目すべきプロキシのログ項目
プロキシのHTTPヘッダの注目すべき箇所は以下の通り。
- Referer
- どのサイトを経由してアクセスしたか記録される
- User-Agent
- どのようなプログラムからアクセスしたか記録される
- Status-Code
- Webサーバのアクセスの際の応答が記録される
- Content-Type
- WebサーバからDLされたファイルの種類が記録される
- User
- Proxy認証が実装されている場合Webサイトにアクセスしたユーザ名が記載される
- Byte
- 送受信したデータ量が記載される
2.1.3. IPS/IDSのログ解析
IPS/IDSの検知の仕組み
IPS/IDSは多くの場合はシグネチャと呼ばれる攻撃パターンの記載リストに基づいて検知を行う。 検知制度はシグネチャの精度に大きく影響される。 シグネチャ型に対してアノマリ型のIDS/IPSも存在する。
シグネチャに関して評判がいいのはET Pro RullSetが評判が良い。有料版/無料版両方提供されている。
なお本稿ではOSSのソフトウェア型IDS/IPSのSnort/Suricataを取り扱う。
Snortのログ形式
Snortの検知ログにはfullとfastの2つのモードが存在する。 fullモードの方がfastモードより記載される情報量は多い。
fastモードで記載される情報は以下の通り。
- 検知時刻
- 検知名
- プロトコル名
- 送信元/送信先IPアドレス
- ポート番号
Snortのログサンプル(fastモード)は以下の通り。
[**] [1:2001219:7] ET POLICY Dropbox Client Broadcasting [**]
[Priority: 1]
06/28-17:45:12.345678 192.168.1.10:56789 -> 162.125.34.129:443
TCP TTL:64 TOS:0x0 ID:39505 IpLen:20 DgmLen:52
***A**** Seq: 0x9AE23E19 Ack: 0xE72390FD Win: 0x16D0 TcpLen: 32
Snortのログ形式の変更
Snortではcsv形式でのログ出力、DBへのログ出力に対応している。 例えばsnort.confに以下記述をすることでcsvで出力可能
output alert_CSV:alert.csv default
またSnortでは検知したログに対しパケットを付随して取得する機能がある。 ただし、データサイズがログの100倍程度になることが多いので注意して運用すること。
Suricataのログ形式
SuricataではSnortとは異なり、ログ出力形式がJSONベースで統一されており、モダンなSIEM連携に非常に適している。 特に「EVE JSON」形式がデフォルトの出力フォーマットとして採用されており、以下のような情報が記録される。
ログタイプ | 説明 |
---|---|
alert | シグネチャにマッチした検知ログ。Snortのfast/fullログに相当。 |
flow | 通信フロー単位の記録(5タプル単位) |
dns | DNSリクエスト/レスポンスの詳細ログ |
http/http2 | HTTPトラフィックの詳細(User-Agent, URL, メソッド等) |
tls | TLS証明書情報、SNI、バージョン、暗号スイートなど |
fileinfo | 通過するファイルの情報(ハッシュ・ファイルタイプなど) |
stats | Suricataの状態情報(パケット数、ドロップ率など) |
Suricataの検知ログ例は以下の通り。
{
"timestamp": "2025-06-28T09:32:15.256+0900",
"event_type": "alert",
"src_ip": "192.168.1.10",
"src_port": 54321,
"dest_ip": "93.184.216.34",
"dest_port": 80,
"proto": "TCP",
"alert": {
"signature": "ET MALWARE Suspicious User-Agent",
"category": "A Network Trojan was detected",
"severity": 2
}
}
Suricataのログ設定の変更
Suricataのログ出力は主に/etc/suricata/suricata.yaml
にて管理されている。
EVE JSONログを有効化して、ファイルに出力する設定は以下の通り。
outputs:
- eve-log:
enabled: yes
filetype: regular
filename: /var/log/suricata/eve.json
types:
- alert
- http
- dns
- tls
- flow
- fileinfo
Suricataのパケットキャプチャ機能
Suricataでは検知ログだけでなく、対象となったパケットの生データ(PCAP)も同時に取得する機能がある。
pcap:
enabled: yes
filename: /var/log/suricata/pcap_output.pcap
ただし、PCAPはログに比べて非常にサイズが大きくなるため、特に常時運用する場合はディスク容量に注意が必要となる。
2.2. ファイヤーウォールのログ解析
ファイヤーウォールのログ
ファイヤーウォール(FW)は内部ネットワークと外部ネットワークの境界に置くゲートウェイのこと。
ネットワーク装置としてはSOHO環境では市販のAPを兼ねた統合サービスルータが、エンタープライズ環境では専用のアプライアンス(Cisco ASA, Palo Alto, Fortigate等)で実装することが多い。 なおサーバ側のFW実装としてはLinuxの場合はiptables,ipfw,ufw, Windowsの場合はWindowsファイヤーウォールが該当する。
ファイヤーウォールのログ形式
ファイヤーウォールでは以下のようなログを得られる。
項目 | 値例 |
---|---|
アクション | Permit,Deny |
プロトコル | TCP,UDP |
宛先IPアドレス | 192.168.X.X/24 |
送信先IPアドレス | 192.168.X.X/24 |
宛先ポート | 80 |
送信元ポート番号 | XXXXX |
送信バイト数 | 100 |
受信バイト数 | 1000 |
通信時間 | 30 |
ネットワーク装置のファイヤーウォールのログはsyslogによりログ収集サーバに送ることが多い。 運用上、ファイヤーウォールからすべてのパケットのログを送信すると、ファイヤーウォールの負荷が増大するため、拒否(deny)したパケット/特定のポリシーにヒットしたパケットのログ情報のみを記録することが一般的。
ファイヤーウォールのログ解析例
ファイヤーウォールのログを活用すると以下内容を検知できる。
- 不審なアプリケーションの検知
- FW側でネットワークスキャンを行っている端末を検知する例
- ホストスキャン検知ルール例: 1分間に1つの送信元IPアドレスから1つの宛先ポートを用いて30以上の宛先IPアドレスに対して「拒否」ログが発生した場合に検知
- ポートスキャン検知ルール例: 1分間に1つの送信元IPアドレスから1つの宛先IPアドレスに対して100以上の宛先ポートへの「拒否」ログが発生した場合に検知
- 外部サービスの利用検知する例
- 例1: 1時間に異なる5種類以上の外部DNSサーバ(53)への「拒否」ログが発生した場合に検知
- 例2: 1時間に異なる2種類以上のSMTPサーバ(25)への「拒否」ログが発生した場合に検知
- 例3: 1時間に異なる2種類以上のIRCサーバ(6667)への「拒否」ログが発生した場合に検知
- FW側でネットワークスキャンを行っている端末を検知する例
- DoS/SlowDoS攻撃の検知
- DoS検知ルール例
- 例: 5秒間にある宛先サーバに対する「許可」ログが5000回以上発生した場合に検知
- SlowDoS検知ルール例
- 例: ある送信元IPアドレスからセッション開始の「許可」ログを受信して20秒以上経過してもセッション終了の「許可」ログを受信しない。こういったセッションが同時に30を超える際に検知
- DoS検知ルール例
なお実装にはファイヤーウォールにログからの蓄積・相関・統計的な異常検知ロジックがない場合は、ログをいったんSyslogサーバに保管し、別途SIEM(Wazuh, ELKStack, Graylog, Splunk等)を用いて解析/検知する必要がある。
2.1.5. システムログのログ解析
Linuxシステムのシステムコール
システムコールはOS上で動作するアプリケーションがOSの機能を呼び出すために利用する機能で、Linuxには約320種類のシステムコールがある。
代表的なシステムコールは以下の通り。
システムコール | 用途 |
---|---|
open,read,write | ファイルの読み書きに使用 |
rename,chmod,chown | ファイルの名前/権限/所有者などを変更する際に使用 |
connect,accept,sendto, recvfrom | ネットワーク通信で接続先に対しセッション形成/データ送受信に利用 |
execve | OSコマンドを実行する際に使用 |
Linuxのシステムコールを記録しログとして残す場合、Linux Auditと呼ばれる機能を利用する。
Linux Audit
Linux AuditはLinuxカーネルに対して発行されるシステムコールなどのOSで発生するイベントを監視する仕組みのこと。 Linux Auditは複数の仕組みから構成されており、メイン部分がシステムコールをフックして情報取得するauditd、auditdが取得した情報を他アプリやネットワーク越し転送する場合に使われるaudispd、監査ログから必要な情報のみを表示させる機能のausearch、指定した監査ログの統計情報を表示するaureport、auditdに対してどのようなシステムコールをフックするかを定めるauditctlなどから構成される。
Linux Auditの設定
RedHat系ではsudo yum install audit
でDLできる。
設定すべきファールは以下の2つ。
- auditd自身:
/etc/audit/audit.conf
- どのシステムコールを監視するか設定:
/etc/audit/audit.rules
audit.confは以下パラメータで構成される。
項目 | 説明 |
---|---|
log_file | 監査ログの出力先 |
log_format | 監査ログの形式 |
flush | 監査ログをディスクに書き込む際の方法 |
freq | 監査ログをディスクに書き込む頻度 |
max_log_file | 監査ログのサイズの最大値 |
max_log_file_action | 監査ログのサイズが最大に達した際の動作 |
space_left | 最小のディスクサイズ |
space_left_action | ディスクが足りないときの動作 |
またaudit.rulesのオプションは以下の通り。
オプション | 説明 |
---|---|
-D | すべての監視ルールの消去 |
-b | Linux Auditが利用できるカーネル内のバッファサイズを指定 |
-a list,action | listに対してactionを行うルールを新たに追加する |
-S | 監査ログを出力するシステムコールを指定 |
-F | 監査ログを出力する条件を設定 |
-k | 作成するルールにその監視ルールを一意に識別できる名前を指定 |
-w | 監視するファイルを指定 |
-p [w,r,x,a] | ファイル操作の各場合の監査ログの取得を指定 |
Linux Auditに含まれるその他のツール
- ausearch
- 検索条件に合う監査ログを出力する
- aureport
- 監査ログの統計情報を出力する
- aulast
- 監査ログに基づいてlastコマンドのように各ユーザのログイン履歴を出力
- ausyscall
- システムコール番号とその名前の対応付けを調べる
Linux Auditの監査ログの見方
Linux Auditのログはkey=valueのフォーマットになっており、以下のようなkeyがある。
key | 説明 |
---|---|
type | イベントの種類を示す |
msg | timesttamp:unique_idで記載 |
syscall | システムコール番号 |
success | システムコールが成功したかどうか |
exit | システムコールの戻り値 |
a0.a1,a2,a3 | システムコールが受け取る最初の4つの引数(16進数) |
ppid, pid | 親プロセスID,プロセスID |
uid, gid | ユーザID,グループID |
exe | 実行プログラムのフルパス |
subj, obj | SELinuxで利用するラベル情報 |
2.1.6. 関数トレースログのログ解析
SystemTap
SystemTapはカーネル/ユーザ空間内で関数やシステムコールをフックするためのフレームワーク。 Linux Auditと同様のシステムコールログの取得のほかにアプリケーションの関数レベルのログ取得も可能となっている。
SystemTapの設定
RedHat系ではsudo yum install systemtap
で本体を、sudo yum install kernel-level kernel-debuginfo kernel-debuginfo-common
でSystemTapがフックで使うデバック情報を出力するパッケージをDLできる。
なおパッケージは動作しているカーネルのバージョンに正しく合わせる必要がある。
uname -r
などで確認しあったものをインストールすることが重要。
SystemTapはstpスクリプトと呼ばれる「どの関数/システムコールをフックし、フックした際の動作を記載したもの」を用意する必要がある。
2.2. 脆弱性発見から修正パッチ配布までの暫定対応
2.2.1. 仮想パッチによる防衛
仮想パッチ
仮想パッチは脆弱性が発見されてから修正パッチが配布されるまでの暫定対応を行う方法のこと。 仮想パッチの適用方法はネットワークの通信を書き換える方法、実行時のプログラムを書き換える方法が存在する。
SystemTapには動作中のプログラムの挙動を書き換える機能が搭載しているため、仮想パッチを適用することができる。
2.2.2. 各脆弱性に対する仮想パッチ適用例
ImageMagickの脆弱性に対する仮想パッチ
ImageMagickは画像を操作したり表示したりするための画像処理ライブラリ。 脆弱性(CVE-2016-3714~CVE-2016-3718等)が多いことで知られている。
ImageMagickの脆弱性は入力データの処理を行う前に入力値の検証が適切に行われていないため、任意のコマンドの実行や任意のファイルへのアクセスが実行されることがある。
ImageMagickを利用した攻撃では多くの場合uname
コマンドが初期段階で利用される。そのためuname
コマンドの実行を制御できれば脆弱性の悪用を軽減させれることが見込まれる。
unameコマンドを制限するSystemTepのstpスクリプト例は以下の通り。
probe kernel.function("sys_execve"){
if (uid() == 48 ){
cmd = kernel_string2($name, "");
if (strlen(cmd) > 0){
println("* execute command ", cmd)
if (isinstr(cmd, "/bin/uname")){
println("* /bin/uname command execution found. prevent execution ")
$name = 0;
}
}
}
}
上記をstap [ファイル名].stp
でそのまま実行しても、SystemTapの安全機能により、動作中のカーネル/プログラムのメモリ参照値を変化させないようになっている。
これは意図しない操作による値変化/カーネルクラッシュ/データ破損を阻止するためである。
仮想パッチは考え方として安全機能は不要であるため-g
オプションにより安全機能を外して適用させる。
stap -g [ファイル名].stp
OpenSSLのHeartBeartの脆弱性に対する仮想パッチ
OpenSSLはOSSの暗号化ライブラリ。 HeartBeat脆弱性(CVE-2014-0160)は入力値を検証しないためOpenSSLの使用しているプロセスメモリが漏洩するというもの。 この脆弱性を悪用するとサーバの秘密鍵、他サイト利用者のCookie/パスワードを盗み出せてしまう。
なお、OpenSSLのHeartBeatの機能はSSL/TLSセッションがアクティブなのかどうかを監視するための機能である。
この脆弱性の修正方針としては不正なHeartBeatリクエストを検知した場合メモリコピーのコピー先変数の値をクリアしてしまうことで回避が見込める。
上記動作の実装のSystemTepのstpスクリプト例は以下の通り。
probe process("/usr/lib64/libssl.so.10").statement("*@/usr/src/debug/openssl-1.0.1e/ssl/t1_lib.c:2514"){
req_size = 1+2+16+$s->s3->rrec->length;
if( 1+2+$payload+16 > req_size ){
$bp = 0;
println("* HeartBleed vulerability attack ditected");
println("* clear output buffer");
}
}
2.2.3. 仮想パッチによる防衛のポイント
仮想パッチのメリットはサービス停止せずに良いこと、正常オペレーションに対する影響が少ないことがある。
一方で安定した仮想パッチの作成には脆弱性に対する理解/対策実装スキルが必要になる。これは脆弱性のあるアプリケーションの動作に精通していることが必要といえる。