概要
- 自前の認証機能を持っていない、既存のウェブサイトや独自アプリがある
- 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_id
と client_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 のガイドに従って実行する。詳細は割愛。
全体記述例
未設定のものは省略
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
で渡すための設定を追加。
<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スクリプトを置いて、どんな情報が提供されているか確認してみた。
HTTP_X_FORWARDED_EMAIL => 'k2ok@your-mail.example.com',
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_USER
は GitHubの登録アカウント名 と思われる。
感想
リバースプロクシに対する基礎知識と、OAuth2の概要くらい分かっていれば容易に導入可能に見えた。
イントラネットで数名~数十名の限られたユーザーベースであれば、十分に耐えられそう。
自身は設定だけで認証情報を待たないので、スケールさせるのも難しくなさそうだが、1インスタンスでどれくらい耐えられるかは更に評価が必要そう。
(GOのマルチスレッド性能?がどんなもんかは寡聞にして知らず)
個人としては、スマホで宅内サーバーの古いミニアプリを利用するのに利用中。(まだ稼働40日程度)