Apache2.4でアクセス制御の方法を調べた

Apache2.4からアクセス制御の方法が、RequireAnyとかを使った方法になっているよう。
ちょっとよくわからなかったので調べて整理してみたメモ。

基本

基本は、以下の3つのタグで囲って条件付けしていく。

  • RequireAny – どれか一つでも当てはまれば許可
  • RequireAll – 全てに当てはまれば許可
  • RequireNone – どれか一つでも当てはまれば拒否

デフォルト、何も囲わなければ RequireAny となるよう。

1
2
3
4
<RequireAny>
  Require {判定する内容}
  Require {判定する内容}
</RequireAny>

判定文基本

1
2
3
4
5
6
7
8
9
10
11
# xxのとき許可
Require xx

# xxでないとき許可
Require not xx

# 全て許可
Require all granted

# 全て拒否
Require all denied

env

envで変数的に値を設定出来る。
以下みたいな感じ。

SetEnvIf {種類} {値} {変数名}

1
2
3
4
5
6
7
# URI
SetEnvIf Request_URI /hoge/ valid-url
SetEnvIf Request_URI "^/hoge/*" valid-url  #正規表現

# IP
SetEnvIf REMOTE_ADDR 192.168.33.1 valid-ip
SetEnvIf X-Forwarded-For 000.00.000.000 valid-ip  #ロードバランサ使用時

URI表記の揺れ

正規表現を使わない場合は正しくかかないと無視されてしまう部分があった。
例えば、/api/以下のディレクトリを許可したい場合。
SetEnvIf Request_URI xxx valid-url
ここの、xxxに入るものを色々変えてアクセスしてみた。
(api/test.phpに対してのアクセス結果)

  • ◯ : /api/*
  • ◯ : /api/
  • ◯ : /
  • ◯ : /a
  • × : /test/
  • ◯ : /test
  • ◯ : /t
  • × : /t/
  • ◯ : "^/api/*"
  • ◯ : "^/api"
  • ◯ : "^/a"
  • × : "^/test/"
  • × : "^/t"

正規表現を利用すると意図した通り動いているが、正規表現を利用しない場合には、スラッシュの後の文字列は無視されているような挙動をしている。/apiでも/testでも/と同じ。注意が必要。

ベーシック認証

ベーシック認証の設定などは以下。

1
2
3
AuthType Basic
AuthName "Password Required"
AuthUserFile /var/www/.htpasswd

で、認証されたユーザを許可、は以下を記述。

1
Require valid-user

組み合わせ

で、これらを組み合わせて設定した制御をかけていく。
例えば…
ベーシック認証をかけるが、特定のIPは許可。さらに特定のディレクトリは常に許可する、とかの場合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Basic認証
AuthType Basic
AuthName "Password Required"
AuthUserFile /var/www/.htpasswd

# env
SetEnvIf REMOTE_ADDR 192.168.33.1 valid-ip
SetEnvIf Request_URI "^/hoge/*" valid-url

# 条件
<RequireAny>
  Require valid-user
  Require env valid-ip
  Require env valid-url
</RequireAny>

RequireAnyの条件なのでいずれかに合致すればアクセスが許可される。
URIの指定は正規表現を使っておいた方が確実。

Laravelの場合

Laravelで同じようにURIを利用して制御したい場合は、制御対象のURIだけを許可してやるだけではダメだった。
理由はルーティングの仕組みにあって、Laravelの場合はアクセスされた際に一旦、index.phpにリダイレクトさせてからLaravelを起動し、ルーティングをさせる仕組みになっている。
よって、/index.phpを許可しておいてやらないと認証が通らなくなってしまう。

1
2
3
4
5
6
7
8
SetEnvIf Request_URI "^/hoge/*" valid-url
SetEnvIf Request_URI "^/index.php" laravel

<RequireAny>
  Require valid-user #ベーシック認証
  Require env valid-url
  Require env laravel
</RequireAny>

ただしこの方法だと、/index.phpへの直接のアクセス(トップページ)は許可されてしまうので注意。
(とはいえ、読み込んでいる別ディレクトリのcssやjsや画像なんかは拒否される)
(/へのアクセスは拒否される。)

参考

SetEnvIfで指定出来る要素は以下にドキュメントがあった。
mod_setenvif – Apache HTTP サーバ バージョン 2.4
SetEnvIf ディレクティブ のセクション

   このエントリーをはてなブックマークに追加