サーバーの IP アドレスが分かれば、Cloudflare を通らずにサーバーへ直接つなぐことができ、WAF やログイン画面の遮断の設定がすべて素通りされます。
本記事では、あるお客様の WordPress サイトで、直接の接続を .htaccess で遮断した手順と、遮断できたことの確認方法を、実測の結果とともに説明します。
IP アドレスが知られる経路と点検の方法は「サーバーの IP アドレスが分かると、守りを素通りされる」で説明しています。本記事はその続きの、サーバー側で閉じる手順です。
結論:.htaccess で、Cloudflare の IP アドレスの範囲だけを通す
サーバー側の .htaccess に、Cloudflare が公開している IP アドレスの範囲だけを許可する記述を置きます。
Cloudflare を経由したアクセスは、必ず Cloudflare の IP アドレスからサーバーへ届くため、それ以外を拒否すれば直接の接続だけが止まります。
| 許可の一覧に入れたもの | 件数・内容 |
|---|---|
| Cloudflare の IPv4 の範囲 | 15件(2026年10月12日に公式の一覧から取得) |
| Cloudflare の IPv6 の範囲 | 7件(同上) |
| サーバー自身 | サーバー自身を指すアドレスと、サーバー自身の IP アドレス(WordPress が自分自身へ送る要求のため) |
各サイトの .htaccess の先頭に、次の形で追記しました。既存の記述は変えていません。
# BEGIN cloudflare-only <IfModule mod_authz_core.c> <RequireAny> Require ip (サーバー自身のアドレス) Require ip (Cloudflare の IPv4 の範囲 15件) Require ip (Cloudflare の IPv6 の範囲 7件) </RequireAny> </IfModule> # END cloudflare-only
Require ipは、サーバーに届いた接続元の IP アドレスで判定します- Cloudflare が付ける「元の閲覧者の IP アドレス」のヘッダー(cf-connecting-ip)では判定していません。このヘッダーは外から偽ることができるためです
- BEGIN と END の行で囲んでおくと、戻すときにその範囲を消すだけで済みます
作業の前に見つかっていたこと
作業の前日に、外から見るだけの点検を行いました。サーバーの IP アドレスへ直接つなぐと、次のように Cloudflare を通らずに応答がありました。
| 直接つないだ先 | 応答 |
|---|---|
| Home | 200(表示される) |
| ユーザー一覧の API(/wp-json/wp/v2/users) | 200(ログイン名が返る) |
| 管理画面(/wp-admin/) | 302(ログイン画面へ到達する) |
| HTTP(80番) | 200(表示される) |
Cloudflare 側では、管理画面の遮断やユーザー一覧の遮断を設定していましたが、直接の接続では、これらの設定がすべて効いていない状態でした。
弊社が行った手順:影響の小さいサイトから3段階に分けて入れる
2026年10月12日に作業しました。同じサーバーに複数のサイトがあったため、影響の小さいものから順に入れ、段階ごとに確認しました。
- 変更前の .htaccess を退避:対象の8か所の .htaccess を、変更前の全文のまま手元へ保存しました
- 第1段階(1時02分):過去の記録用のサイト1つに追記しました
- 第2段階(1時03分):本体のサイト(www 付きと、www の無いドメイン)に追記しました
- 第3段階(1時04分):残る3つのサイトに追記しました
- 段階ごとの確認:各段階の後に、Home・記事・お問い合わせのページ・英語のページが Cloudflare 経由で表示されることを確認しました
作業は1時00分から1時07分までの7分で終わりました。
確認の方法と、変更の前後の結果
確認では、次の3つの経路を比べました。Cloudflare やサーバーのキャッシュに残ったページを見ないよう、URL の末尾に毎回違う文字列を付けました。
- サーバーへ直接(HTTPS・443番と HTTP・80番):名前解決を Cloudflare ではなくサーバーの IP アドレスへ向けて接続する
- Cloudflare 経由(許可の一覧に載った接続元から)
- Cloudflare 経由(許可の一覧に載っていない接続元から):外部の取得サービスを通して確認する
| 段階 | 直接(443/80) | Cloudflare 経由(許可の接続元) | Cloudflare 経由(その他の接続元) |
|---|---|---|---|
| 第1段階 | 403/403(拒否) | 200(表示) | 200(表示) |
| 第2段階 | 403/403(拒否) | 200(表示) | 200(表示) |
| 第3段階 | 3サイトとも 403/403(拒否) | 200(表示) | 200(表示) |
第2段階では、直接の接続で、ユーザー一覧の API・管理画面・ログイン画面がいずれも 403(拒否)に変わったことも確認しました。
直接の接続での POST(フォームの送信などの書き込み)も 403 でした。
この設定だけでは足りないこと
- サーバーのページキャッシュ:サーバーの前段にページキャッシュ(nginx のキャッシュ)があるサーバーでは、キャッシュに入ったページは .htaccess の判定より前に返されます。今回も、Cloudflare 経由で一度表示されたページは、その後の直接の接続でも 200 で返りました。キャッシュに無い URL は 403 でした。届くのは公開済みのページの読み出しだけで、フォームの送信・管理画面・API は止まります。これも塞ぐ場合は、サーバー側のキャッシュの設定を見直します
- ベーシック認証をかけたフォルダー:同じ階層で
Require ipを足すと「どちらか一方を満たせば通す」扱いになり、Cloudflare 経由ならパスワードなしで開いてしまいます。両方を求める場合は<RequireAll>で囲みます。今回はこのフォルダーを変えず、直接の接続にはパスワードが求められることを確認しました - 子のフォルダーの .htaccess:Apache では、子のフォルダーの .htaccess に
Requireの記述があると、親の制限はそのフォルダーに引き継がれません。作業の前に、各サイトのフォルダーにRequireが無いことを確認しました - 作業する側の接続:作業者の事務所からの直接の接続も 403 で拒否されます。管理作業は Cloudflare 経由で行います
- Cloudflare の IP アドレスの範囲が変わったとき:公開の一覧が変わったら、許可の一覧を作り直して BEGIN〜END を差し替えます。差し替えないと、新しい範囲から来た閲覧者が拒否され、サイトを見られません
戻すときは、各 .htaccess の「# BEGIN cloudflare-only」から「# END cloudflare-only」までを消すか、退避した変更前の .htaccess を戻します。反映は即時です。
出典
- Cloudflare の IPv4 の範囲の一覧 https://www.cloudflare.com/ips-v4(2026/10/12 確認)
- Cloudflare の IPv6 の範囲の一覧 https://www.cloudflare.com/ips-v6(2026/10/12 確認)
- Cloudflare「Protect your origin server」 https://developers.cloudflare.com/fundamentals/security/protect-your-origin-server/(2026/10/11 確認)