6.

IP制限をかける方法|Apache・Nginx・ファイアウォールでの設定例

編集

IP制限とは、特定のIPアドレス(または範囲)からのアクセスだけを許可し、それ以外を拒否する、あるいは特定のIPからのアクセスを拒否するアクセス制御の手法です。WebサーバーならApacheの「Require」ディレクティブやNginxの「allow / deny」、サーバー全体ならファイアウォール(firewalld / iptables / ufw)、その手前ならクラウドのセキュリティグループやWAFで設定するのが基本です。

この記事の要点
  • IP制限は「どの層で止めるか」で設定場所が変わる。Webアプリだけならサーバーソフト、サーバー全体ならファイアウォール、ネットワークの入口ならクラウド側で行う。
  • Apache 2.4以降Require ipRequire all deniedを使う。古いOrder / Allow / Deny(mod_access_compat由来)は非推奨で、2.4系では混在させないのが推奨。
  • Nginxallowdenyを記述順に評価し、最初に一致したルールが適用される。
  • OSのファイアウォールは、Linuxならfirewalld・iptables(nftables)・ufwのいずれかで送信元IP単位の許可/拒否ができる。
  • CIDR表記(例: 192.168.0.0/24)を使えば範囲をまとめて指定できる。
  • 落とし穴: プロキシ/ロードバランサー経由だと送信元IPが変わるためX-Forwarded-Forの考慮が必要。IPv6の指定漏れや、自分自身を締め出す事故にも注意。

 

IP制限とは

IP制限(IPアクセス制限)は、アクセス元のIPアドレスを条件として通信を許可または拒否する仕組みです。考え方は大きく2通りあります。

  • 許可リスト方式(ホワイトリスト): 原則すべて拒否し、信頼できる特定のIPだけを許可する。管理画面・社内システムなど、限られた相手だけにアクセスさせたい場合に有効。
  • 拒否リスト方式(ブラックリスト): 原則すべて許可し、問題のある特定のIPだけを拒否する。不正アクセス元の遮断などに使う。

セキュリティ目的では、原則拒否+必要な相手だけ許可する許可リスト方式のほうが堅牢です。なお、IP制限はあくまで「どこから来たか」での制御であり、IPは偽装・共有・変動し得るため、認証(パスワード・鍵)と組み合わせて使うのが前提です。

制限をかける「層」は次のように整理できます。下の層ほど早い段階で遮断でき、上の層ほどアプリの事情に合わせた細かい制御がしやすくなります。

  • クラウド/ネットワーク層: セキュリティグループ、ネットワークACL、WAF(ネットワークの入口で遮断)
  • OS層: firewalld / iptables / ufw(サーバーに届くパケット単位で遮断)
  • Webサーバー層: Apache / Nginx(HTTPリクエスト単位で遮断)
  • アプリケーション層: フレームワークやミドルウェアでの判定

 

①Apacheでの設定(.htaccess / httpd.conf)

Apache HTTP Serverでは、httpd.confや仮想ホスト設定、または.htaccessでIP制限をかけられます。Apache 2.4以降ではRequireディレクティブ(mod_authz_host)を使うのが正しい書き方です。

特定IPだけ許可する(許可リスト)

たとえば203.0.113.10と社内ネット192.168.1.0/24だけを許可し、それ以外を拒否する場合は次のように書きます。

<Directory "/var/www/html/admin">
    Require ip 203.0.113.10
    Require ip 192.168.1.0/24
</Directory>

複数のRequireを並べた場合、デフォルト(RequireAny)ではいずれか1つに一致すれば許可されます。明示的に「すべて拒否してから一部許可」を表したい場合は次のようにも書けます。

<RequireAll>
    Require all denied
    Require ip 203.0.113.10
</RequireAll>

特定IPだけ拒否する(拒否リスト)

<RequireAll>
    Require all granted
    Require not ip 198.51.100.23
</RequireAll>

特定ファイルだけ制限する

特定のファイル(例: wp-login.php)に対してだけ制限したい場合は<Files><FilesMatch>を使います。

<Files "wp-login.php">
    Require ip 203.0.113.10
</Files>

古い Allow / Deny について

Apache 2.2まで使われていたOrderAllow fromDeny fromという書き方は、2.4以降では互換モジュールmod_access_compatによる非推奨(deprecated)の構文です。当面は動作しますが、新規に書くならRequire系を使うべきです。参考までに、2.2時代の同等の書き方は次の通りでした。

# Apache 2.2 までの書き方(2.4以降は非推奨)
Order deny,allow
Deny from all
Allow from 203.0.113.10

新旧の構文を同じ範囲で混在させると、認可の評価が直感に反する結果になりやすいため、どちらか一方に統一してください。設定変更後はapachectl configtestで構文を確認し、リロードして反映します。

 

②Nginxでの設定(allow / deny)

Nginxではngx_http_access_moduleallowdenyディレクティブを使います。httpserverlocationのいずれのブロックにも書け、上から順に評価し、最初に一致したルールが適用されます。

特定IPだけ許可する

location /admin/ {
    allow 203.0.113.10;
    allow 192.168.1.0/24;
    deny all;
}

許可したいIPをallowで列挙し、最後にdeny all;で残りを拒否します。順序が重要で、deny all;を先に書くと以降のallowに到達しません。

特定IPだけ拒否する

server {
    deny 198.51.100.23;
    allow all;
}

設定後はnginx -tで構文チェックし、nginx -s reloadで反映します。なお、ロードバランサーやCDNの背後にNginxを置く場合は、後述のとおりallowdenyが見るIPが実クライアントではなくプロキシのIPになる点に注意が必要です(ngx_http_realip_moduleで実IPに置き換えてから判定するのが定石です)。

 

③ファイアウォール(firewalld / iptables / ufw)

OSのファイアウォールで制限すると、Webサーバーに限らずサーバーへ届くすべての通信を送信元IP単位で制御できます。Linuxでは主に次の3つが使われます。

firewalld(RHEL系で標準)

rich rule を使うと送信元IPを指定できます。次の例は203.0.113.10からのSSH(22番)を許可します。

# 特定IPからのSSHを許可
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" port port="22" protocol="tcp" accept'

# 特定IPからの通信を拒否
firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="198.51.100.23" reject'

firewall-cmd --reload

iptables(nftables)

古くから使われる低レベルなツールです。次の例は特定IPからの22番を許可し、それ以外を拒否します。

# 特定IPからのSSHを許可、それ以外は拒否
iptables -A INPUT -p tcp -s 203.0.113.10 --dport 22 -j ACCEPT
iptables -A INPUT -p tcp --dport 22 -j DROP

iptablesはルールを上から順に評価し、最初に一致したルールが適用されるため、許可ルールを拒否ルールより前に置く必要があります。近年のディストリビューションでは内部的に後継のnftablesが使われていることが多く、新規構築ではnftablesやfirewalld経由での設定が推奨されます。設定はそのままでは再起動で消えるため、永続化(iptables-save等)も忘れないようにします。

ufw(Ubuntu/Debianで簡単)

# 特定IPからのSSHを許可
ufw allow from 203.0.113.10 to any port 22

# 特定IPからの通信を拒否
ufw deny from 198.51.100.23

ufwはiptablesのフロントエンドで、コマンドが簡潔なのが利点です。ufw status numberedで現在のルールを確認できます。

参考: TCP Wrapper(hosts.allow / hosts.deny)

従来、/etc/hosts.allow/etc/hosts.denyによるTCP Wrapperでのアクセス制御も使われてきました。hosts.allowを先に評価し、許可されずhosts.denyに該当するIPを拒否します。ただしTCP Wrapper(libwrap)は近年のディストリビューションでは縮小・廃止が進んでいるため、現在はファイアウォールで制御するのが基本です。

# /etc/hosts.allow
sshd: 203.0.113.10

# /etc/hosts.deny
ALL: ALL

 

④アプリ/クラウドでの制限(WAF・セキュリティグループ)

クラウド環境では、サーバーに届く前のネットワーク入口で制限するのが効率的です。

  • セキュリティグループ: 仮想サーバー(インスタンス)単位のファイアウォール。インバウンドルールで「送信元IP(CIDR)」と「ポート」を指定して許可する。AWS・各社クラウドで広く提供。
  • ネットワークACL(NACL): サブネット単位で許可/拒否を設定。セキュリティグループと違い「拒否」ルールも明示できる。
  • WAF(Web Application Firewall): HTTP層で動作し、IPアドレスのほか地域(GeoIP)やリクエスト内容で制御できる。CDNと組み合わせて使うことが多い。

これらは管理コンソール(GUI)やAPI、IaC(Terraform等)で設定します。具体的なメニュー名・上限値は各サービスのバージョンや仕様により異なるため、利用中のサービスの公式ドキュメントを確認してください。

アプリケーション側(PHP・Java・各種フレームワーク)で送信元IPを判定して弾くこともできますが、後述のプロキシ問題があるため、どのIPを「送信元」とみなすかの扱いに注意が必要です。

 

環境別の比較

方法 主な設定場所 制御の単位 向いている用途
Apache.htaccess / httpd.conf(RequireHTTPリクエスト(パス・ファイル単位)Webの特定ディレクトリ・管理画面の制限
Nginxnginx.conf(allow/denyHTTPリクエスト(location単位)Webの細かいパス単位の制限
firewalld / iptables / ufwOSのファイアウォールパケット(IP・ポート単位)SSHなどサーバー全体の入口制限
セキュリティグループ / NACLクラウド管理画面・APIインスタンス/サブネット単位クラウドでの入口制限
WAFWAF / CDNHTTP(IP・地域・内容)地域制限や攻撃遮断を含む高度な制御

 

CIDR表記(範囲の指定)

IP制限では1つずつではなく範囲をまとめて指定したい場面が多く、その際に使うのがCIDR表記です。IPアドレス/プレフィックス長の形で書き、プレフィックス長は「先頭から何ビットを固定するか」を表します。

表記 意味 含まれるアドレス数(目安)
203.0.113.10/32その1つのIPだけ1個
192.168.1.0/24192.168.1.0〜192.168.1.255256個
10.0.0.0/1610.0.0.0〜10.0.255.255約6.5万個
0.0.0.0/0すべてのIPv4アドレス全部

プレフィックス長が小さいほど広い範囲を表します。単一IPを指定するときの/32は省略できるツールも多いですが、明示するとCIDRであることが分かりやすくなります。IPv6では同様に2001:db8::/32のように書きます。

 

落とし穴・注意点

設定前に必ず確認したい注意点
  • プロキシ/ロードバランサー経由で送信元IPが変わる: CDN・LB・リバースプロキシの背後では、サーバーから見える送信元IPがクライアントではなくプロキシのIPになる。そのままだと全員が同じIPに見え、IP制限が機能しない、あるいは全員を弾いてしまう。
  • X-Forwarded-Forの扱い: 実クライアントIPはX-Forwarded-Forヘッダで渡されることが多い。Nginxならngx_http_realip_module、Apacheならmod_remoteip信頼できるプロキシからのヘッダだけを実IPに反映させてから判定する。ヘッダはクライアントが詐称できるため、信頼するプロキシを限定せずに鵜呑みにしないこと。
  • IPv6の指定漏れ: IPv4だけを許可・拒否しても、サーバーがIPv6でも待ち受けていると、IPv6側からのアクセスが想定外に通る/弾かれることがある。IPv4とIPv6の両方を漏れなく設定する。
  • 自分自身を締め出す: 許可リストで原則拒否にすると、設定ミスで自分の管理用IPまで拒否してしまい、サーバーにログインできなくなる事故が起きやすい。特にSSHのファイアウォール設定では、別経路(コンソール)を確保し、可能なら自動ロールバック付きで適用する。
  • 動的IP・共有IP: 家庭用回線やモバイルはIPが変わることがあり、固定で許可した相手が翌日アクセスできなくなる場合がある。逆に、特定IPを拒否しても同じIPを共有する無関係な利用者まで巻き込むことがある。

 

よくある質問(FAQ)

Q. ApacheでもうAllow / Denyで動いているのですが、書き直す必要はありますか。
A. 2026年時点でApache 2.4系なら、AllowDenyは互換モジュールmod_access_compatにより動作はしますが非推奨です。すぐ壊れるわけではないものの、新規・改修のタイミングでRequire系へ移行するのが推奨されます。新旧構文の混在は挙動が読みにくくなるため避けてください。

Q. WebサーバーとファイアウォールのどちらでIP制限すべきですか。
A. 目的次第です。SSHなどHTTP以外も含めサーバー全体を守るならファイアウォール(やクラウドのセキュリティグループ)が適し、Webの特定パスや管理画面だけを限定したいならApache/Nginxが向きます。両方を併用し、入口で広く絞ってからアプリ側で細かく制御するのが堅実です。

Q. IP制限だけで十分なセキュリティになりますか。
A. なりません。IPアドレスは詐称・共有・変動し得るため、IP制限は「アクセスできる相手を絞る」補助的な層です。必ずパスワードや公開鍵認証、TLS、適切な権限設定などと組み合わせて多層防御にしてください。

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. クラス
  2. グローバルIPアドレス
  3. プライベートIPアドレス
  4. 内部IPアドレスの確認方法(Linux)
  5. 外部IPアドレスの確認方法(Linux)
  6. IP制限をかける方法

最近更新/作成されたページ