CloudflareでプロキシしながらユーザーのグローバルIPアドレスを取得する方法

こんにちは!
RSPインターネットグループ インフラエンジニアリングの陸ステです。

WordPressで取得するグローバルIPv4v6アドレスを正規ユーザーのIPに
する方法を紹介していきたいと思います。

弊組織グループは、順次Cloudflareを導入しておりますが導入する過程で
管理上の理由から接続した組織員の生IP等を取得する必要があり、記事と
して紹介されている方法がほとんど、リバースプロキシ向けのものが多く
調整に苦戦(は?)したため、今回は弊組織が設定している値などを紹介
していきます(ご参考にされる際は、注意事項もご確認ください)。

この記事は、あくまでも弊組織グループの環境で運用する際に設定した値を紹介するものです。
皆様の環境が弊組織環境と異なる可能性もため、本記事の情報で動作しない可能性があります。
仮に本記事通りに設定する場合は、事前にバックアップをするなどをお願い致します。

※サーバによっては、すでにCloudflare等を通しても取得できる場合があります。
 弊組織で確認したサーバ:コアサーバー(v2)、XREA、mixhost(RisuPu鯖)
※弊組織は、本記事を技術情報として発信しているため参考にした結果の損害は、
 一切責任を負いかねます。
※弊組織グループの環境につきましては、記事上で記載します。

弊組織グループの環境について(サーバー)

弊組織グループの環境は、運用しているページなどによって異なりますが
弊組織は現在、ConoHa WINGさん・お名前.comさんのどちらかですね。
検証時に両サーバーで動作することは確認しています。
(尚、サーバIPは現在順次公開されない状況になってはいます。)

弊組織グループでの独自調査ですが、両サービスの構成はほとんど違いはありません。
そのため、ConoHa WINGで動作するものはお名前.com レンタルサーバー(RS)でも
動作します。なお、その逆も然りです(因みに言うとプラン的な違いはあります)。

P.S. ごめんなさい、他社サーバーさんについて動作確認等はできていません。

弊組織グループの環境について(WordPress)

バージョンは、セキュリティ上の観点から記載はしませんが、
WordPress(以下WP)で構成されている普通のサイトです。
マルチサイト化とかも一切していないものです。

一部プラグインの設定も設定する為、そのプラグインについて
記載しておきますが、JP-Secureジェイピー・セキュア社の「SiteGuardサイトガード WP」です。

IPアドレスの取得方法を定義する

ファイル名については、設定コード前に「ファイル名」を拡張子ありで掲載します。
変更するファイル、バックアップ取得のファイルには誤りがないようご注意下さい。
※直下の場合は、直下である旨、それ以外はファイルパスも記載しております。

まずは、WordPressインストール直下にある「wp-config.php」に以下を追記します。

# start | remote_addr to http_cf_connecting_ip by https://freeblog.rspnet.jp/?p=364
if (isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CF_CONNECTING_IP'];
}
# end | remote_addr to http_cf_connecting_ip by https://freeblog.rspnet.jp/?p=364

なお、変数「HTTP_CF_CONNECTING_IP」が取得できない場合は以下をご利用ください。

# start | remote_addr to http_x_forwarded_for by https://freeblog.rspnet.jp/?p=364
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
    $_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_X_FORWARDED_FOR'];
}
# end | remote_addr to http_x_forwarded_for by https://freeblog.rspnet.jp/?p=364

これでWordPress自身がREMOTE_ADDRでCloudflareから通知された閲覧者さんのIP取得が
行えるようになりました。コメントなどでもCFではないコメントした方のIPが記載されると
思いますので、確認してみてください。

Cloudflareで閲覧者さんのグローバルIPv4v6アドレス取得は、以下のdocを参考にしました。
その他にも日本からのアクセスか判定する方法もあるので、日本以外は閲覧禁止にしたい等で
活用することもできますので、是非見てみてください。

Cloudflare HTTP request headers | Cloudflare Fundamentals docs
Cloudflare passes all HTTP request headers to your origin web server and adds additional headers as specified below.

ちなみにWordPressのモバイルアプリだとxmlrpx.phpにアクセスする必要があります。
アクセス制御している場合は、IP制限を外すか以下のようなコードが必要です。
SetEnvIfについては、本記事の本題とは離れるため詳細は省略します。
※IPアドレスは、例で弊組織ネットワークのものを掲載しております。
 ご自身のIPに変更してくださいね!

<Files xmlrpc.php>
SetEnvIf "CF-Connecting-IP" "122.222.1.93" "myip" # ←環境が複数ある場合は、コピー等で対応
Order deny,allow
Deny from all
Allow from env=myip
</Files>

ちなみにSiteGuardのWAFがある場合、以下のようなIPアドレスでの除外は使えません。

SiteGuard_User_ExcludeSig ip(122.222.1.93)

その場合は、SiteGuardのWAFをOFFにするか、できない場合は全許可にしてCFに任せましょう!
(REMOTE_ADDR以外から取得する方法をご存じの方がいらっしゃいましたら、教えてほしいです!)

SiteGuard_User_ExcludeSig all
SiteGuard WPで取得するIPアドレスを変更する

WordPressのセキュリティプラグイン「SiteGuard WP」を利用している方は、こちらの設定が必要です。
それ以外のセキュリティプラグインに関しましては、不明です。申し訳ありません!

変更する前にSiteGuard WPのソースコード一部を変えてもよいのか問題ですが、
ライセンス上はGNUライセンスですので、変更しても問題はないという見解です。
ライセンスはこちら↓

siteguard/license.txt at master · wp-plugins/siteguard
WordPress.org Plugin Mirror. Contribute to wp-plugins/siteguard development by creating an account on GitHub.

それでは、早速設定していきますがプラグインの設定状況によって、変更が必要か否かも
異なります。

現時点のバージョンでもSiteGuard WPにある「管理ページアクセス制限」をONにしている
場合は、設定変更が必要です。こちらをOFFにしている方は、ログイン通知関係の取得でも
wp-config.phpに設定したコードは有効なので、以下の変更は必要ありません。

ONにしている方は、また条件分岐します。

SiteGuardのバージョンが「1.6.1」以前だと[X_FORWARDED_FOR]から取得変更が可能
でした。ただバージョンが「1.7.0」以降は、完全に[REMOTE_ADDR]からのみです。
一応IPアドレス自体は、正確なログイン時のIPが取得できますが.htaccessに記載される値を
変更する必要があります。

今からインストールすると1.7.0以降になるので、1.7.0の設定方法を先に紹介します。

ファイルパスが「/wp-content/plugins/siteguard/classes/siteguard-admin-filter.php」の
ファイルで48行~50行を以下に変更します。(SiteGuard WP バージョン:1.7.0以上)

	function get_rewrite_cond( $ip ) {
		return '    RewriteCond %{HTTP:CF-Connecting-IP} !^' . str_replace( '.', '\.', $ip ) . "$\n";
	} // by https://freeblog.rspnet.jp/?p=364

次に1.6.1以前の場合も同じ感じでREMOTE_ADDRを変更するだけですが、こちらのファイル
パスも同様「/wp-content/plugins/siteguard/classes/siteguard-admin-filter.php」にて
84行~86行を以下値に変更します。(SiteGuard WP バージョン:1.6.1以下)

		if ( 0 === $ip_mode ) {
			return '    RewriteCond %{HTTP:CF-Connecting-IP} !^' . str_replace( '.', '\.', $ip ) . "$\n";
		} // by https://freeblog.rspnet.jp/?p=364

どちらのバージョンも[HTTP:CF-Connecting-IP]の部分が[REMOTE_ADDR]だったと思います。
wp-config.phpでのコードはプログラム的に置き換えているだけで、サーバーから見たら
REMOTE_ADDRは、そのままCloudflareのIPアドレスが通知されるので、.htaccessでは
明確的に参照元の変更が必要です。

こういう部分を考えると自動的に置き換えられるサーバーは一見便利ではありますね。
どちらもメリット・デメリットはありますが()

Cloudflareからどういうヘッダーが取得できるのか(番外編)

CloudFlareを使うとどういうヘッダーを取得できるのか、番外編で紹介します。

Cloudflare からの HTTP リクエストヘッダを可視化する - Qiita
はじめにWeb サイトに Cloudflare の Proxy を適用すると、元々の HTTP リクエストに対してヘッダが追加されます。そうしたヘッダ情報を可視化することで、理解を深めたり、トラ…

筆者:@khayama様の以下コードをphpファイルで作成することで確認できます。

<?php
  echo php_uname('n');
  echo " <br />\n";
  echo " <br />\n";
  $headers = apache_request_headers();
  foreach ($headers as $header => $value) {
    echo "$header: $value <br />\n";
  }
?>

レンタルサーバーによって、出力してもらえる値があったりなかったりするので、
ぜひお使いのレンタルサーバーで出力してみてください!
(差し支えなければ、コメントでご共有頂けると幸いです!)

Cloudflare利用時に使えるtrace(番外編)

読み方というかなんと総称されているのかわかりませんでした()

まあ簡単に言えば、CFでプロキシしているときに見れるやつですね(はい?)。

https://u.rspn.jp/rl1?btn_id=freeblog_rspnet_jp-p364_post20240330a21
おわりに

ほんとは、この記事をCloudflare導入した翌日の25日に公開するつもりでしたが、
いろいろとあって記事をまとめる時間がありませんでした(計画性が著しk(ry)。
まぁ3月中に公開できたので、ヨシ!(は?)

ではでは、RSPインターネットグループ ネットワークチーム 陸ステでした^^

コメント

  1. vpn469465381.opengw.net:995 より:

    LiteSpeedが採用されてるサーバー会社は基本remote_addrが勝手に置き換えられますよ

    • コメントありがとうございます。

      確認した限りではサーバーソフトウェア設定が依存するため、
      LiteSpeedが採用されているからREMOTE_ADDRが正規IPとなる
      というわけではありません。

      少なくとも、列挙していたサーバ事業者はご認識の通り置き換えられます。

トップへ戻る