Cloudflare を使用しているとアクセス元の IP は CF-Connecting-IP(HTTP_CF_CONNECTING_IP
ヘッダー)に設定されます。他にも x-real-ip などがありますがこれらは書き換えができないことになっています。
Xserver(またはシンレンタルサーバー)の機能としてログ出力がありますがこちらには Cloudflare の IP アドレスが記録されるためアクセス元の特定ができません。(色々試してみたところこれ Apache のログじゃなくて Nginx のログっぽい気がする。RequestHeader
で弄っても変化がない)
FPM では access.log
や access.format
という設定項目がありますが Xserver や新レンタルサーバー は FastCGI なようなので php.ini
や .user.ini
に設定しても効果が無いようです。
そこで PHP スクリプトの方でログを出力するようにします。下記のような感じで functions.php
などに追記します(先頭の <?php
は不要な場合もあります)。lltsv
でパースできるように書式は LTSV 形式にしています。
<?php function writeLog(){ $log = "/home/アカウント/ドメイン/log/php_access.log"; $time = (new DateTime('Asia/Tokyo'))->format(DateTimeInterface::RFC3339_EXTENDED); $country = getenv('HTTP_CF_IPCOUNTRY'); $host = getenv('HTTP_CF_CONNECTING_IP'); $real_ip = getenv('HTTP_X_REAL_IP'); $forwardedfor = getenv('HTTP_X_FORWARDED_FOR'); $forwardedproto = getenv('HTTP_X_FORWARDED_PROTO'); $method = getenv('REQUEST_METHOD'); $uri = getenv('REQUEST_URI'); $query = getenv('QUERY_STRING') ?: '-'; $referer = getenv('HTTP_REFERER') ?: '-'; $ua = getenv('HTTP_USER_AGENT') ?: '-'; $vhost = getenv('HTTP_HOST'); $path = urldecode(parse_url($uri, PHP_URL_PATH)); $query = urldecode($query); $referer = urldecode($referer); $row = implode("\t", array( "time:$time", "country:$country", "host:$host", "real_ip:$real_ip", "method:$method", "path:$path", "query:$query", "referer:$referer", "ua:$ua", "vhost:$vhost", )); file_put_contents($log, $row . PHP_EOL, FILE_APPEND | LOCK_EX); } writeLog();
これでタブ区切りで情報を得ることができるので lltsv
を使ってフィルタリングなどができるようになります。
time:2024-06-25T08:52:21.483+09:00 country:US host:66.249.79.7 real_ip:162.158.42.64 method:GET path:/ query:- referer:- ua:Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html) vhost:hobby.mattintosh-note.jp
画像等の index.php
を経由しないアクセスについては記録できませんがリモートの IP がまったくわからないよりはマシだと思います。
LTSV や lltsv
に関しては下記を参照してください。
追記
Transform Rules で UA に IP アドレスを含めることが出来ました。