LoginSignup
6
2

More than 5 years have passed since last update.

Cookieでマルチサービスでアクセス制御

Posted at

概要

たとえば、

  • 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で制御する、それだけです。
image.png

前提

  • 通信が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時間かけて気づきました。

フォーム認証の書き方

login.php
setcookie("key","pass",time()+3600*2,"/","example.com",true,true);

あとはcronとかで何日かに一回0-auth.confpassと、login.phppassを違う文字列に置き換えます。
以上、簡単ですね。

安全性

Cookieに鍵となる文字列を入れてしまって不正アクセスされないの?
というところにだいぶ悩みました。
結論としては、

  • HttpOnly属性をtrueにしてXSS攻撃を防ぐ
  • Secure属性をtrueにして通信路での漏洩を防ぐ
  • 鍵となる文字列を何日かに一回更新する

の三点をやれば良いんじゃないかなぁっていう感じです。たぶん

鍵となる文字列をユーザ側に保存するという点では通常のフォーム認証やセッションと同じだけど、
ここで問題になるのは全ユーザが同じ文字列を持つという点で、でもそれってBASIC認証でも同じだよねって

情報セキュリティスペシャリスト受かってもこれぐらいの自信しか持てない

最後に

BASIC認証、iOSだとID/PWが保持できなかったりしてくそめんどくさいですね。
代替案としてこんなのを考えてみましたが、セキュリティ的にどうなのでしょうか…HttpOnly無視されたらXSSで詰みそう…
同じことやってる人がみつけられなかったのでもしかしたら致命的な欠陥があるのかもしれません。コメント欄で教えていただければ幸いです。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2