結論
IP制限をかけたいディレクトリ配下に「.htaccess」を作成し、次のような記述をします
### Define Environment Variables
<IfModule mod_env.c>
# 許可するIPアドレスをここに記入
SetEnvIf REMOTE_ADDR 192.168.33.1 IsAdmin=1
# ロードバランサなどを使ってるならコメントアウトを外してここに記入
#SetEnvIf X-Forwarded-For xx.xx.xx.xx IsAdmin=1
</IfModule>
### Access Restriction By Client IP Address
Order deny,allow
Deny from all
Allow from env=IsAdmin
### Replace 403 Page To 404
ErrorDocument 403 /admin/403.html
ErrorDocument 404 /admin/404.html
<Files ~ "40(3|4).html">
Order allow,deny
Allow from all
</Files>
### Return 404 Error To Denied Clients (To Hide Directory Exists)
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{ENV:IsAdmin} !=1
RewriteRule 403.html - [R=404,L]
</IfModule>
IP制限を記述した.htaccess
と同階層に404ページを作成し、次のようなHTMLを記述します
(403ページは必要ありません)
<!DOCTYPE html>
<html>
<head>
<title>404 Not Found</title>
</head>
<body>
<h1>Not Found</h1>
<p>The requested URL /admin/ was not found on this server.</p>
</body>
</html>
目的
アクセス制限を行っているApacheでステータス403を404で返す方法
http://blog.shinkaku.co.jp/archives/45972397.html
ほとんど上のブログに書いてある記述の通りなんですが、Location
ディレクティブは.htaccess
では使えません。(httpd.conf
なら使える)
私の環境ではhttpd.conf
を編集できないため、.htaccess
だけで完結できる方法を探すことが目的でした。
(私の環境はCentOS7 - Apache2.4 ですが、CentOS6 - Apache2.2でも動くと思います)
ディレクトリ構造
次のようなディレクトリ構造を想定しています。
document_root/
admin/
.htaccess
404.html
index.html
ドキュメントルート配下は普通に誰でも見えるが、
/admin
ディレクトリ配下は、IP制限をかけ、許可していないユーザーのアクセス時、「404」エラーを返します。
(普通は403エラーを返しますが、それだとそこにディレクトリが存在するのを暗に示してしまうので、なんかセキュリティ上よくない気がして。)
追記
特定のディレクトリ配下はBASIC認証もIP制限も不要な公開領域にする必要が出てきたので、
全文を公開します。覚えられる気がしないので。
ちなみに当方環境はApache 2.4です
### Define Environment Variables
<IfModule mod_env.c>
## Allow Authenticated User Access By Client IP Address
# Local Host
SetEnvIf REMOTE_ADDR 192.168.33.1 IsAdmin=1
# Global IP Address
SetEnvIf X-Forwarded-For xx.xx.xx.xx IsAdmin=1
## Allow Unauthenticated User Access By Following URL
SetEnvIf REQUEST_URI /api/ IsPublic=1
SetEnvIf REQUEST_URI /admin/uploads/ IsPublic=1
</IfModule>
### BASIC Authorization
AuthUserFile /path/to/project/admin/.htpasswd
AuthType Basic
AuthName "Web access"
Require valid-user
Require env IsPublic
### Access Restriction
Order deny,allow
Deny from all
Allow from env=IsAdmin
Allow from env=IsPublic
### Replace 403 Page To 404
ErrorDocument 403 /admin/403.html
ErrorDocument 404 /admin/404.html
### Allow All User Access For Showing 403 And 404 Pages
<Files ~ "40(3|4).html">
Satisfy Any
Order allow,deny
Allow from all
</Files>
### Return 404 Error To Denied Clients (To Hide Directory Exists)
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{ENV:IsAdmin} !=1
RewriteCond %{ENV:IsPublic} !=1
RewriteRule 403.html - [R=404,L]
</IfModule>