2.サービス毎のログ解析のテクニック

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日時
\"ダブルクォーテーション
%rHTTPリクエストの最初の行
%>sHTTPステータスコード
%bヘッダを除く送信バイト数
%{foo}iHTTPヘッダ内の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はコアに含まれる)
LogFormatlog_format ディレクティブ
CustomLogaccess_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}iUser-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より利用できる。

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タプル単位)
dnsDNSリクエスト/レスポンスの詳細ログ
http/http2HTTPトラフィックの詳細(User-Agent, URL, メソッド等)
tlsTLS証明書情報、SNI、バージョン、暗号スイートなど
fileinfo通過するファイルの情報(ハッシュ・ファイルタイプなど)
statsSuricataの状態情報(パケット数、ドロップ率など)

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)への「拒否」ログが発生した場合に検知
  • DoS/SlowDoS攻撃の検知
    • DoS検知ルール例
      • 例: 5秒間にある宛先サーバに対する「許可」ログが5000回以上発生した場合に検知
    • SlowDoS検知ルール例
      • 例: ある送信元IPアドレスからセッション開始の「許可」ログを受信して20秒以上経過してもセッション終了の「許可」ログを受信しない。こういったセッションが同時に30を超える際に検知

なお実装にはファイヤーウォールにログからの蓄積・相関・統計的な異常検知ロジックがない場合は、ログをいったんSyslogサーバに保管し、別途SIEM(Wazuh, ELKStack, Graylog, Splunk等)を用いて解析/検知する必要がある。

2.1.5. システムログのログ解析

Linuxシステムのシステムコール

システムコールはOS上で動作するアプリケーションがOSの機能を呼び出すために利用する機能で、Linuxには約320種類のシステムコールがある。

代表的なシステムコールは以下の通り。

システムコール用途
open,read,writeファイルの読み書きに使用
rename,chmod,chownファイルの名前/権限/所有者などを変更する際に使用
connect,accept,sendto, recvfromネットワーク通信で接続先に対しセッション形成/データ送受信に利用
execveOSコマンドを実行する際に使用

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すべての監視ルールの消去
-bLinux Auditが利用できるカーネル内のバッファサイズを指定
-a list,actionlistに対して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イベントの種類を示す
msgtimesttamp:unique_idで記載
syscallシステムコール番号
successシステムコールが成功したかどうか
exitシステムコールの戻り値
a0.a1,a2,a3システムコールが受け取る最初の4つの引数(16進数)
ppid, pid親プロセスID,プロセスID
uid, gidユーザID,グループID
exe実行プログラムのフルパス
subj, objSELinuxで利用するラベル情報

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. 仮想パッチによる防衛のポイント

仮想パッチのメリットはサービス停止せずに良いこと、正常オペレーションに対する影響が少ないことがある。

一方で安定した仮想パッチの作成には脆弱性に対する理解/対策実装スキルが必要になる。これは脆弱性のあるアプリケーションの動作に精通していることが必要といえる。