概要
たとえば、
- git.example.com - GitLab
- wiki.example.com - pukiWiki
- md.example.com - hackMD
- portal.example.com - 普通のWebサイト
- redmine.example.com - redmine
のようなたくさんのサービスが同じドメイン上で動いているとき、アクセス制限をかけたい!でも全部のサービスでBASIC認証を入れるのは手間!かといってセッションを用いた認証を挟もうにもサービスに手を加えたくない!
そんなときの解決策として、1つ思いついて実装してみたのを記録に残そうと思います。
(まあどうせ誰かのn番煎じなんだろうけど、一応検索して見つからなかったので)
結論から言うと、Cookieを用いてApacheのmod_rewrite
で制御する、それだけです。
前提
- 通信がhttpsであること
- 普通にWebサーバが動いていること
実装
Cookieの値の設定
> vi /etc/httpd/conf.d/0-auth.conf
#値は適当
Define COOKIE_KEY key=pass
このDefine
と出会うまで1時間かかりました。
vertualHostの設定
> vi /etc/httpd/conf.d/hoge-vhost.conf
<virtualHost *:443>
## その他の設定 ##
#認証
RewriteEngine On
RewriteCond %{HTTP_COOKIE} !${COOKIE_KEY}
RewriteRule ^.*$ https://portal.example.com/login.php
## その他の設定 ##
</virtualHost>
portal.example.com
のconfだけRewriteCond %{REQUEST_URI} !login\.php
も条件に追加しないと爆発する。
RedirectじゃなくてRewriteを使うことに2時間かけて気づきました。
フォーム認証の書き方
setcookie("key","pass",time()+3600*2,"/","example.com",true,true);
あとはcronとかで何日かに一回0-auth.conf
のpass
と、login.php
のpass
を違う文字列に置き換えます。
以上、簡単ですね。
安全性
Cookieに鍵となる文字列を入れてしまって不正アクセスされないの?
というところにだいぶ悩みました。
結論としては、
- HttpOnly属性をtrueにしてXSS攻撃を防ぐ
- Secure属性をtrueにして通信路での漏洩を防ぐ
- 鍵となる文字列を何日かに一回更新する
の三点をやれば良いんじゃないかなぁっていう感じです。たぶん
鍵となる文字列をユーザ側に保存するという点では通常のフォーム認証やセッションと同じだけど、
ここで問題になるのは全ユーザが同じ文字列を持つという点で、でもそれってBASIC認証でも同じだよねって
情報セキュリティスペシャリスト受かってもこれぐらいの自信しか持てない
最後に
BASIC認証、iOSだとID/PWが保持できなかったりしてくそめんどくさいですね。
代替案としてこんなのを考えてみましたが、セキュリティ的にどうなのでしょうか…HttpOnly無視されたらXSSで詰みそう…
同じことやってる人がみつけられなかったのでもしかしたら致命的な欠陥があるのかもしれません。コメント欄で教えていただければ幸いです。