Apache + mod_auth_openidc で G Suite アカウント認証するリバースプロキシを作って安全に社内サーバにアクセスする

こんにちは。未だにオンプレサーバをたくさん抱えている会社でひとり情シスをやっているけーのです。世知辛いけど、ある意味自由にできるサーバがたくさんあるのは幸せなのか…

mod_auth_openidc とは

mod_auth_openidc というステキなApacheモジュールがあります。これをリバースプロキシに使うと、普段会社で使っているG SuiteやOffice 365などのアカウント情報でユーザー認証し、従業員にだけ社内のWebシステムにアクセスさせることができるようになります。いわゆるSSO(Single Sign On)というやつですね。ステキ。

社内システムというのは、いつの間にかたくさんできあがってしまい、ユーザーがアカウントのパスワードを忘れるということがよく発生します。忘れると管理者に再設定を依頼したりする必要がありますし、ユーザー側は忘れないようにと簡単で覚えやすいパスワードを設定しがちになります。なので、アカウント/パスワード自体を少しでも減らしていく方向に持っていくのはIT管理部門の使命のひとつでしょう。

Apache + mod_auth_openidc の設定例

以下のような Dockerfile でコンテナを作って使っています。 mod_auth_openidc 配布元で .deb や .rpm パッケージを作ってくれているのでこれを使うのが簡単でしょう。

FROM debian:stretch
MAINTAINER Shinsuke KAWANO <kno@2502.net>

RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y wget apache2 php php-curl \
&& apt-get clean

# 新しいバージョンがリリースされたらこのへんを適当に書き換える
RUN wget -q https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.3.6/libapache2-mod-auth-openidc_2.3.6-1.stretch.1_amd64.deb \
https://github.com/pingidentity/mod_auth_openidc/releases/download/v2.3.0/libcjose0_0.5.1-1.stretch.1_amd64.deb
RUN dpkg -i *.deb; exit 0
RUN apt-get -yf install
RUN rm -f *.deb

RUN mkdir -p /var/run/apache2
COPY auth_openidc.conf /etc/apache2/mods-available/auth_openidc.conf
RUN a2enmod auth_openidc

RUN a2enmod rewrite && a2enmod proxy && a2enmod proxy_http && a2enmod headers

COPY 000-default.conf /etc/apache2/sites-available/000-default.conf

EXPOSE 80/tcp

CMD /usr/sbin/apache2 -DFOREGROUND

auth_openidc.conf は以下のようなものです。

OIDCClientID, OIDCClientSecret, OIDCCryptoPassphrase は Google API Console で作って、コピペします。

OIDCProviderMetadataURL https://accounts.google.com/.well-known/openid-configuration
OIDCClientID xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com
OIDCClientSecret XXXXXXXXXXXXXXXXXXXXXXXX
OIDCScope "openid email profile"

OIDCRedirectURI /redirect
OIDCCryptoPassphrase XXXXXXXXXXXXXXX

OIDCSessionInactivityTimeout 3600
OIDCAuthNHeader X-Remote-User

AuthType openid-connect
Require claim hd:example.com

これを クライアント(ブラウザ)(HTTPS) -&gt; Nginx -&gt; Apache + mod_auth_openidc -&gt; Web Application のように、多段リバースプロキシ構成で使っています。インターネットではHTTPSを使っているので通信路の暗号化もばっちりです。

多段リバースプロキシにした理由

フロントエンドのリバースプロキシとmod_auth_openidcのリバースプロキシを別々にすることで、以下のようなメリットがあります。

  • 将来、mod_auth_openidcがメンテナンスされなくなったとしても、類似のプロダクトへの乗り換えが容易
  • HTTPSや証明書の設定を行うサーバと認証を行うサーバを完全に分けることができ、ソフトウェアアップデートや設定変更時の影響範囲を限定できる

失礼ながら、あまりメジャーでないプロダクトを使う場合は、いざという時に乗り換えがやりやすいように心がけています。かなり以前に、Oracle DBのテーブルからアカウント情報を取得して認証するモジュールを使っていて、後で一切変更が効かなくなった経験もあり…あれは未だにApache 1.3で動いていたような…

なお、リバースプロキシ先がわかりにくくなる点はささやかな欠点です。

ユーザーを識別

アプリで HTTP_OIDC_CLAIM_EMAIL を参照すれば、メールアドレスからユーザーを識別することができます。他にもいくつか方法がありますが、これが一番便利そう。

参考

詳細に解説されていて助かります。ありがたや。