【Cloudflare】 Tunnel経由のApacheで、アクセスログを生IPアドレスに書き換える方法(mod_remoteip)

apache

 Cloudflare Tunnel(cloudflared)を利用して自宅サーバーを公開すると、セキュリティやIP固定化の面で非常に便利です。
 しかし、そのままの設定では、Webサーバー(Apache)が受け取るアクセスIPがすべてローカルホスト(127.0.0.1::1)またはCloudflareのIPになってしまい、誰がアクセスしてきたのか分からなくなってしまいます。

 この記事では、AlmaLinux環境のApacheに mod_remoteip を導入し、ログを「接続元の本来の生IPアドレス」に書き換える一連の手順を解説します。

1. ログに生IPが表示されない理由

通常、Cloudflare Tunnelを経由した通信は以下の経路をたどります。

[ユーザーの生IP][Cloudflareエッジ][cloudflared (127.0.0.1)][Apache]

Apacheから見ると、リクエストはすべて目の前にある cloudflared(ローカルホスト)から届くため、ログには 127.0.0.1 やCloudflareのプロキシIPしか記録されません。 これを解決するために、Cloudflareがリクエストヘッダーに付与してくれる CF-Connecting-IP(ユーザーの真のIP)をApache側で読み替える設定を行います。

2. Apacheのログフォーマット(LogFormat)の変更

まずは、Apacheがログを出力する際に「書き換えられたIPアドレス」を参照するように設定を変更します。

ファイル内の <IfModule log_config_module> ブロックを探し、ログフォーマットの先頭にある %h(リモートホスト)%a(クライアントのIPアドレス) に書き換えます。

特に combinedio は見落としがちなので、すべて %a に統一するのがポイントです。

[root@almalinux ~]# /etc/httpd/conf/httpd.conf

<IfModule log_config_module>
    # %h を %a に変更
    LogFormat "%a %l %u %t \"%!414r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    LogFormat "%a %l %u %t \"%r\" %>s %b" common

    <IfModule logio_module>
      # combinedio も同様に %h から %a に変更
      LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
    </IfModule>
</IfModule>

3. mod_remoteip の設定ファイル作成

次に、Cloudflareからのヘッダーを信頼するための設定ファイルを作成します。今回は管理しやすいように別ファイルとして新規作成します。

[root@almalinux ~]# /etc/httpd/conf.d/cloudflare.conf

# mod_remoteipモジュールが有効であることを確認
<IfModule mod_remoteip.c>
    # Cloudflareから渡されるヘッダーを指定
    RemoteIPHeader CF-Connecting-IP

    # cloudflared(ローカルホスト)からのプロキシを信頼する
    RemoteIPInternalProxy 127.0.0.1 ::1

    # Cloudflare自体のエッジサーバーIP帯(IPv4 / IPv6)も信頼する
    RemoteIPTrustedProxy 103.21.244.0/22
    RemoteIPTrustedProxy 103.22.200.0/22
    RemoteIPTrustedProxy 103.31.4.0/22
    RemoteIPTrustedProxy 141.101.64.0/18
    RemoteIPTrustedProxy 108.162.192.0/18
    RemoteIPTrustedProxy 190.93.240.0/20
    RemoteIPTrustedProxy 188.114.96.0/20
    RemoteIPTrustedProxy 197.234.240.0/22
    RemoteIPTrustedProxy 198.41.128.0/17
    RemoteIPTrustedProxy 162.158.0.0/15
    RemoteIPTrustedProxy 104.16.0.0/13
    RemoteIPTrustedProxy 104.24.0.0/14
    RemoteIPTrustedProxy 172.64.0.0/13
    RemoteIPTrustedProxy 131.0.72.0/22

    RemoteIPTrustedProxy 2400:cb00::/32
    RemoteIPTrustedProxy 2606:4700::/32
    RemoteIPTrustedProxy 2803:f800::/32
    RemoteIPTrustedProxy 2405:b500::/32
    RemoteIPTrustedProxy 2405:8100::/32
    RemoteIPTrustedProxy 2a06:98c0::/29
    RemoteIPTrustedProxy 2c0f:f248::/32
</IfModule>

💡 ここがハマりポイント!

 RemoteIPInternalProxy 127.0.0.1 ::1 だけでなく、CloudflareのグローバルIP帯(RemoteIPTrustedProxy)も同時に登録する必要があります。
 mod_remoteip は「直前のプロキシ」と「ヘッダーを付与した大元のプロキシ」の両方を検証するため、この両方を信頼対象に入れないとIPの書き換えが拒否されてしまいます。

4. 設定のテストと反映

設定ファイルの記述が終わったら、構文チェックを行いApacheを再起動します。

# 設定ファイルの文法チェック
[root@almalinux ~]# sudo httpd -t
# Syntax OK と出れば成功

# Apacheの再起動
[root@almalinux ~]# sudo systemctl restart httpd

5. 動作確認

実際に外部からWebサイト(WordPressなど)にアクセスし、Apacheのアクセスログを確認してみましょう。

[root@almalinux ~]# tail -n 10 /var/log/httpd/access_log

240d:f:660:e200:xxxx:xxxx:xxxx:xxxx - - [20/Jun/2026:20:54:54 +0900] "POST /wp-admin/admin-ajax.php HTTP/1.1" 200 ...
xxx.xxx.xxx.xxx - - [20/Jun/2026:20:56:48 +0900] "GET /feed/? HTTP/1.1" 200 ...

 ログの先頭に 127.0.0.1 ではなく、接続元の「日本のプロバイダのIPv6アドレス」「クローラーの生IPv4アドレス」がしっかりと記録されていれば成功です!

まとめ

生IPアドレスが正しくログに残るようになることで、不審なアクセスやWordPressへのログイン試行があった際に、攻撃者の本当のIPを特定してブロック(Fail2ban等との連携など)できるようになります。

自宅サーバーのセキュリティと運用効率が一段とアップするので、Cloudflare Tunnelを導入した際は必ずセットで設定しておきたい項目です。

コメント