OAuth2 Proxyで外部認証(1) GitHub編


概要

  • 自前の認証機能を持っていない、既存のウェブサイトや独自アプリがある
  • Basic認証などで都度ID/パスワード設定するのは古臭いし管理たいへんなので止めたい
  • シングルサインオンできる外部の認証機能を使いたい

⇒ リバースプロキシとして機能する OAuth2 Proxyを立てる

OAuth2 Proxyの紹介

  • 開発言語は GO言語 ⇒ ライブラリ同梱した単体実行ファイル生成可能
  • ライセンスは MITライセンス
  • 証明書登録してTLSサイトとなることも可能(だが今回は使わない)
  • 他のHTTPサーバのバックエンドとしても機能することも可能(今回はこの使い方をする)
  • リバースプロキシの下流サーバはSNI未対応 ⇒ name based Virtual Hostには使えない(ちょっと残念)

仕様構成

こんな感じ。

設定の流れ

Apacheベースの既存サイトが起動済み、仮想サーバ設定を追加していく想定。

起動済みサイトは https://example.com として例示する。

OAuth2 Proxyダウンロード

今回は releases から、ターゲットホストであるLinux x64バイナリをダウンロードしてそのまま使う。

v7.2.1を利用。

OAuth2 Proxy設定ファイル記述

認証プロバイダごとの設定方法 が紹介されているので、そちらを参考にする。今回はGitHubを使うので、 GitHubの項 を参照する。

GitHubでのアプリケーション登録

設定ファイルには、認証プロバイダに接続するための client_idclient_secret (秘密鍵)が必要になるので登録する。

説明に書いてある以下URLに飛ぶ。

https://github.com/settings/developers

右上の「New OAuth App」ボタンを押して新規アプリケーションを登録。
必須項目は以下だけ。

  • Application name
  • Homepage URL
  • Authorization callback URL

最後がOAuth2 Proxyの設定に影響するので注意。

既存サイト(アプリ)にかぶらない任意のパスを設定する。たとえば以下とする。

https://example.com/oauth2/callback

決定したURLは、設定ファイルの redirect_url の項目として記述。

client_id, client_secret の取得

GitHub のガイドに従って実行する。詳細は割愛。

全体記述例

未設定のものは省略

oauth2-proxy.cfg
http_address = "127.0.0.1:3333"
reverse_proxy = true
redirect_url = "https://example.com/oauth2/callback"
upstreams = [
    "http://inside.example.com/"
]
header = true
pass_host_email_domains = [
    "your-mail.example.com"
]
provider = "github"
client_id = "xxxx"
client_secret = "xxxx"
cookie_secret = "xxxx"

upstreams が提供サイトの情報。
OAuth2 Proxyから見えさえすればよく、Hostヘッダも送らないようなので、プライベートなIPv4アドレス直指定でもよいと思われる。

client_id, client_secret は、前述で取得したものを利用。

cookie_secret には任意の値で構わないと思われるが、 /dev/urandom から取得したものを文字列として利用した(たしか)。

OAuth2 Proxy起動

作成した oauth2-proxy.cfg を引数にして実行ファイルを起動する。

$ ./oauth2-proxy --config oauth2-proxy.cfg

とりあえず一般ユーザーでの手動起動。
systemdへの登録などは今後検討。

外部用サイトの仮想設定

外部サイト側のすべてのパスをOAuth2化したいわけではなかったので、ProxyPass / ProxyPassReverse で渡すための設定を追加。

virtual.conf (既存のサイト設定)
<VitrualHost example.com:443>
        ProxyPass /oauth2/ http://127.0.0.1:3333/oauth2/ disablereuse=On
        ProxyPassReverse /oauth2/ http://127.0.0.1:3333/oauth2/
        ProxyPass /apps/ http://127.0.0.1:3333/apps/ disablereuse=On
        ProxyPassReverse /apps/ http://127.0.0.1:3333/apps/
</Virtualhost>

/apps/ 以下が登録したいアプリケーション。
/oauth2/ 以下が、GitHubや設定ファイルに記述したcallback urlのためのもの。

提供サイト側の設定

name based Virtual Hostだったので、ホストへ内部IPv4アドレス1コを追加。
IP addr based Virtual Hostとした。
詳細は本記事の範囲外なので割愛。

IP addr based Virtual Hostベースの仮想サーバで起動済みであれば、とくに新たな設定は不要と思われる。

その他

アプリ側に簡単なCGIスクリプトを置いて、どんな情報が提供されているか確認してみた。

/apps/env.cgi
HTTP_X_FORWARDED_EMAIL => '[email protected]',
HTTP_X_FORWARDED_FOR => '127.0.0.1',
HTTP_X_FORWARDED_HOST => 'example.com',
HTTP_X_FORWARDED_SERVER => 'example.com',
HTTP_X_FORWARDED_USER => 'k2ok',

HTTP_X_FORWARDED_EMAIL は、実際にはGitHubに登録しているメールアドレスが入る。
HTTP_X_FORWARDED_USERGitHubの登録アカウント名 と思われる。

感想

リバースプロクシに対する基礎知識と、OAuth2の概要くらい分かっていれば容易に導入可能に見えた。

イントラネットで数名~数十名の限られたユーザーベースであれば、十分に耐えられそう。

自身は設定だけで認証情報を待たないので、スケールさせるのも難しくなさそうだが、1インスタンスでどれくらい耐えられるかは更に評価が必要そう。
(GOのマルチスレッド性能?がどんなもんかは寡聞にして知らず)

個人としては、スマホで宅内サーバーの古いミニアプリを利用するのに利用中。(まだ稼働40日程度)