.htaccessでIP制限をかける方法|特定のIPだけ許可・拒否する書き方【Apache 2.4】

開発中のサイトや管理画面を、社内や自宅など決まった場所からしか開けないようにしたいときは、.htaccessでIPアドレスによるアクセス制限(IP制限)をかけるのが手軽です。サーバーの設定ファイルを触れないレンタルサーバーでも、.htaccessを1つ置くだけで設定できます。
この記事では、Apache 2.4の書き方で、特定のIPアドレスだけを許可する方法、拒否する方法、範囲の指定、ファイルやWordPressの管理画面だけを制限する方法、うまく効かないときの確認ポイントまでを解説します。
.htaccessのIP制限とは
IP制限は、アクセスしてきた端末のIPアドレスを見て、表示を許可するか拒否するかを決める仕組みです。許可されていないIPアドレスからアクセスすると、「403 Forbidden」のエラーになります。
同じアクセス制限でも、Basic認証とは次の点が違います。
| IP制限 | Basic認証 | |
|---|---|---|
| 判定に使うもの | アクセス元のIPアドレス | ユーザー名とパスワード |
| 入力の手間 | なし(許可された場所からはそのまま開ける) | 開くたびに入力が必要 |
| 向いている場面 | 社内・自宅など、決まった場所からだけ使うページ | 場所を問わず、知っている人だけに見せたいページ |
| 弱点 | IPアドレスが変わる環境では使いにくい | パスワードが漏れると誰でも開ける |
許可するIPアドレスには、インターネット側から見えるグローバルIPアドレスを指定します。自分のグローバルIPアドレスは「IPアドレス確認ツール」で調べられます。
この記事の例では、説明用のIPアドレス(203.0.113.0〜203.0.113.255、198.51.100.0〜198.51.100.255)を使っています。実際に設定するときは、ご自分の環境のIPアドレスに置き換えてください。
IP制限の基本の書き方
特定のIPアドレスだけ許可する
制限したいディレクトリに、次の内容の.htaccessを置きます。203.0.113.25 からのアクセスだけが表示され、それ以外は403エラーになります。
Require ip 203.0.113.25Require ip は「このIPアドレスからのアクセスなら許可する」という意味です。許可の条件に合わないアクセスは、すべて拒否されます。
複数のIPアドレスを許可する
許可したいIPアドレスが複数あるときは、スペースで区切って並べます。
Require ip 203.0.113.25 198.51.100.101行に1つずつ書いても同じ意味になります。複数の Require を並べると、「どれか1つに当てはまれば許可」として扱われます。社内と自宅のように場所ごとに分けて書くと、後から見て分かりやすくなります。
# 社内
Require ip 203.0.113.25
# 自宅
Require ip 198.51.100.10コメント(#)は、必ず行の先頭から書いてください。Require ip 203.0.113.25 # 社内 のように行の途中に書くと、「#」もIPアドレスとして読まれてしまい、500エラーになります。
IPアドレスの範囲を指定する
会社のネットワークなどで、連続したIPアドレスをまとめて許可したいときは、範囲で指定できます。書き方は3通りあります。
# CIDR表記(203.0.113.0〜203.0.113.255)
Require ip 203.0.113.0/24
# 先頭部分だけ書く(203.0.113.0〜203.0.113.255)
Require ip 203.0.113
# ネットマスクで書く(203.0.113.0〜203.0.113.255)
Require ip 203.0.113.0/255.255.255.03つとも同じ範囲を表しています。よく使うCIDR表記の範囲は次のとおりです。
| 書き方 | 範囲 | IPアドレスの数 |
|---|---|---|
203.0.113.25/32 | 203.0.113.25 だけ | 1 |
203.0.113.24/29 | 203.0.113.24〜203.0.113.31 | 8 |
203.0.113.0/24 | 203.0.113.0〜203.0.113.255 | 256 |
203.0.0.0/16 | 203.0.0.0〜203.0.255.255 | 65,536 |
「先頭部分だけ書く」方法は、203.0.113 のように区切りの「.」単位でしか指定できません。203.0.113.24〜203.0.113.31 のように、区切りの途中で範囲を切りたいときはCIDR表記を使います。
特定のIPアドレスだけ拒否する
反対に、全体は公開したまま、迷惑なアクセスを繰り返すIPアドレスだけを拒否したいときは、次のように書きます。
<RequireAll>
Require all granted
Require not ip 203.0.113.25
Require not ip 198.51.100.0/24
</RequireAll><RequireAll> は「中の条件をすべて満たしたときだけ許可する」という意味です。「全員を許可する(Require all granted)」と「このIPアドレスではない(Require not ip)」の両方を満たす場合、つまり指定したIPアドレス以外からのアクセスだけが表示されます。
Require not ip は、<RequireAll> の外に単独で書くと500エラーになります。拒否の条件は、必ず <RequireAll> で囲んでください。
IPv6アドレスを指定する
IPv6アドレスも、同じ Require ip で指定できます。範囲はCIDR表記で書きます。
Require ip 2001:db8::25
Require ip 2001:db8::/32最近は、IPv6で接続している家庭や会社が増えています。IPv4アドレスだけを許可していると、IPv6で接続したときに403エラーになります。詳しくは後の「IP制限が効かないときの確認ポイント」で説明します。
制限する範囲を決める
ディレクトリ単位で制限する
.htaccessの設定は、置いたディレクトリと、その下のすべてのディレクトリに効きます。たとえば /staging/ に置けば、/staging/ 以下だけが制限され、ほかのページには影響しません。
制限したディレクトリの中に、誰でも見られるようにしたいディレクトリがある場合は、そのディレクトリに次の.htaccessを置きます。下の階層の .htaccess に書いた Require は、上の階層の Require を置き換えるので、そこから下だけ制限が外れます。
Require all granted特定のファイルだけ制限する
ディレクトリ全体ではなく、特定のファイルだけを制限したいときは、<Files> で対象のファイル名を指定します。
<Files "admin.php">
Require ip 203.0.113.25
</Files>複数のファイルをまとめて指定したいときは、正規表現が使える <FilesMatch> を使います。次の例は、PDFとZIPのファイルだけを制限します。
<FilesMatch "\.(pdf|zip)$">
Require ip 203.0.113.25
</FilesMatch>WordPressの管理画面だけ制限する
WordPressのログイン画面や管理画面への不正なログインを防ぐ目的でも、IP制限はよく使われます。設定は2か所に分けて行います。
1つ目は、ログイン画面(wp-login.php)です。WordPressをインストールしたディレクトリの.htaccessに、次の内容を書き足します。
<Files "wp-login.php">
Require ip 203.0.113.25
</Files>この.htaccessには、WordPressが自動で書き換える「# BEGIN WordPress」から「# END WordPress」までの部分があります。この部分の中に書くと、パーマリンクの設定を保存したときなどに消えてしまうので、必ずその外(前か後ろ)に書いてください。
2つ目は、管理画面のディレクトリ(wp-admin)です。wp-admin の中に、次の内容で.htaccessを新しく作ります。
Require ip 203.0.113.25
<Files "admin-ajax.php">
Require all granted
</Files>admin-ajax.php は、管理画面の中にありながら、公開側のページからも使われるファイルです。お問い合わせフォームや「もっと見る」ボタンなど、プラグインやテーマの機能が呼び出しています。ここまで制限すると、一般の訪問者が使う機能が動かなくなるので、このファイルだけ制限から外しています。
設定した後は、許可したIPアドレスからログインできること、公開側のページでフォームなどが動くことを必ず確認してください。
拒否したときに表示するページを変える
拒否されたときには、サーバー標準の「403 Forbidden」の画面が表示されます。自分で作ったページを表示したいときは、ErrorDocument で指定します。パスは、サイトのドキュメントルートから書きます。
ErrorDocument 403 /403.html
Require ip 203.0.113.25IP制限とBasic認証を組み合わせる
IP制限とBasic認証は、組み合わせて使うこともできます。組み合わせ方は2通りあります。
両方を満たしたときだけ許可する
許可したIPアドレスからのアクセスで、さらにパスワードも正しいときだけ表示します。セキュリティを最も高くしたい場合の書き方です。
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /home/example/.htpasswd
<RequireAll>
Require ip 203.0.113.25
Require valid-user
</RequireAll>どちらか一方を満たせば許可する
社内からはパスワードなしで開け、社外からはパスワードを入力すれば開ける、という使い方です。<RequireAny> は「中の条件のどれか1つを満たせば許可する」という意味です。
AuthType Basic
AuthName "Restricted Area"
AuthUserFile /home/example/.htpasswd
<RequireAny>
Require ip 203.0.113.25
Require valid-user
</RequireAny>AuthUserFile には、.htpasswdファイルの場所をサーバー上の絶対パスで書きます。.htpasswdファイルは「.htpasswd作成ツール」で作れます。絶対パスの調べ方は「Basic認証で必要なAuthUserFileの絶対パスを調べる方法」、IP制限とBasic認証を組み合わせた設定の全体は「.htaccessで2段階のアクセス制限をかける方法」で解説しています。
Apache 2.2の書き方との違い
IP制限の解説を探すと、Order・Allow・Deny を使った書き方もよく見かけます。これは古いApache 2.2の書き方です。主な書き方の対応は次のとおりです。
| やりたいこと | Apache 2.4 | Apache 2.2 |
|---|---|---|
| 特定のIPだけ許可 | Require ip 203.0.113.25 | Order Deny,AllowDeny from allAllow from 203.0.113.25 |
| 特定のIPだけ拒否 | <RequireAll>Require all grantedRequire not ip 203.0.113.25</RequireAll> | Order Allow,DenyAllow from allDeny from 203.0.113.25 |
| 全員を許可 | Require all granted | Order Allow,DenyAllow from all |
| 全員を拒否 | Require all denied | Order Deny,AllowDeny from all |
Apache 2.4でも、互換用のモジュール(mod_access_compat)が有効なサーバーなら2.2の書き方が動きます。ただし、このモジュールが無いサーバーでは500エラーになります。今から設定するなら、2.4の書き方を使ってください。
特に注意したいのが、2.2と2.4の書き方を混ぜた場合です。両方の書き方があると、それぞれの判定を両方とも満たさないと許可されません。たとえば次のように書くと、許可したはずの 203.0.113.25 からも403エラーになります。古い Deny from all が残っていて、全員を拒否しているためです。
# 間違った例:203.0.113.25 からも開けない
Require ip 203.0.113.25
Order Deny,Allow
Deny from all2.4の書き方に書き換えるときは、Order・Allow・Deny の行を残さず消してください。
IP制限が効かないときの確認ポイント
許可したのに403エラーになる
- IPアドレスが変わっていないか:家庭用のインターネット回線やスマートフォンの回線は、ルーターの再起動などでIPアドレスが変わることがあります。IPアドレス確認ツールで、今のIPアドレスを確認してください。
- IPv6で接続していないか:同じ回線でも、IPv4とIPv6のどちらで接続するかは環境によって変わります。IPv4アドレスだけを許可していて、IPv6で接続していると拒否されます。両方を許可するか、IPv6アドレスも追加してください。
- VPNを使っていないか:VPNに接続していると、VPNサーバーのIPアドレスでアクセスすることになります。
- 2.2の書き方が残っていないか:
Deny from allなどが残っていると、Require ipで許可しても拒否されます(前の節を参照)。上の階層の.htaccessも確認してください。
500エラーになる
- 行の途中にコメントを書いていないか:
Require ip 203.0.113.25 # 社内のような書き方は500エラーになります。コメントは行の先頭に書きます。 Require not ipを単独で書いていないか:拒否の条件は<RequireAll>で囲む必要があります。- .htaccessで
Requireが使える設定になっているか:サーバーの設定(AllowOverride)で、.htaccessでの認証・アクセス制限の設定(AuthConfig)が許可されている必要があります。レンタルサーバーで使えない場合は、サーバー会社のマニュアルを確認してください。 - 2.2の書き方を使っていないか:互換用のモジュールが無いサーバーでは、
Order・Allow・Denyが500エラーになります。
CDNやロードバランサーを経由している
Cloudflareなどのサービスや、サーバーの手前にあるロードバランサーを経由している場合、Apacheから見たアクセス元は、訪問者ではなく中継するサーバーのIPアドレスになります。このままでは、訪問者のIPアドレスで制限できません。
訪問者の本来のIPアドレスは、中継するサーバーが「X-Forwarded-For」などのヘッダーに入れて送ってきます。.htaccessでは、SetEnvIf でこのヘッダーを調べて制限する方法があります。
SetEnvIf X-Forwarded-For "^203\.0\.113\.25$" allowed_ip
Require env allowed_ipただし、ヘッダーはアクセスする側が自由に書き換えられます。中継するサーバーを通さずに直接アクセスされると、ヘッダーをごまかすだけで制限を通り抜けられてしまいます。CDNやロードバランサーを使っている場合は、次の方法を優先してください。
- CDNやロードバランサーが持っているアクセス制限の機能を使う
- サーバーの設定で mod_remoteip を有効にしてもらう。中継するサーバーから届いたヘッダーだけを信用して、訪問者のIPアドレスに置き換える仕組みで、有効になっていれば
Require ipがそのまま使えます。サーバー全体の設定が必要なので、.htaccessだけでは設定できません。
Nginxのサーバーを使っている
.htaccessはApacheの機能です。Nginxのサーバーでは、.htaccessを置いても読み込まれず、制限はかかりません。Nginxでは、サーバーの設定ファイルに allow と deny を書きます。
location /staging/ {
allow 203.0.113.25;
deny all;
}まとめ
- 特定のIPアドレスだけ許可するには、
Require ipを書く - 複数のIPアドレスはスペース区切りか複数行で、範囲はCIDR表記で指定する
- 特定のIPアドレスだけ拒否するには、
<RequireAll>の中にRequire not ipを書く - ファイルは
<Files>、WordPressの管理画面はwp-login.phpとwp-adminの2か所で制限する - Apache 2.2の
Order・Allow・Denyは使わず、2.4の書き方と混ぜない - 効かないときは、IPアドレスの変化、IPv6、CDN経由かどうかを確認する
IP制限は、.htaccessを1つ置くだけでかけられる手軽なアクセス制限です。設定する前に、IPアドレス確認ツールで自分のIPアドレスを確かめておきましょう。





