0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PHPを使ってXFFの値をアクセスログに出力する方法(Xserver編)

Last updated at Posted at 2024-09-16

概要

レンタルサーバー環境(Xserver等)では、Apacheのアクセスログフォーマットを自由に変更できない場合が多くあります。

クライアントのIPアドレスとしてX-Forwarded-For(XFF)の値を記録したい場合、標準ログの代わりにカスタムログを出力する必要があります。本記事では、PHPを使ってXFFの値を含むカスタムアクセスログを生成する方法を紹介します。

なぜXFFが重要なのか

WAFやCDNを利用している場合、サーバーが直接受け取るIPアドレス(REMOTE_ADDR)はプロキシやCDNのものになることが多く、実際のクライアントIPを取得できません。XFFヘッダーは、そのような環境でクライアントの実際のIPアドレスを取得するために使われます。

実装手順

1. logディレクトリの作成

ログファイルを保存するためのディレクトリを作成します。SSHやFTPを使用する方法もありますが、今回はXserverのコントロールパネルから「ファイルマネージャー」を使用します。

CleanShot 2024-09-16 at 17.21.11.png

  1. Xserverのコントロールパネルにログイン
  2. 「ファイル管理」 > 「ファイルマネージャー」を選択
  3. /home/サーバーID/サーバーID.xsrv.jp/ ディレクトリに移動(パスは環境ごとに異なります)
  4. log ディレクトリを新規作成

CleanShot 2024-09-16 at 17.19.44.png

2. PHPスクリプトを追加してカスタムログを生成

WordPressを使っている場合、現在使用しているテーマのfunctions.phpファイルを編集して、カスタムログを生成するコードを追加します。

CleanShot 2024-09-16 at 17.17.10.png

以下の手順では、/home/xs999999/xs999999.xsrv.jp/public_html/test/wp-content/themes/twentytwentyfour/functions.phpにコードを追加しています。

  1. コントロールパネルの「ファイルマネージャー」を開く
  2. /home/xs999999/xs999999.xsrv.jp/public_html/test/wp-content/themes/your-theme/functions.php へ移動
  3. functions.phpを選択して「編集」をクリック
  4. コードをfunctions.phpの先頭に追加
<?php
// WordPress初期化後、カスタムログを生成する
add_action('shutdown', 'custom_log_user_info', 9999); // shutdownフックで最後に実行

// カスタムログを生成し、ファイルに保存する
function custom_log_user_info() {
    // ログインユーザー名を取得(未ログインなら'-')
    $logname = is_user_logged_in() ? wp_get_current_user()->user_login : '-';

    // リモートアドレスとX-Forwarded-Forの最初のIPを取得
    $remote_addr = $_SERVER['REMOTE_ADDR'];
    $xff_ip = !empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0] : $remote_addr;

    // リクエストサイズ(存在しない場合は`-`)
    $request_size = isset($_SERVER['CONTENT_LENGTH']) ? $_SERVER['CONTENT_LENGTH'] : '-';

    // 日本時間に設定し、日時フォーマットを指定
    date_default_timezone_set('Asia/Tokyo');
    $time = '[' . date('d/M/Y:H:i:s O') . ']';

    // HTTPリクエスト情報、ステータスコード、ユーザーエージェント、リファラを取得
    $request = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] . ' ' . $_SERVER['REQUEST_URI'] . ' ' . $_SERVER['SERVER_PROTOCOL'] : '-';
    $status = http_response_code();
    $user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '-';
    $referer = isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '-';

    // ログエントリを作成(Refererヘッダーも含める)
    $log_entry = sprintf('"%s" %s - %s %s "%s" %s %s "%s" "%s"' . "\n", 
        $xff_ip, 
        $remote_addr, 
        $logname, 
        $time, 
        $request, 
        $status, 
        $request_size, 
        $referer,
        $user_agent
    );

    // ログファイルに書き込む
    $log_file = '/home/xs999999/xs999999.xsrv.jp/log/access_' . date('Ymd') . '.log';
    if ($fp = fopen($log_file, 'a')) {
        if (flock($fp, LOCK_EX)) {
            fwrite($fp, $log_entry);
            fflush($fp);
            flock($fp, LOCK_UN);
        }
        fclose($fp);
    }
}
?>

// 以下、既存コード

/home/xs999999/xs999999.xsrv.jp/log/ の箇所は実際の環境に合わせて変更してください

3. テーマのfunctions.php使用について

functions.phpは、WordPressテーマの中で追加のカスタム機能を定義するために使われるファイルです。wp-includes/functions.phpのようなコアファイルを直接編集すると、将来的なWordPressのアップデートで変更が上書きされるリスクがありますが、テーマのfunctions.phpを使用することで、このリスクを回避できます。

テーマを変更した場合、新しいテーマのfunctions.phpに同じカスタムコードを移す必要があります。テーマに依存しない方法としては、カスタムプラグインを作成することも一つの選択肢です。

4. コードの説明

このスクリプトでは、以下の情報を含むログを生成します。

項目 説明 Apache標準ログとの違い
X-Forwarded-For クライアントのIPアドレス X-Forwarded-最初の値を取得
REMOTE_ADDR 接続元IPアドレス 通常はWAFやCDNのIPアドレス
識別情報 常に「-」を出力 Apacheログフォーマットへの準拠用
認証ユーザー WordPressユーザー名 WordPressにログインしている場合のみ記録
タイムスタンプ アクセス時間 日本標準時間
リクエスト内容 HTTPメソッド、リクエストURI、プロトコル -
ステータス HTTPレスポンスのステータスコード -
転送量 リクエストのContent-Lengthヘッダー値 Apacheと計測が異なる
リファラー リクエスト元のページURL -
ユーザーエージェント クライアントのユーザーエージェント -

5. ログ出力例

実際にWebアクセスをすると指定したディレクトリにログファイルが出力されます。

CleanShot 2024-09-16 at 17.22.45.png

出力されるログの例は以下の通りです。

“203.0.113.5” 203.0.113.1 - user [29/Sep/2024:12:34:56 +0900] “GET /wp-admin/ HTTP/1.1” 200 12345 “https://example.com” “Mozilla/5.0 (Windows NT 10.0; Win64; x64)”

このように、クライアントIP(XFF)、プロキシIP(REMOTE_ADDR)、リクエスト情報など必要な情報が記録されます。

まとめ

Xserverなどのレンタルサーバーではアクセスログのフォーマットをカスタマイズできない場合がありますが、PHPを使って独自のログを生成することで、X-Forwarded-Forヘッダーの値を含む詳細なアクセスログを残すことができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?